|
4 | 4 | from django.test import RequestFactory, TestCase
|
5 | 5 | from django.urls import reverse
|
6 | 6 | from django.utils import timezone
|
| 7 | +from pytest_django.asserts import assertRedirects |
7 | 8 |
|
8 | 9 | from oauth2_provider.exceptions import ClientIdMissmatch, InvalidOIDCClientError, InvalidOIDCRedirectURIError
|
9 | 10 | from oauth2_provider.models import get_access_token_model, get_id_token_model, get_refresh_token_model
|
@@ -197,37 +198,37 @@ def test_validate_logout_request(oidc_tokens, public_application, other_user, rp
|
197 | 198 | id_token_hint=None,
|
198 | 199 | client_id=None,
|
199 | 200 | post_logout_redirect_uri=None,
|
200 |
| - ) == (True, (None, None)) |
| 201 | + ) == (True, (None, None), None) |
201 | 202 | assert validate_logout_request(
|
202 | 203 | request=mock_request_for(oidc_tokens.user),
|
203 | 204 | id_token_hint=None,
|
204 | 205 | client_id=client_id,
|
205 | 206 | post_logout_redirect_uri=None,
|
206 |
| - ) == (True, (None, application)) |
| 207 | + ) == (True, (None, application), None) |
207 | 208 | assert validate_logout_request(
|
208 | 209 | request=mock_request_for(oidc_tokens.user),
|
209 | 210 | id_token_hint=None,
|
210 | 211 | client_id=client_id,
|
211 | 212 | post_logout_redirect_uri="http://example.org",
|
212 |
| - ) == (True, ("http://example.org", application)) |
| 213 | + ) == (True, ("http://example.org", application), None) |
213 | 214 | assert validate_logout_request(
|
214 | 215 | request=mock_request_for(oidc_tokens.user),
|
215 | 216 | id_token_hint=id_token,
|
216 | 217 | client_id=None,
|
217 | 218 | post_logout_redirect_uri="http://example.org",
|
218 |
| - ) == (ALWAYS_PROMPT, ("http://example.org", application)) |
| 219 | + ) == (ALWAYS_PROMPT, ("http://example.org", application), oidc_tokens.user) |
219 | 220 | assert validate_logout_request(
|
220 | 221 | request=mock_request_for(other_user),
|
221 | 222 | id_token_hint=id_token,
|
222 | 223 | client_id=None,
|
223 | 224 | post_logout_redirect_uri="http://example.org",
|
224 |
| - ) == (True, ("http://example.org", application)) |
| 225 | + ) == (True, ("http://example.org", application), oidc_tokens.user) |
225 | 226 | assert validate_logout_request(
|
226 | 227 | request=mock_request_for(oidc_tokens.user),
|
227 | 228 | id_token_hint=id_token,
|
228 | 229 | client_id=client_id,
|
229 | 230 | post_logout_redirect_uri="http://example.org",
|
230 |
| - ) == (ALWAYS_PROMPT, ("http://example.org", application)) |
| 231 | + ) == (ALWAYS_PROMPT, ("http://example.org", application), oidc_tokens.user) |
231 | 232 | with pytest.raises(ClientIdMissmatch):
|
232 | 233 | validate_logout_request(
|
233 | 234 | request=mock_request_for(oidc_tokens.user),
|
@@ -519,6 +520,47 @@ def test_token_deletion_on_logout(oidc_tokens, loggend_in_client, rp_settings):
|
519 | 520 | assert all([token.revoked <= timezone.now() for token in RefreshToken.objects.all()])
|
520 | 521 |
|
521 | 522 |
|
| 523 | +@pytest.mark.django_db |
| 524 | +def test_token_deletion_on_logout_expired_session(oidc_tokens, client, rp_settings): |
| 525 | + AccessToken = get_access_token_model() |
| 526 | + IDToken = get_id_token_model() |
| 527 | + RefreshToken = get_refresh_token_model() |
| 528 | + assert AccessToken.objects.count() == 1 |
| 529 | + assert IDToken.objects.count() == 1 |
| 530 | + assert RefreshToken.objects.count() == 1 |
| 531 | + rsp = client.get( |
| 532 | + reverse("oauth2_provider:rp-initiated-logout"), |
| 533 | + data={ |
| 534 | + "id_token_hint": oidc_tokens.id_token, |
| 535 | + "client_id": oidc_tokens.application.client_id, |
| 536 | + }, |
| 537 | + ) |
| 538 | + assert rsp.status_code == 200 |
| 539 | + assert not is_logged_in(client) |
| 540 | + # Check that all tokens are active. |
| 541 | + access_token = AccessToken.objects.get() |
| 542 | + assert not access_token.is_expired() |
| 543 | + id_token = IDToken.objects.get() |
| 544 | + assert not id_token.is_expired() |
| 545 | + refresh_token = RefreshToken.objects.get() |
| 546 | + assert refresh_token.revoked is None |
| 547 | + |
| 548 | + rsp = client.post( |
| 549 | + reverse("oauth2_provider:rp-initiated-logout"), |
| 550 | + data={ |
| 551 | + "id_token_hint": oidc_tokens.id_token, |
| 552 | + "client_id": oidc_tokens.application.client_id, |
| 553 | + "allow": True, |
| 554 | + }, |
| 555 | + ) |
| 556 | + assertRedirects(rsp, "http://testserver/", fetch_redirect_response=False) |
| 557 | + assert not is_logged_in(client) |
| 558 | + # Check that all tokens have either been deleted or expired. |
| 559 | + assert all(token.is_expired() for token in AccessToken.objects.all()) |
| 560 | + assert all(token.is_expired() for token in IDToken.objects.all()) |
| 561 | + assert all(token.revoked <= timezone.now() for token in RefreshToken.objects.all()) |
| 562 | + |
| 563 | + |
522 | 564 | @pytest.mark.django_db
|
523 | 565 | @pytest.mark.oauth2_settings(presets.OIDC_SETTINGS_RP_LOGOUT_KEEP_TOKENS)
|
524 | 566 | def test_token_deletion_on_logout_disabled(oidc_tokens, loggend_in_client, rp_settings):
|
|
0 commit comments