diff options
| author | Thais Siqueira <thais.siqueira@gmail.com> | 2017-03-02 16:23:17 -0300 | 
|---|---|---|
| committer | Ruben Pollan <meskio@sindominio.net> | 2017-03-30 17:00:06 +0200 | 
| commit | caed945c7c85800d7467f52471509afc21a6f071 (patch) | |
| tree | 4b1c3167e49044f14c0192e842bfd30fc92e8912 | |
| parent | bd853141a23055cf2d1e0a4ae1712577024f9b84 (diff) | |
[feature] Creates methods for update recovery code.
Related with: https://github.com/pixelated/pixelated-user-agent/issues/924
with @aarni
Signed-off-by: Ruben Pollan <meskio@sindominio.net>
| -rw-r--r-- | src/leap/bitmask/bonafide/_srp.py | 16 | ||||
| -rw-r--r-- | src/leap/bitmask/bonafide/session.py | 12 | ||||
| -rw-r--r-- | tests/unit/bonafide/test_users.py | 34 | 
3 files changed, 61 insertions, 1 deletions
| diff --git a/src/leap/bitmask/bonafide/_srp.py b/src/leap/bitmask/bonafide/_srp.py index 3939c5ac..1ec40d82 100644 --- a/src/leap/bitmask/bonafide/_srp.py +++ b/src/leap/bitmask/bonafide/_srp.py @@ -144,7 +144,7 @@ class SRPSignupMechanism(object):  class SRPPasswordChangeMechanism(object):      """ -    Implement a protocol-agnostic SRP passord change mechanism. +    Implement a protocol-agnostic SRP password change mechanism.      """      def get_password_params(self, username, password): @@ -155,6 +155,20 @@ class SRPPasswordChangeMechanism(object):          return user_data +class SRPRecoveryCodeUpdateMechanism(object): + +    """ +    Implement a protocol-agnostic SRP recovery code update mechanism. +    """ + +    def get_recovery_code_params(self, username, recovery_code): +        salt, verifier = _get_salt_verifier(username, recovery_code) +        user_data = { +            'user[recovery_code_salt]': binascii.hexlify(salt), +            'user[recovery_code_verifier]': binascii.hexlify(verifier)} +        return user_data + +  def _get_salt_verifier(username, password):      return srp.create_salted_verification_key(bytes(username), bytes(password),                                                srp.SHA256, srp.NG_1024) diff --git a/src/leap/bitmask/bonafide/session.py b/src/leap/bitmask/bonafide/session.py index 5a743e94..732afe53 100644 --- a/src/leap/bitmask/bonafide/session.py +++ b/src/leap/bitmask/bonafide/session.py @@ -69,6 +69,7 @@ class Session(object):          self._srp_auth = _srp.SRPAuthMechanism(username, password)          self._srp_signup = _srp.SRPSignupMechanism()          self._srp_password = _srp.SRPPasswordChangeMechanism() +        self._srp_recovery_code = _srp.SRPRecoveryCodeUpdateMechanism()          self._token = None          self._uuid = None @@ -139,6 +140,17 @@ class Session(object):          self._srp_auth = _srp.SRPAuthMechanism(self.username, password)          defer.returnValue(OK) +    @_auth_required +    @defer.inlineCallbacks +    def update_recovery_code(self, recovery_code): +        uri = self._api.get_update_user_uri(uid=self._uuid) +        met = self._api.get_update_user_method() +        params = self._srp_recovery_code.get_recovery_code_params( +            self.username, recovery_code) +        update = yield self._request(self._agent, uri, values=params, +                                     method=met) +        defer.returnValue(update) +      # User certificates      def get_vpn_cert(self): diff --git a/tests/unit/bonafide/test_users.py b/tests/unit/bonafide/test_users.py new file mode 100644 index 00000000..952e73d4 --- /dev/null +++ b/tests/unit/bonafide/test_users.py @@ -0,0 +1,34 @@ +from mock import patch, ANY + +from twisted.internet import defer +from twisted.trial import unittest +from twisted.cred.credentials import UsernamePassword + +from leap.bitmask.bonafide.provider import Api +from leap.bitmask.bonafide.session import Session + + +class UsersTest(unittest.TestCase): + +    @patch('leap.bitmask.bonafide.session.Session.is_authenticated') +    @patch('leap.bitmask.bonafide.session.cookieAgentFactory') +    @patch('leap.bitmask.bonafide.session.httpRequest') +    @defer.inlineCallbacks +    def test_recovery_code_creation(self, +                                    mock_http_request, +                                    mock_cookie_agent, +                                    mock_is_authenticated): +        api = Api('https://api.test:4430') +        credentials = UsernamePassword('username', 'password') + +        mock_is_authenticated.return_value = True +        session = Session(credentials, api, 'fake path') +        session._uuid = '123' + +        response = yield session.update_recovery_code('RECOVERY_CODE') +        mock_http_request.assert_called_with( +            ANY, 'https://api.test:4430/1/users/123', +            method='PUT', +            token=None, +            values={'user[recovery_code_salt]': ANY, +                    'user[recovery_code_verifier]': ANY}) | 
