/
backend.py
172 lines (137 loc) · 6.21 KB
/
backend.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# coding: utf-8
"""
Common test functionality for backends.
"""
import os
import string
import pytest
from .util import random_string
from keyring import errors
# unicode only characters
# Sourced from The Quick Brown Fox... Pangrams
# http://www.columbia.edu/~fdc/utf8/
UNICODE_CHARS = (
"זהכיףסתםלשמועאיךתנצחקרפדעץטובבגן"
"ξεσκεπάζωτηνψυχοφθόραβδελυγμία"
"Съешьжеещёэтихмягкихфранцузскихбулокдавыпейчаю"
"Жълтатадюлябешещастливачепухъткойтоцъфназамръзнакатогьон"
)
# ensure no-ascii chars slip by - watch your editor!
assert min(ord(char) for char in UNICODE_CHARS) > 127
def is_ascii_printable(s):
return all(32 <= ord(c) < 127 for c in s)
class BackendBasicTests:
"""Test for the keyring's basic functions. password_set and password_get"""
DIFFICULT_CHARS = string.whitespace + string.punctuation
@pytest.fixture(autouse=True)
def _init_properties(self, request):
self.keyring = self.init_keyring()
self.credentials_created = set()
request.addfinalizer(self.cleanup)
def cleanup(self):
for item in self.credentials_created:
self.keyring.delete_password(*item)
def set_password(self, service, username, password):
# set the password and save the result so the test runner can clean
# up after if necessary.
self.keyring.set_password(service, username, password)
self.credentials_created.add((service, username))
def check_set_get(self, service, username, password):
keyring = self.keyring
# for the non-existent password
assert keyring.get_password(service, username) is None
# common usage
self.set_password(service, username, password)
assert keyring.get_password(service, username) == password
# for the empty password
self.set_password(service, username, "")
assert keyring.get_password(service, username) == ""
def test_password_set_get(self):
password = random_string(20)
username = random_string(20)
service = random_string(20)
self.check_set_get(service, username, password)
def test_difficult_chars(self):
password = random_string(20, self.DIFFICULT_CHARS)
username = random_string(20, self.DIFFICULT_CHARS)
service = random_string(20, self.DIFFICULT_CHARS)
self.check_set_get(service, username, password)
def test_delete_present(self):
password = random_string(20, self.DIFFICULT_CHARS)
username = random_string(20, self.DIFFICULT_CHARS)
service = random_string(20, self.DIFFICULT_CHARS)
self.keyring.set_password(service, username, password)
self.keyring.delete_password(service, username)
assert self.keyring.get_password(service, username) is None
def test_delete_not_present(self):
username = random_string(20, self.DIFFICULT_CHARS)
service = random_string(20, self.DIFFICULT_CHARS)
with pytest.raises(errors.PasswordDeleteError):
self.keyring.delete_password(service, username)
def test_delete_one_in_group(self):
username1 = random_string(20, self.DIFFICULT_CHARS)
username2 = random_string(20, self.DIFFICULT_CHARS)
password = random_string(20, self.DIFFICULT_CHARS)
service = random_string(20, self.DIFFICULT_CHARS)
self.keyring.set_password(service, username1, password)
self.set_password(service, username2, password)
self.keyring.delete_password(service, username1)
assert self.keyring.get_password(service, username2) == password
def test_name_property(self):
assert is_ascii_printable(self.keyring.name)
def test_unicode_chars(self):
password = random_string(20, UNICODE_CHARS)
username = random_string(20, UNICODE_CHARS)
service = random_string(20, UNICODE_CHARS)
self.check_set_get(service, username, password)
def test_unicode_and_ascii_chars(self):
source = (
random_string(10, UNICODE_CHARS)
+ random_string(10)
+ random_string(10, self.DIFFICULT_CHARS)
)
password = random_string(20, source)
username = random_string(20, source)
service = random_string(20, source)
self.check_set_get(service, username, password)
def test_different_user(self):
"""
Issue #47 reports that WinVault isn't storing passwords for
multiple users. This test exercises that test for each of the
backends.
"""
keyring = self.keyring
self.set_password('service1', 'user1', 'password1')
self.set_password('service1', 'user2', 'password2')
assert keyring.get_password('service1', 'user1') == 'password1'
assert keyring.get_password('service1', 'user2') == 'password2'
self.set_password('service2', 'user3', 'password3')
assert keyring.get_password('service1', 'user1') == 'password1'
def test_credential(self):
keyring = self.keyring
cred = keyring.get_credential('service', None)
assert cred is None
self.set_password('service1', 'user1', 'password1')
self.set_password('service1', 'user2', 'password2')
cred = keyring.get_credential('service1', None)
assert cred is None or (cred.username, cred.password) in (
('user1', 'password1'),
('user2', 'password2'),
)
cred = keyring.get_credential('service1', 'user2')
assert cred is not None
assert (cred.username, cred.password) in (
('user1', 'password1'),
('user2', 'password2'),
)
def test_set_properties(self, monkeypatch):
env = dict(KEYRING_PROPERTY_FOO_BAR='fizz buzz', OTHER_SETTING='ignore me')
monkeypatch.setattr(os, 'environ', env)
self.keyring.set_properties_from_env()
assert self.keyring.foo_bar == 'fizz buzz'
def test_new_with_properties(self):
alt = self.keyring.with_properties(foo='bar')
assert alt is not self.keyring
assert alt.foo == 'bar'
with pytest.raises(AttributeError):
self.keyring.foo