commit | author | age
|
0b4b05
|
1 |
import unittest |
TS |
2 |
|
9c1e6f
|
3 |
|
826ba0
|
4 |
class AuthTicketTests(unittest.TestCase): |
0b4b05
|
5 |
|
TS |
6 |
def _getTargetClass(self): |
|
7 |
from .._auth_tkt import AuthTicket |
|
8 |
return AuthTicket |
|
9 |
|
|
10 |
def _makeOne(self, *args, **kw): |
|
11 |
return self._getTargetClass()(*args, **kw) |
|
12 |
|
|
13 |
def test_ctor_defaults(self): |
b70ba3
|
14 |
import hashlib |
0b4b05
|
15 |
from .. import _auth_tkt |
TS |
16 |
with _Monkey(_auth_tkt, time_mod=_Timemod): |
|
17 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4') |
|
18 |
self.assertEqual(tkt.secret, 'SEEKRIT') |
|
19 |
self.assertEqual(tkt.userid, 'USERID') |
|
20 |
self.assertEqual(tkt.ip, '1.2.3.4') |
|
21 |
self.assertEqual(tkt.tokens, '') |
|
22 |
self.assertEqual(tkt.user_data, '') |
|
23 |
self.assertEqual(tkt.time, _WHEN) |
|
24 |
self.assertEqual(tkt.cookie_name, 'auth_tkt') |
|
25 |
self.assertEqual(tkt.secure, False) |
b70ba3
|
26 |
self.assertEqual(tkt.digest_algo, hashlib.md5) |
0b4b05
|
27 |
|
TS |
28 |
def test_ctor_explicit(self): |
b70ba3
|
29 |
import hashlib |
0b4b05
|
30 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), |
TS |
31 |
user_data='DATA', time=_WHEN, |
b70ba3
|
32 |
cookie_name='oatmeal', secure=True, |
DT |
33 |
digest_algo=hashlib.sha512) |
0b4b05
|
34 |
self.assertEqual(tkt.secret, 'SEEKRIT') |
TS |
35 |
self.assertEqual(tkt.userid, 'USERID') |
|
36 |
self.assertEqual(tkt.ip, '1.2.3.4') |
|
37 |
self.assertEqual(tkt.tokens, 'a,b') |
|
38 |
self.assertEqual(tkt.user_data, 'DATA') |
|
39 |
self.assertEqual(tkt.time, _WHEN) |
|
40 |
self.assertEqual(tkt.cookie_name, 'oatmeal') |
|
41 |
self.assertEqual(tkt.secure, True) |
b70ba3
|
42 |
self.assertEqual(tkt.digest_algo, hashlib.sha512) |
DT |
43 |
|
|
44 |
def test_ctor_string_algorithm(self): |
|
45 |
import hashlib |
|
46 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), |
|
47 |
user_data='DATA', time=_WHEN, |
|
48 |
cookie_name='oatmeal', secure=True, |
|
49 |
digest_algo='sha1') |
|
50 |
self.assertEqual(tkt.secret, 'SEEKRIT') |
|
51 |
self.assertEqual(tkt.userid, 'USERID') |
|
52 |
self.assertEqual(tkt.ip, '1.2.3.4') |
|
53 |
self.assertEqual(tkt.tokens, 'a,b') |
|
54 |
self.assertEqual(tkt.user_data, 'DATA') |
|
55 |
self.assertEqual(tkt.time, _WHEN) |
|
56 |
self.assertEqual(tkt.cookie_name, 'oatmeal') |
|
57 |
self.assertEqual(tkt.secure, True) |
|
58 |
self.assertEqual(tkt.digest_algo, hashlib.sha1) |
0b4b05
|
59 |
|
TS |
60 |
def test_digest(self): |
fcf53b
|
61 |
from .._auth_tkt import calculate_digest, hashlib |
0b4b05
|
62 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), |
TS |
63 |
user_data='DATA', time=_WHEN, |
|
64 |
cookie_name='oatmeal', secure=True) |
|
65 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
fcf53b
|
66 |
'a,b', 'DATA', hashlib.md5) |
0b4b05
|
67 |
self.assertEqual(tkt.digest(), digest) |
TS |
68 |
|
|
69 |
def test_cookie_value_wo_tokens_or_userdata(self): |
fcf53b
|
70 |
from .._auth_tkt import calculate_digest, hashlib |
0b4b05
|
71 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', time=_WHEN) |
565160
|
72 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
TS |
73 |
'', '', hashlib.md5) |
0b4b05
|
74 |
self.assertEqual(tkt.cookie_value(), |
TS |
75 |
'%s%08xUSERID!' % (digest, _WHEN)) |
|
76 |
|
|
77 |
def test_cookie_value_w_tokens_and_userdata(self): |
fcf53b
|
78 |
from .._auth_tkt import calculate_digest, hashlib |
0b4b05
|
79 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), |
TS |
80 |
user_data='DATA', time=_WHEN) |
|
81 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
fcf53b
|
82 |
'a,b', 'DATA', hashlib.md5) |
0b4b05
|
83 |
self.assertEqual(tkt.cookie_value(), |
TS |
84 |
'%s%08xUSERID!a,b!DATA' % (digest, _WHEN)) |
|
85 |
|
|
86 |
def test_cookie_not_secure_wo_tokens_or_userdata(self): |
fcf53b
|
87 |
from .._auth_tkt import calculate_digest, hashlib |
0b4b05
|
88 |
from .._compat import encodestring |
TS |
89 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', time=_WHEN, |
|
90 |
cookie_name='oatmeal') |
565160
|
91 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
TS |
92 |
'', '', hashlib.md5) |
0b4b05
|
93 |
cookie = tkt.cookie() |
TS |
94 |
self.assertEqual(cookie['oatmeal'].value, |
|
95 |
encodestring('%s%08xUSERID!' % (digest, _WHEN) |
|
96 |
).strip()) |
|
97 |
self.assertEqual(cookie['oatmeal']['path'], '/') |
|
98 |
self.assertEqual(cookie['oatmeal']['secure'], '') |
|
99 |
|
|
100 |
def test_cookie_secure_w_tokens_and_userdata(self): |
fcf53b
|
101 |
from .._auth_tkt import calculate_digest, hashlib |
0b4b05
|
102 |
from .._compat import encodestring |
TS |
103 |
tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), |
|
104 |
user_data='DATA', time=_WHEN, |
|
105 |
cookie_name='oatmeal', secure=True) |
|
106 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
fcf53b
|
107 |
'a,b', 'DATA', hashlib.md5) |
0b4b05
|
108 |
cookie = tkt.cookie() |
TS |
109 |
self.assertEqual(cookie['oatmeal'].value, |
|
110 |
encodestring('%s%08xUSERID!a,b!DATA' % (digest, _WHEN) |
|
111 |
).strip()) |
|
112 |
self.assertEqual(cookie['oatmeal']['path'], '/') |
|
113 |
self.assertEqual(cookie['oatmeal']['secure'], 'true') |
|
114 |
|
|
115 |
|
826ba0
|
116 |
class BadTicketTests(unittest.TestCase): |
ff80e0
|
117 |
|
TS |
118 |
def _getTargetClass(self): |
|
119 |
from .._auth_tkt import BadTicket |
|
120 |
return BadTicket |
|
121 |
|
|
122 |
def _makeOne(self, *args, **kw): |
|
123 |
return self._getTargetClass()(*args, **kw) |
|
124 |
|
|
125 |
def test_wo_expected(self): |
|
126 |
exc = self._makeOne('message') |
|
127 |
self.assertEqual(exc.args, ('message',)) |
|
128 |
self.assertEqual(exc.expected, None) |
|
129 |
|
|
130 |
def test_w_expected(self): |
|
131 |
exc = self._makeOne('message', 'foo') |
|
132 |
self.assertEqual(exc.args, ('message',)) |
|
133 |
self.assertEqual(exc.expected, 'foo') |
|
134 |
|
|
135 |
|
826ba0
|
136 |
class Test_parse_ticket(unittest.TestCase): |
ff80e0
|
137 |
|
565160
|
138 |
def _callFUT(self, secret='SEEKRIT', ticket=None, |
TS |
139 |
ip='1.2.3.4', digest="md5"): |
ff80e0
|
140 |
from .._auth_tkt import parse_ticket |
b70ba3
|
141 |
return parse_ticket(secret, ticket, ip, digest) |
ff80e0
|
142 |
|
TS |
143 |
def test_bad_timestamp(self): |
|
144 |
from .._auth_tkt import BadTicket |
|
145 |
TICKET = '12345678901234567890123456789012XXXXXXXXuserid!' |
|
146 |
try: |
|
147 |
self._callFUT(ticket=TICKET) |
|
148 |
except BadTicket as e: |
826ba0
|
149 |
self.assertTrue(e.args[0].startswith( |
ff80e0
|
150 |
'Timestamp is not a hex integer:')) |
d13829
|
151 |
else: # pragma: no cover |
ff80e0
|
152 |
self.fail('Did not raise') |
TS |
153 |
|
|
154 |
def test_no_bang_after_userid(self): |
|
155 |
from .._auth_tkt import BadTicket |
|
156 |
TICKET = '1234567890123456789012345678901201020304userid' |
|
157 |
try: |
|
158 |
self._callFUT(ticket=TICKET) |
|
159 |
except BadTicket as e: |
|
160 |
self.assertEqual(e.args[0], 'userid is not followed by !') |
d13829
|
161 |
else: # pragma: no cover |
ff80e0
|
162 |
self.fail('Did not raise') |
TS |
163 |
|
|
164 |
def test_wo_tokens_or_data_bad_digest(self): |
|
165 |
from .._auth_tkt import BadTicket |
|
166 |
TICKET = '1234567890123456789012345678901201020304userid!' |
|
167 |
try: |
|
168 |
self._callFUT(ticket=TICKET) |
|
169 |
except BadTicket as e: |
|
170 |
self.assertEqual(e.args[0], 'Digest signature is not correct') |
d13829
|
171 |
else: # pragma: no cover |
ff80e0
|
172 |
self.fail('Did not raise') |
TS |
173 |
|
|
174 |
def test_wo_tokens_or_data_ok_digest(self): |
fcf53b
|
175 |
from .._auth_tkt import calculate_digest, hashlib |
565160
|
176 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
TS |
177 |
'', '', hashlib.md5) |
ff80e0
|
178 |
TICKET = '%s%08xUSERID!' % (digest, _WHEN) |
TS |
179 |
timestamp, userid, tokens, user_data = self._callFUT(ticket=TICKET) |
|
180 |
self.assertEqual(timestamp, _WHEN) |
|
181 |
self.assertEqual(userid, 'USERID') |
|
182 |
self.assertEqual(tokens, ['']) |
|
183 |
self.assertEqual(user_data, '') |
|
184 |
|
|
185 |
def test_w_tokens_and_data_ok_digest(self): |
fcf53b
|
186 |
from .._auth_tkt import calculate_digest, hashlib |
ff80e0
|
187 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
fcf53b
|
188 |
'a,b', 'DATA', hashlib.md5) |
ff80e0
|
189 |
TICKET = '%s%08xUSERID!a,b!DATA' % (digest, _WHEN) |
TS |
190 |
timestamp, userid, tokens, user_data = self._callFUT(ticket=TICKET) |
|
191 |
self.assertEqual(timestamp, _WHEN) |
|
192 |
self.assertEqual(userid, 'USERID') |
|
193 |
self.assertEqual(tokens, ['a', 'b']) |
|
194 |
self.assertEqual(user_data, 'DATA') |
|
195 |
|
b70ba3
|
196 |
def test_w_tokens_and_data_ok_alternate_digest(self): |
DT |
197 |
from .._auth_tkt import calculate_digest, hashlib |
|
198 |
digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', |
|
199 |
'a,b', 'DATA', hashlib.sha256) |
|
200 |
TICKET = '%s%08xUSERID!a,b!DATA' % (digest, _WHEN) |
565160
|
201 |
timestamp, userid, tokens, user_data = self._callFUT( |
TS |
202 |
ticket=TICKET, digest=hashlib.sha256) |
b70ba3
|
203 |
self.assertEqual(timestamp, _WHEN) |
DT |
204 |
self.assertEqual(userid, 'USERID') |
|
205 |
self.assertEqual(tokens, ['a', 'b']) |
|
206 |
self.assertEqual(user_data, 'DATA') |
|
207 |
|
ff80e0
|
208 |
|
826ba0
|
209 |
class Test_helpers(unittest.TestCase): |
ff80e0
|
210 |
|
565160
|
211 |
# calculate_digest is not very testable, fully exercised through callers. |
ff80e0
|
212 |
|
TS |
213 |
def test_ints_to_bytes(self): |
|
214 |
from struct import pack |
|
215 |
from .._auth_tkt import ints2bytes |
|
216 |
self.assertEqual(ints2bytes([1, 2, 3, 4]), pack('>BBBB', 1, 2, 3, 4)) |
|
217 |
|
|
218 |
def test_encode_ip_timestamp(self): |
|
219 |
from struct import pack |
|
220 |
from .._auth_tkt import encode_ip_timestamp |
|
221 |
self.assertEqual(encode_ip_timestamp('1.2.3.4', _WHEN), |
|
222 |
pack('>BBBBL', 1, 2, 3, 4, _WHEN)) |
|
223 |
|
|
224 |
def test_maybe_encode_bytes(self): |
|
225 |
from .._auth_tkt import maybe_encode |
|
226 |
foo = b'foo' |
826ba0
|
227 |
self.assertTrue(maybe_encode(foo) is foo) |
ff80e0
|
228 |
|
TS |
229 |
def test_maybe_encode_native_string(self): |
|
230 |
from .._auth_tkt import maybe_encode |
|
231 |
foo = 'foo' |
|
232 |
self.assertEqual(maybe_encode(foo), b'foo') |
|
233 |
|
|
234 |
def test_maybe_encode_unicode(self): |
|
235 |
from .._auth_tkt import maybe_encode |
|
236 |
from .._compat import u |
|
237 |
foo = u('foo') |
|
238 |
self.assertEqual(maybe_encode(foo), b'foo') |
|
239 |
|
0b4b05
|
240 |
|
TS |
241 |
_WHEN = 1234567 |
|
242 |
class _Timemod(object): |
|
243 |
@staticmethod |
|
244 |
def time(): |
|
245 |
return _WHEN |
|
246 |
|
|
247 |
|
|
248 |
class _Monkey(object): |
|
249 |
|
|
250 |
def __init__(self, module, **replacements): |
|
251 |
self.module = module |
|
252 |
self.orig = {} |
|
253 |
self.replacements = replacements |
|
254 |
|
|
255 |
def __enter__(self): |
|
256 |
for k, v in self.replacements.items(): |
|
257 |
orig = getattr(self.module, k, self) |
|
258 |
if orig is not self: |
|
259 |
self.orig[k] = orig |
|
260 |
setattr(self.module, k, v) |
|
261 |
|
|
262 |
def __exit__(self, *exc_info): |
|
263 |
for k, v in self.replacements.items(): |
|
264 |
if k in self.orig: |
|
265 |
setattr(self.module, k, self.orig[k]) |
|
266 |
else: #pragma NO COVERSGE |
|
267 |
delattr(self.module, k) |