diff options
| -rw-r--r-- | service/app/bitmask_libraries/leap_srp.py | 29 | ||||
| -rw-r--r-- | service/test/bitmask_libraries/leap_srp_test.py | 41 | 
2 files changed, 69 insertions, 1 deletions
diff --git a/service/app/bitmask_libraries/leap_srp.py b/service/app/bitmask_libraries/leap_srp.py index a1de7de3..d534e732 100644 --- a/service/app/bitmask_libraries/leap_srp.py +++ b/service/app/bitmask_libraries/leap_srp.py @@ -1,11 +1,16 @@  import binascii  import json +import requests  from requests import Session -from srp import User, srp +from srp import User, srp, create_salted_verification_key  from requests.exceptions import HTTPError, SSLError, Timeout  from config import SYSTEM_CA_BUNDLE +REGISTER_USER_LOGIN_KEY = 'user[login]' +REGISTER_USER_VERIFIER_KEY = 'user[password_verifier]' +REGISTER_USER_SALT_KEY = 'user[password_salt]' +  class LeapAuthException(Exception):      def __init__(self, *args, **kwargs): @@ -98,6 +103,28 @@ class LeapSecureRemotePassword(object):          if not user.authenticated():              raise LeapAuthException() +    def register(self, api_uri, username, password): +        try: +            salt, verifier = create_salted_verification_key(username, password, self.hash_alg, self.ng_type) +            return self._post_registration_data(api_uri, username, salt, verifier) +        except (HTTPError, SSLError, Timeout), e: +            raise LeapAuthException(e) + +    def _post_registration_data(self, api_uri, username, salt, verifier): +        users_url = '%s/%s/users' % (api_uri, self.leap_api_version) + +        user_data = { +            REGISTER_USER_LOGIN_KEY: username, +            REGISTER_USER_SALT_KEY: binascii.hexlify(salt), +            REGISTER_USER_VERIFIER_KEY: binascii.hexlify(verifier) +        } + +        response = requests.post(users_url, data=user_data, verify=self.ca_bundle, timeout=self.timeout_in_s) +        response.raise_for_status() +        reg_json = json.loads(response.content) + +        return reg_json['ok'] +  def _safe_unhexlify(hex_str):      return binascii.unhexlify(hex_str) \ diff --git a/service/test/bitmask_libraries/leap_srp_test.py b/service/test/bitmask_libraries/leap_srp_test.py index e10be216..f02344f3 100644 --- a/service/test/bitmask_libraries/leap_srp_test.py +++ b/service/test/bitmask_libraries/leap_srp_test.py @@ -100,3 +100,44 @@ class LeapSRPTest(unittest.TestCase):          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')  | 
