diff --git a/tests/oidc/test_authorization_code_flow.py b/tests/oidc/test_authorization_code_flow.py index 3c3187de..651f164e 100644 --- a/tests/oidc/test_authorization_code_flow.py +++ b/tests/oidc/test_authorization_code_flow.py @@ -4,6 +4,7 @@ from urllib.parse import urlsplit import freezegun from authlib.jose import jwt from authlib.oauth2.rfc7636 import create_s256_code_challenge +from canaille.models import User from canaille.oidc.models import AuthorizationCode from canaille.oidc.models import Consent from canaille.oidc.models import Token @@ -764,3 +765,87 @@ def test_authorization_code_request_scope_too_large( for consent in consents: consent.delete() + + +def test_authorization_code_expired(testclient, user, client): + with freezegun.freeze_time("2020-01-01 01:00:00"): + res = testclient.get( + "/oauth/authorize", + params=dict( + response_type="code", + client_id=client.client_id, + scope="openid profile email groups address phone", + nonce="somenonce", + ), + status=200, + ) + res.form["login"] = "John (johnny) Doe" + res.form["password"] = "correct horse battery staple" + res = res.form.submit(name="answer", value="accept").follow() + res = res.form.submit(name="answer", value="accept", status=302) + params = parse_qs(urlsplit(res.location).query) + code = params["code"][0] + + with freezegun.freeze_time("2021-01-01 01:00:00"): + res = testclient.post( + "/oauth/token", + params=dict( + grant_type="authorization_code", + code=code, + scope="openid profile email groups address phone", + redirect_uri=client.redirect_uris[0], + ), + headers={"Authorization": f"Basic {client_credentials(client)}"}, + status=400, + ) + assert res.json == { + "error": "invalid_grant", + "error_description": 'Invalid "code" in request.', + } + + +def test_invalid_user(testclient, admin, client): + user = User( + objectClass=["inetOrgPerson"], + cn="John Doe", + sn="Doe", + uid="temp", + mail="john@doe.com", + userPassword="{SSHA}fw9DYeF/gHTHuVMepsQzVYAkffGcU8Fz", + ) + user.save() + + res = testclient.get( + "/oauth/authorize", + params=dict( + response_type="code", + client_id=client.client_id, + scope="openid profile email groups address phone", + nonce="somenonce", + ), + status=200, + ) + res.form["login"] = "Temp" + res.form["password"] = "correct horse battery staple" + res = res.form.submit(name="answer", value="accept", status=302).follow() + res = res.form.submit(name="answer", value="accept", status=302) + params = parse_qs(urlsplit(res.location).query) + code = params["code"][0] + + user.delete() + + res = testclient.post( + "/oauth/token", + params=dict( + grant_type="authorization_code", + code=code, + scope="openid profile email groups address phone", + redirect_uri=client.redirect_uris[0], + ), + headers={"Authorization": f"Basic {client_credentials(client)}"}, + status=400, + ) + assert res.json == { + "error": "invalid_grant", + "error_description": 'There is no "user" for this code.', + }