From a8274b633a62262e65c7d013e61a54541ce07bf8 Mon Sep 17 00:00:00 2001 From: Duda Dornelles Date: Thu, 22 Jan 2015 10:25:40 -0200 Subject: #224 renaming tests so they get caught by trial runner --- .../test/unit/bitmask_libraries/test_leap_srp.py | 157 +++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 service/test/unit/bitmask_libraries/test_leap_srp.py (limited to 'service/test/unit/bitmask_libraries/test_leap_srp.py') diff --git a/service/test/unit/bitmask_libraries/test_leap_srp.py b/service/test/unit/bitmask_libraries/test_leap_srp.py new file mode 100644 index 00000000..6d067e5d --- /dev/null +++ b/service/test/unit/bitmask_libraries/test_leap_srp.py @@ -0,0 +1,157 @@ +# +# Copyright (c) 2014 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +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 pixelated.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') + + def test_register_raises_auth_exception_on_error(self): + with HTTMock(not_found_mock): + lsrp = LeapSecureRemotePassword() + self.assertRaises(LeapAuthException, lsrp.register, 'https://api.leap.local', 'username', 'password') + + def test_register(self): + @urlmatch(netloc=r'(.*\.)?leap\.local$', path='/1/users') + def register_success(url, request): + + content = { + 'login': 'username', + 'ok': True + } + + return {'status_code': 201, + 'content': content} + + with HTTMock(register_success, not_found_mock): + lsrp = LeapSecureRemotePassword() + self.assertTrue(lsrp.register('https://api.leap.local', 'username', 'password')) + + def test_register_user_exists(self): + @urlmatch(netloc=r'(.*\.)?leap\.local$', path='/1/users') + def register_error_user_exists(url, request): + content = {"errors": { + "login": [ + "has already been taken", "has already been taken", "has already been taken" + ]}} + + return {'status_code': 422, + 'content': content} + + with HTTMock(register_error_user_exists, not_found_mock): + lsrp = LeapSecureRemotePassword() + self.assertRaises(LeapAuthException, lsrp.register, 'https://api.leap.local', 'username', 'password') + + def test_registration_timeout(self): + with HTTMock(timeout_mock): + lsrp = LeapSecureRemotePassword() + self.assertRaises(LeapAuthException, lsrp.register, 'https://api.leap.local', 'username', 'password') -- cgit v1.2.3