From c75d5884f3a1c165f1ff59dba6f403f68904650c Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Sat, 2 Jul 2022 10:54:50 +0200 Subject: [PATCH] idp_oidc: do not delete code on resolution by token endpoint (#66893) --- src/authentic2_idp_oidc/views.py | 1 - tests/idp_oidc/test_misc.py | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/authentic2_idp_oidc/views.py b/src/authentic2_idp_oidc/views.py index 1305b196..4a8fa1a9 100644 --- a/src/authentic2_idp_oidc/views.py +++ b/src/authentic2_idp_oidc/views.py @@ -733,7 +733,6 @@ def tokens_from_authz_code(request): raise InvalidRequest(_('Parameter "code" is invalid'), client=client) if not oidc_code.is_valid(): raise InvalidRequest(_('Parameter "code" has expired or user is disconnected'), client=client) - models.OIDCCode.objects.filter(uuid=code).delete() redirect_uri = request.POST.get('redirect_uri') if oidc_code.redirect_uri != redirect_uri: raise InvalidRequest(_('Parameter "redirect_uri" does not match the code.'), client=client) diff --git a/tests/idp_oidc/test_misc.py b/tests/idp_oidc/test_misc.py index eb2233ee..8e36b1a8 100644 --- a/tests/idp_oidc/test_misc.py +++ b/tests/idp_oidc/test_misc.py @@ -1801,3 +1801,52 @@ def test_authorize_with_view_restriction(oidc_settings, app, simple_oidc_client, response = app.get(authorize_url) assert response.location.startswith('/accounts/edit/required/?') + + +def test_token_endpoint_code_timeout(oidc_client, oidc_settings, simple_user, app, caplog, rf, freezer): + '''Verify codes are valid during 30 seconds''' + utils.login(app, simple_user) + + oidc_client.authorization_mode = oidc_client.AUTHORIZATION_MODE_NONE + oidc_client.save() + + redirect_uri = oidc_client.redirect_uris.split()[0] + params = { + 'client_id': oidc_client.client_id, + 'scope': 'openid profile email', + 'redirect_uri': redirect_uri, + 'state': 'xxx', + 'nonce': 'yyy', + 'login_hint': 'backoffice john@example.com', + 'response_type': 'code', + } + authorize_url = make_url('oidc-authorize', params=params) + response = app.get(authorize_url) + location = urllib.parse.urlparse(response['Location']) + query = urllib.parse.parse_qs(location.query) + code = query['code'][0] + + def resolve_code(**kwargs): + token_url = make_url('oidc-token') + return app.post( + token_url, + params={ + 'grant_type': 'authorization_code', + 'code': code, + 'redirect_uri': oidc_client.redirect_uris.split()[0], + }, + headers=client_authentication_headers(oidc_client), + **kwargs, + ) + + response = resolve_code() + assert 'access_token' in response.json + + freezer.move_to(datetime.timedelta(seconds=29)) + response = resolve_code() + assert 'access_token' in response.json + + # code should expire after 30 seconds + freezer.move_to(datetime.timedelta(seconds=1.1)) + response = resolve_code(status=400) + assert 'access_token' not in response.json -- 2.35.1