def test_without_user_and_with_valid_token(self): """Tests resolving with a valid token on a request without user""" token = create_jwt(self.user) request = HttpRequest() request.META[HTTP_AUTHORIZATION_HEADER] = f"Token {token}" info = InfoObject(context=request) def next(root, info, **kwargs): self.assertTrue(hasattr(info.context, "user")) self.assertEquals(info.context.user, self.user) next = Mock(wraps=next) settings = { "AUTHENTICATION_BACKENDS": ( "django_ariadne_jwt.backends.JSONWebTokenBackend", "django.contrib.auth.backends.ModelBackend", ) } with self.settings(**settings): middleware = JSONWebTokenMiddleware() middleware.resolve(next, {}, info) self.assertTrue(next.called)
def test_valid_jwt_decoding(self): """Tests decoding of a valid JWT""" expected_username = "******" user = User(username=expected_username) token = utils.create_jwt(user) data = utils.decode_jwt(token) self.assertIn("user", data) self.assertEqual(data["user"], expected_username)
def test_jwt_creation_for_authenticated_user(self): """Tests the creation of a JWT for an authenticated user""" user = User(username="******") token = utils.create_jwt(user) self.assertIsNotNone(token) self.assertIsInstance(token, str) parts = token.split(".") self.assertEqual(len(parts), 3)
def test_refreshing_for_valid_token(self): """Test refreshing a valid token""" info = InfoObject(context=HttpRequest()) token = utils.create_jwt(self.user) resolved_data = resolvers.resolve_refresh_token(None, info, token) self.assertIsNotNone(resolved_data) self.assertIn("token", resolved_data) self.assertIsInstance(resolved_data["token"], str)
def test_login_required_decorator_with_valid_token(self): """Tests the login required decorator called with valid token""" type_definitions = ariadne.gql(""" type Query { test: String! } """) query_type = ariadne.QueryType() def resolve_test(_, info): request = info.context self.assertTrue(hasattr(request, "user")) self.assertEqual(request.user, self.user) return "Test!" resolve_test = Mock(wraps=resolve_test) decorated_resolve_test = Mock(wraps=login_required(resolve_test)) query_type.set_field("test", decorated_resolve_test) schema = ariadne.make_executable_schema([type_definitions], [query_type]) middleware = [JSONWebTokenMiddleware()] token = create_jwt(self.user) request = HttpRequest() request.META[HTTP_AUTHORIZATION_HEADER] = f"Token {token}" settings = { "AUTHENTICATION_BACKENDS": ( "django_ariadne_jwt.backends.JSONWebTokenBackend", "django.contrib.auth.backends.ModelBackend", ) } with self.settings(**settings): ariadne.graphql_sync( schema, { "query": """ query { test } """ }, context_value=request, middleware=middleware, ) self.assertTrue(resolve_test.called)
def test_expired_jwt_decoding(self): """Tests decoding of an expired JWT""" expected_username = "******" user = User(username=expected_username) settings = {"JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=-10)} with self.settings(**settings): token = utils.create_jwt(user) with self.assertRaises(exceptions.ExpiredTokenError): utils.decode_jwt(token)
def test_refreshing_jwt_at_end_of_life(self): """Tests refreshing a JWT for token at its end of life""" user = User.objects.create(username="******") settings = { "JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=3), "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(seconds=0), } with self.settings(**settings): token = utils.create_jwt(user) with self.assertRaises(exceptions.MaximumTokenLifeReachedError): utils.refresh_jwt(token) # Refresh the token
def test_jwt_with_non_existent_user(self): """Tests refreshing a JWT for a user that doesn't exist""" expected_username = "******" user = User(username=expected_username) settings = { "JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=3), "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(seconds=3), } with self.settings(**settings): token = utils.create_jwt(user) with self.assertRaises(exceptions.InvalidTokenError): utils.refresh_jwt(token)
def test_verification_for_expired_token(self): """Test verification of an expired token""" request = HttpRequest() info = InfoObject(context=request) settings = {"JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=-10)} with self.settings(**settings): token = utils.create_jwt(self.user) resolved_data = resolvers.resolve_verify_token(None, info, token) self.assertIsNotNone(resolved_data) self.assertIn("valid", resolved_data) self.assertFalse(resolved_data["valid"]) self.assertNotIn("username", resolved_data)
def test_authentication_with_valid_token(self): """Tests the authentication of a user from a valid token""" token = utils.create_jwt(self.user) request = HttpRequest() settings = { "AUTHENTICATION_BACKENDS": ( "django_ariadne_jwt.backends.JSONWebTokenBackend", ) } with self.settings(**settings): user = authenticate(request, token=token) self.assertIsNotNone(user) self.assertEqual(user, self.user)
def test_refreshing_token_not_at_end_of_life(self): """Test refreshing a token which is at its end of life""" request = HttpRequest() info = InfoObject(context=request) settings = { "JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=3), "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(seconds=1), } with self.settings(**settings): token = utils.create_jwt(self.user) resolved_data = resolvers.resolve_refresh_token(None, info, token) self.assertIsNotNone(resolved_data) self.assertIn("token", resolved_data) self.assertIsInstance(resolved_data["token"], str)
def test_refreshing_jwt_not_at_end_of_life(self): """Tests refreshing a JWT for token at its end of life""" user = User.objects.create(username="******") settings = { "JWT_EXPIRATION_DELTA": datetime.timedelta(seconds=10), "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(seconds=10), } with self.settings(**settings): first_token = utils.create_jwt(user) decoded_first_token = utils.decode_jwt(first_token) second_token = utils.refresh_jwt(first_token) # Refresh the token decoded_second_token = utils.decode_jwt(second_token) self.assertIsNotNone(second_token) self.assertIn(utils.ORIGINAL_IAT_CLAIM, decoded_second_token) self.assertEqual( decoded_second_token[utils.ORIGINAL_IAT_CLAIM], decoded_first_token["iat"], )
def test_with_user_and_valid_token(self): """Tests that the middleware respects the already authenticated user""" token = create_jwt(self.other_user) request = HttpRequest() request.user = self.user request.META[HTTP_AUTHORIZATION_HEADER] = f"Token {token}" info = InfoObject(context=request) def next(root, info, **kwargs): self.assertTrue(hasattr(info.context, "user")) self.assertEquals(info.context.user, self.user) settings = { "AUTHENTICATION_BACKENDS": ( "django_ariadne_jwt.backends.JSONWebTokenBackend", "django.contrib.auth.backends.ModelBackend", ) } with self.settings(**settings): middleware = JSONWebTokenMiddleware() middleware.resolve(next, {}, info)
def test_jwt_creation_for_non_authenticated_user(self): """Tests the creation of a JWT for a non-authenticated user""" with self.assertRaises(exceptions.AuthenticatedUserRequiredError): user = AnonymousUser() utils.create_jwt(user)
def tests_regular_requests(self): # fmt: off """Tests that the middleware is being called correctly on """ \ """regular requests""" # fmt: on type_definitions = ariadne.gql( """ type Query { test: String! } """ ) query_type = ariadne.QueryType() def resolve_test(_, info): request = info.context self.assertTrue(hasattr(request, "user")) self.assertEqual(request.user, self.user) return "Test!" resolve_test = Mock(wraps=resolve_test) query_type.set_field("test", resolve_test) schema = ariadne.make_executable_schema( [type_definitions], [query_type] ) middleware = JSONWebTokenMiddleware() token = create_jwt(self.user) request = HttpRequest() request.META[HTTP_AUTHORIZATION_HEADER] = f"Token {token}" settings = { "AUTHENTICATION_BACKENDS": ( "django_ariadne_jwt.backends.JSONWebTokenBackend", "django.contrib.auth.backends.ModelBackend", ) } with self.settings(**settings): # Spies on the JSONWebTokenMiddleware.resolve method def spy(*args, **kwargs): return JSONWebTokenMiddleware.resolve( middleware, *args, **kwargs ) spy = Mock(wraps=spy) with patch.object(middleware, "resolve", new=spy): ariadne.graphql_sync( schema, { "query": """ query { test } """ }, context_value=request, middleware=[middleware], ) self.assertTrue(spy.called) self.assertTrue(resolve_test.called)