예제 #1
0
 def test_login_success(self):
     user = UserProfile.objects.create(username='******',
                                       email='*****@*****.**')
     identity = {'email': '*****@*****.**', 'uid': '9001'}
     self.fxa_identify.return_value = identity
     response = self.client.post(self.url, {
         'code': 'code',
         'state': 'some-blob'
     })
     assert response.status_code == 200
     assert response.data['email'] == '*****@*****.**'
     token = response.data['token']
     verify = WebTokenAuthentication().authenticate_token(token)
     assert verify[0] == user
     self.update_user.assert_called_with(user, identity)
예제 #2
0
 def test_success_with_account_logs_in(self):
     user = UserProfile.objects.create(username='******',
                                       email='*****@*****.**',
                                       fxa_id='10')
     identity = {'email': '*****@*****.**', 'uid': '9001'}
     self.fxa_identify.return_value = identity
     response = self.client.get(self.url, {
         'code': 'code',
         'state': self.fxa_state
     })
     self.assertRedirects(response, reverse('home'))
     token = response.cookies['api_auth_token'].value
     verify = WebTokenAuthentication().authenticate_token(token)
     assert verify[0] == user
     self.login_user.assert_called_with(mock.ANY, user, identity)
     assert not self.register_user.called
예제 #3
0
 def test_success_no_account_registers(self):
     user_qs = UserProfile.objects.filter(email='*****@*****.**')
     assert not user_qs.exists()
     identity = {u'email': u'*****@*****.**', u'uid': u'e0b6f'}
     self.fxa_identify.return_value = identity
     self.register_user.side_effect = (
         lambda r, i: UserProfile.objects.create(
             username='******', email='*****@*****.**', fxa_id='e0b6f'))
     response = self.client.get(self.url, {
         'code': 'codes!!',
         'state': self.fxa_state
     })
     self.fxa_identify.assert_called_with('codes!!', config=FXA_CONFIG)
     assert not self.login_user.called
     self.register_user.assert_called_with(mock.ANY, identity)
     token = response.cookies['api_auth_token'].value
     verify = WebTokenAuthentication().authenticate_token(token)
     assert verify[0] == UserProfile.objects.get(username='******')
예제 #4
0
 def login_user(self, user):
     identity = {
         'username': user.username,
         'email': user.email,
         'uid': user.fxa_id,
     }
     self.initialize_session({'fxa_state': 'myfxastate'})
     with mock.patch('olympia.accounts.views.verify.fxa_identify',
                     lambda code, config: identity):
         response = self.client.get(
             '{url}?code={code}&state={state}'.format(
                 url=reverse('accounts.authenticate'),
                 state='myfxastate',
                 code='thecode'))
         token = response.cookies[views.API_TOKEN_COOKIE].value
         assert token
         verify = WebTokenAuthentication().authenticate_token(token)
         assert verify[0] == user
         assert self.client.session['_auth_user_id'] == str(user.id)
         return token
예제 #5
0
 def setUp(self):
     super(TestWebTokenAuthentication, self).setUp()
     self.auth = WebTokenAuthentication()
     self.factory = RequestFactory()
     self.user = user_factory(read_dev_agreement=datetime.now())
예제 #6
0
class TestWebTokenAuthentication(TestCase):
    client_class = APITestClient

    def setUp(self):
        super(TestWebTokenAuthentication, self).setUp()
        self.auth = WebTokenAuthentication()
        self.factory = RequestFactory()
        self.user = user_factory(read_dev_agreement=datetime.now())

    def _authenticate(self, token):
        url = absolutify('/api/v3/whatever/')
        prefix = WebTokenAuthentication.auth_header_prefix
        request = self.factory.post(url,
                                    HTTP_HOST='testserver',
                                    HTTP_AUTHORIZATION='{0} {1}'.format(
                                        prefix, token))

        return self.auth.authenticate(request)

    def test_success(self):
        token = self.client.generate_api_token(self.user)
        user, _ = self._authenticate(token)
        assert user == self.user

    def test_authenticate_header(self):
        request = self.factory.post('/api/v3/whatever/')
        assert (self.auth.authenticate_header(request) == 'bearer realm="api"')

    def test_wrong_header_only_prefix(self):
        request = self.factory.post(
            '/api/v3/whatever/',
            HTTP_AUTHORIZATION=WebTokenAuthentication.auth_header_prefix)
        with self.assertRaises(AuthenticationFailed) as exp:
            self.auth.authenticate(request)
        assert exp.exception.detail['code'] == 'ERROR_INVALID_HEADER'
        assert exp.exception.detail['detail'] == (
            'Invalid Authorization header. No credentials provided.')

    def test_wrong_header_too_many_spaces(self):
        request = self.factory.post(
            '/api/v3/whatever/',
            HTTP_AUTHORIZATION='{} foo bar'.format(
                WebTokenAuthentication.auth_header_prefix))
        with self.assertRaises(AuthenticationFailed) as exp:
            self.auth.authenticate(request)
        assert exp.exception.detail['code'] == 'ERROR_INVALID_HEADER'
        assert exp.exception.detail['detail'] == (
            'Invalid Authorization header. '
            'Credentials string should not contain spaces.')

    def test_no_token(self):
        request = self.factory.post('/api/v3/whatever/')
        self.auth.authenticate(request) is None

    def test_expired_token(self):
        old_date = datetime.now() - timedelta(
            seconds=settings.SESSION_COOKIE_AGE + 1)
        with freeze_time(old_date):
            token = self.client.generate_api_token(self.user)
        with self.assertRaises(AuthenticationFailed) as exp:
            self._authenticate(token)
        assert exp.exception.detail['code'] == 'ERROR_SIGNATURE_EXPIRED'
        assert exp.exception.detail['detail'] == 'Signature has expired.'

    def test_still_valid_token(self):
        not_so_old_date = datetime.now() - timedelta(
            seconds=settings.SESSION_COOKIE_AGE - 30)
        with freeze_time(not_so_old_date):
            token = self.client.generate_api_token(self.user)
        assert self._authenticate(token)[0] == self.user

    def test_bad_token(self):
        token = 'garbage'
        with self.assertRaises(AuthenticationFailed) as exp:
            self._authenticate(token)
        assert exp.exception.detail['code'] == 'ERROR_DECODING_SIGNATURE'
        assert exp.exception.detail['detail'] == 'Error decoding signature.'

    def test_user_id_is_none(self):
        token = self.client.generate_api_token(self.user, user_id=None)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_no_user_id_in_payload(self):
        data = {
            'auth_hash': self.user.get_session_auth_hash(),
        }
        token = signing.dumps(data, salt=WebTokenAuthentication.salt)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_no_auth_hash_in_payload(self):
        data = {
            'user_id': self.user.pk,
        }
        token = signing.dumps(data, salt=WebTokenAuthentication.salt)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_user_deleted(self):
        self.user.delete()
        token = self.client.generate_api_token(self.user)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_invalid_user_not_found(self):
        token = self.client.generate_api_token(self.user, user_id=-1)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_invalid_user_other_user(self):
        user2 = user_factory(read_dev_agreement=datetime.now())
        token = self.client.generate_api_token(self.user, user_id=user2.pk)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_wrong_auth_id(self):
        token = self.client.generate_api_token(self.user)
        self.user.update(auth_id=self.user.auth_id + 42)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_make_sure_token_is_decodable(self):
        token = self.client.generate_api_token(self.user)
        # A token is really a string containing the json dict,
        # a timestamp and a signature, separated by ':'. The base64 encoding
        # lacks padding, which is why we need to use signing.b64_decode() which
        # handles that for us.
        data = json.loads(signing.b64_decode(token.split(':')[0]))
        assert data['user_id'] == self.user.pk
        assert data['auth_hash'] == self.user.get_session_auth_hash()
 def setUp(self):
     super(TestWebTokenAuthentication, self).setUp()
     self.auth = WebTokenAuthentication()
     self.factory = RequestFactory()
     self.user = user_factory(read_dev_agreement=datetime.now())
class TestWebTokenAuthentication(TestCase):
    client_class = APITestClient

    def setUp(self):
        super(TestWebTokenAuthentication, self).setUp()
        self.auth = WebTokenAuthentication()
        self.factory = RequestFactory()
        self.user = user_factory(read_dev_agreement=datetime.now())

    def _authenticate(self, token):
        url = absolutify('/api/v3/whatever/')
        prefix = WebTokenAuthentication.auth_header_prefix
        request = self.factory.post(
            url, HTTP_HOST='testserver',
            HTTP_AUTHORIZATION='{0} {1}'.format(prefix, token))

        return self.auth.authenticate(request)

    def test_success(self):
        token = self.client.generate_api_token(self.user)
        user, _ = self._authenticate(token)
        assert user == self.user

    def test_authenticate_header(self):
        request = self.factory.post('/api/v3/whatever/')
        assert (self.auth.authenticate_header(request) ==
                'bearer realm="api"')

    def test_wrong_header_only_prefix(self):
        request = self.factory.post(
            '/api/v3/whatever/',
            HTTP_AUTHORIZATION=WebTokenAuthentication.auth_header_prefix)
        with self.assertRaises(AuthenticationFailed) as exp:
            self.auth.authenticate(request)
        assert exp.exception.detail['code'] == 'ERROR_INVALID_HEADER'
        assert exp.exception.detail['detail'] == (
            'Invalid Authorization header. No credentials provided.')

    def test_wrong_header_too_many_spaces(self):
        request = self.factory.post(
            '/api/v3/whatever/',
            HTTP_AUTHORIZATION='{} foo bar'.format(
                WebTokenAuthentication.auth_header_prefix))
        with self.assertRaises(AuthenticationFailed) as exp:
            self.auth.authenticate(request)
        assert exp.exception.detail['code'] == 'ERROR_INVALID_HEADER'
        assert exp.exception.detail['detail'] == (
            'Invalid Authorization header. '
            'Credentials string should not contain spaces.')

    def test_no_token(self):
        request = self.factory.post('/api/v3/whatever/')
        self.auth.authenticate(request) is None

    def test_expired_token(self):
        old_date = datetime.now() - timedelta(
            seconds=settings.SESSION_COOKIE_AGE + 1)
        with freeze_time(old_date):
            token = self.client.generate_api_token(self.user)
        with self.assertRaises(AuthenticationFailed) as exp:
            self._authenticate(token)
        assert exp.exception.detail['code'] == 'ERROR_SIGNATURE_EXPIRED'
        assert exp.exception.detail['detail'] == 'Signature has expired.'

    def test_still_valid_token(self):
        not_so_old_date = datetime.now() - timedelta(
            seconds=settings.SESSION_COOKIE_AGE - 30)
        with freeze_time(not_so_old_date):
            token = self.client.generate_api_token(self.user)
        assert self._authenticate(token)[0] == self.user

    def test_bad_token(self):
        token = 'garbage'
        with self.assertRaises(AuthenticationFailed) as exp:
            self._authenticate(token)
        assert exp.exception.detail['code'] == 'ERROR_DECODING_SIGNATURE'
        assert exp.exception.detail['detail'] == 'Error decoding signature.'

    def test_user_id_is_none(self):
        token = self.client.generate_api_token(self.user, user_id=None)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_no_user_id_in_payload(self):
        data = {
            'auth_hash': self.user.get_session_auth_hash(),
        }
        token = signing.dumps(data, salt=WebTokenAuthentication.salt)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_no_auth_hash_in_payload(self):
        data = {
            'user_id': self.user.pk,
        }
        token = signing.dumps(data, salt=WebTokenAuthentication.salt)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_user_deleted(self):
        self.user.delete()
        token = self.client.generate_api_token(self.user)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_invalid_user_not_found(self):
        token = self.client.generate_api_token(self.user, user_id=-1)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_invalid_user_other_user(self):
        user2 = user_factory(read_dev_agreement=datetime.now())
        token = self.client.generate_api_token(self.user, user_id=user2.pk)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_wrong_auth_id(self):
        token = self.client.generate_api_token(self.user)
        self.user.update(auth_id=self.user.auth_id + 42)
        with self.assertRaises(AuthenticationFailed):
            self._authenticate(token)

    def test_make_sure_token_is_decodable(self):
        token = self.client.generate_api_token(self.user)
        # A token is really a string containing the json dict,
        # a timestamp and a signature, separated by ':'. The base64 encoding
        # lacks padding, which is why we need to use signing.b64_decode() which
        # handles that for us.
        data = json.loads(signing.b64_decode(token.split(':')[0]))
        assert data['user_id'] == self.user.pk
        assert data['auth_hash'] == self.user.get_session_auth_hash()