From 94dce7c9b494ce595c7dc73e0dda70bedecf455e Mon Sep 17 00:00:00 2001 From: Casper van der Wel Date: Wed, 2 Aug 2023 10:53:21 +0200 Subject: [PATCH] Validate authorize query --- nens_auth_client/cognito.py | 11 +++++++++++ nens_auth_client/tests/test_authorize_view.py | 8 ++++++++ nens_auth_client/views.py | 10 ++++++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/nens_auth_client/cognito.py b/nens_auth_client/cognito.py index 8864440..d025be5 100644 --- a/nens_auth_client/cognito.py +++ b/nens_auth_client/cognito.py @@ -147,3 +147,14 @@ def load_key(header, payload): claims.validate(leeway=leeway) return claims + + def validate_authorize_request_params(self, query_params): + """Returns a list of validation errors""" + result = [] + if query_params.get("error"): + return result + if not query_params.get("code"): + result.append("missing 'code' parameter") + if not query_params.get("state"): + result.append("missing 'state' parameter") + return result diff --git a/nens_auth_client/tests/test_authorize_view.py b/nens_auth_client/tests/test_authorize_view.py index 78a491b..d94051f 100644 --- a/nens_auth_client/tests/test_authorize_view.py +++ b/nens_auth_client/tests/test_authorize_view.py @@ -383,6 +383,14 @@ def test_authorize_error_with_description(rf): views.authorize(request) +@pytest.mark.parametrize("params", ["", "code=foo", "state=bar"]) +def test_authorize_missing_query_params(rf): + request = rf.get(f"http://testserver/authorize/?{params}") + request.session = {} + response = views.authorize(request) + assert response.status_code == 400 + + def test_token_error(rq_mocker, rf, openid_configuration): rq_mocker.post( openid_configuration["token_endpoint"], diff --git a/nens_auth_client/views.py b/nens_auth_client/views.py index 5c71d44..e606415 100644 --- a/nens_auth_client/views.py +++ b/nens_auth_client/views.py @@ -7,7 +7,7 @@ from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied -from django.http.response import HttpResponseRedirect +from django.http.response import HttpResponseRedirect, JsonResponse from django.shortcuts import get_object_or_404 from django.urls import reverse @@ -134,6 +134,10 @@ def authorize(request): HTTP 302 Redirect to the 'next' query parameter (see login view) + missing query parameters: + + HTTP 400 Bad Request + invalid state / expired code: HTTP 302 Redirect to the login view ('next' parameter is persisted, but @@ -150,7 +154,9 @@ def authorize(request): acceptable invitation. """ client = get_oauth_client() - # client.check_error_in_query_params(request) + validation_errors = client.validate_authorize_request_params(request.GET) + if validation_errors: + return JsonResponse({"errors": validation_errors}, status=400) try: tokens = client.authorize_access_token( request, timeout=settings.NENS_AUTH_TIMEOUT