def test_user_creation_failure(self, mock_get_or_create): """ Verify that IntegrityErrors beyond the configured retry limit are raised. """ authentication = JwtAuthentication() errors = [IntegrityError] * (MAX_RETRIES + 1) mock_get_or_create.side_effect = errors + [(User.objects.create(username=self.USERNAME), False)] with self.assertRaises(IntegrityError): authentication.authenticate_credentials({'preferred_username': self.USERNAME})
def test_required_claims(self, claim): """ Verify that tokens that do not carry 'exp' or 'iat' claims are rejected """ authentication = JwtAuthentication() user = UserFactory() jwt_payload = self.default_payload(user) del jwt_payload[claim] jwt_value = self.generate_token(jwt_payload) request = APIRequestFactory().get('dummy', HTTP_AUTHORIZATION='JWT {}'.format(jwt_value)) with self.assertRaises(AuthenticationFailed): authentication.authenticate(request)
def test_no_preferred_username(self): """ Ensure the service gracefully handles an inability to extract a username from the id token. """ # with preferred_username: all good authentication = JwtAuthentication() user = authentication.authenticate_credentials({'preferred_username': self.USERNAME}) self.assertEqual(user.username, self.USERNAME) # missing preferred_username: exception authentication = JwtAuthentication() with self.assertRaises(AuthenticationFailed): authentication.authenticate_credentials({})
def test_required_claims(self, claim): """ Verify that tokens that do not carry 'exp' or 'iat' claims are rejected """ authentication = JwtAuthentication() user = UserFactory() jwt_payload = self.default_payload(user) del jwt_payload[claim] jwt_value = self.generate_token(jwt_payload) request = APIRequestFactory().get( 'dummy', HTTP_AUTHORIZATION='JWT {}'.format(jwt_value)) with self.assertRaises(AuthenticationFailed): authentication.authenticate(request)
def test_robust_user_creation(self, retries, mock_get_or_create): """ Verify that the service is robust to IntegrityErrors during user creation. """ authentication = JwtAuthentication() # If side_effect is an iterable, each call to the mock will return # the next value from the iterable. # See: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect. errors = [IntegrityError] * retries mock_get_or_create.side_effect = errors + [(User.objects.create(username=self.USERNAME), False)] user = authentication.authenticate_credentials({'preferred_username': self.USERNAME}) self.assertEqual(user.username, self.USERNAME)
def test_user_creation_failure(self, mock_get_or_create): """ Verify that IntegrityErrors beyond the configured retry limit are raised. """ authentication = JwtAuthentication() errors = [IntegrityError] * (MAX_RETRIES + 1) mock_get_or_create.side_effect = errors + [ (User.objects.create(username=self.USERNAME), False) ] with self.assertRaises(IntegrityError): authentication.authenticate_credentials( {'preferred_username': self.USERNAME})
def test_robust_user_creation(self, retries, mock_get_or_create): """ Verify that the service is robust to IntegrityErrors during user creation. """ authentication = JwtAuthentication() # If side_effect is an iterable, each call to the mock will return # the next value from the iterable. # See: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.side_effect. errors = [IntegrityError] * retries mock_get_or_create.side_effect = errors + [ (User.objects.create(username=self.USERNAME), False) ] user = authentication.authenticate_credentials( {'preferred_username': self.USERNAME}) self.assertEqual(user.username, self.USERNAME)
def test_leeway(self, claim, offset): """ Verify that the service allows the specified amount of leeway (in seconds) when nonzero and validating "exp" and "iat" claims. """ authentication = JwtAuthentication() user = UserFactory() jwt_value = self.generate_id_token(user, **{claim: int(time.time()) + offset}) request = APIRequestFactory().get('dummy', HTTP_AUTHORIZATION='JWT {}'.format(jwt_value)) # with no leeway, these requests should not be authenticated with mock.patch.object(drf_jwt_settings, 'JWT_LEEWAY', 0): with self.assertRaises(AuthenticationFailed): authentication.authenticate(request) # with enough leeway, these requests should be authenticated with mock.patch.object(drf_jwt_settings, 'JWT_LEEWAY', abs(offset)): self.assertEqual( (user, jwt_value), authentication.authenticate(request) )
def test_leeway(self, claim, offset): """ Verify that the service allows the specified amount of leeway (in seconds) when nonzero and validating "exp" and "iat" claims. """ authentication = JwtAuthentication() user = UserFactory() jwt_value = self.generate_id_token( user, **{claim: int(time.time()) + offset}) request = APIRequestFactory().get( 'dummy', HTTP_AUTHORIZATION='JWT {}'.format(jwt_value)) # with no leeway, these requests should not be authenticated with mock.patch.object(drf_jwt_settings, 'JWT_LEEWAY', 0): with self.assertRaises(AuthenticationFailed): authentication.authenticate(request) # with enough leeway, these requests should be authenticated with mock.patch.object(drf_jwt_settings, 'JWT_LEEWAY', abs(offset)): self.assertEqual((user, jwt_value), authentication.authenticate(request))
def test_no_preferred_username(self): """ Ensure the service gracefully handles an inability to extract a username from the id token. """ # with preferred_username: all good authentication = JwtAuthentication() user = authentication.authenticate_credentials( {'preferred_username': self.USERNAME}) self.assertEqual(user.username, self.USERNAME) # missing preferred_username: exception authentication = JwtAuthentication() with self.assertRaises(AuthenticationFailed): authentication.authenticate_credentials({})