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
|
import sys
import os
sys.path.insert(0, os.environ['APP_ROOT'])
import json
import unittest
import binascii
from urlparse import parse_qs
from httmock import urlmatch, all_requests, HTTMock, response
from requests.exceptions import Timeout
import srp
from app.bitmask_libraries.leap_srp import LeapSecureRemotePassword, LeapAuthException
(salt_bytes, verification_key_bytes) = srp.create_salted_verification_key('username', 'password', hash_alg=srp.SHA256, ng_type=srp.NG_1024)
verifier = None
@all_requests
def not_found_mock(url, request):
return {'status_code': 404,
'content': 'foobar'}
@all_requests
def timeout_mock(url, request):
raise Timeout()
@urlmatch(netloc=r'(.*\.)?leap\.local$')
def srp_login_server_simulator_mock(url, request):
global verifier
data = parse_qs(request.body)
if 'login' in data:
# SRP Authentication Step 1
A = binascii.unhexlify(data.get('A')[0])
verifier = srp.Verifier('username', salt_bytes, verification_key_bytes, A, hash_alg=srp.SHA256, ng_type=srp.NG_1024)
(salt, B) = verifier.get_challenge()
content = {
'salt': binascii.hexlify(salt),
'B': binascii.hexlify(B)
}
return {'status_code': 200,
'content': json.dumps(content)}
else:
# SRP Authentication Step 2
data = parse_qs(request.body)
client_auth = binascii.unhexlify(data.get('client_auth')[0])
M2 = verifier.verify_session(client_auth)
if not verifier.authenticated():
return {'status_code': 404,
'content': ''}
content = {
'M2': binascii.hexlify(M2),
'id': 'some id',
'token': 'some token'
}
headers = {
'Content-Type': 'application/json',
'Set-Cookie': '_session_id=some_session_id;'}
return response(200, content, headers, None, 5, request)
class LeapSRPTest(unittest.TestCase):
def test_status_code_is_checked(self):
with HTTMock(not_found_mock):
lsrp = LeapSecureRemotePassword()
self.assertRaises(LeapAuthException, lsrp.authenticate, 'https://api.leap.local', 'username', 'password')
def test_invalid_username(self):
with HTTMock(srp_login_server_simulator_mock):
lsrp = LeapSecureRemotePassword()
self.assertRaises(LeapAuthException, lsrp.authenticate, 'https://api.leap.local', 'invalid_user', 'password')
def test_invalid_password(self):
with HTTMock(srp_login_server_simulator_mock):
lsrp = LeapSecureRemotePassword()
self.assertRaises(LeapAuthException, lsrp.authenticate, 'https://api.leap.local', 'username', 'invalid')
def test_login(self):
with HTTMock(srp_login_server_simulator_mock):
lsrp = LeapSecureRemotePassword()
leap_session = lsrp.authenticate('https://api.leap.local', 'username', 'password')
self.assertIsNotNone(leap_session)
self.assertEqual('username', leap_session.user_name)
self.assertEqual('1', leap_session.api_version)
self.assertEqual('https://api.leap.local', leap_session.api_server_name)
self.assertEqual('some token', leap_session.token)
self.assertEqual('some_session_id', leap_session.session_id)
def test_timeout(self):
with HTTMock(timeout_mock):
lrsp = LeapSecureRemotePassword()
self.assertRaises(LeapAuthException, lrsp.authenticate, 'https://api.leap.local', 'username', 'password')
|