-
Notifications
You must be signed in to change notification settings - Fork 29
BB2-4781: Revoke prior tokens on new auth flow #1605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
6e8d9f3
599e102
de1fa4d
b0ea5ae
4f2cffa
f570eed
8508c52
4335eb3
e89f80d
5a993e1
605a6ce
f86556e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,14 @@ | |
| from django.db import transaction | ||
| from django.http import HttpRequest | ||
| from django.http.response import JsonResponse | ||
| from oauth2_provider.models import AccessToken, RefreshToken, get_application_model | ||
| from django.utils import timezone | ||
| from oauth2_provider.models import ( | ||
| AccessToken, | ||
| RefreshToken, | ||
| get_access_token_model, | ||
| get_application_model, | ||
| get_refresh_token_model, | ||
| ) | ||
| from oauthlib.oauth2.rfc6749.errors import ( | ||
| InvalidClientError, | ||
| InvalidGrantError, | ||
|
|
@@ -326,3 +333,42 @@ def validate_latin_extended_string(text: str) -> bool: | |
| bool: if all strings are encoded less than U+017F (383) and it is not empty | ||
| """ | ||
| return all(ord(char) <= 383 for char in text) and bool(text) | ||
|
|
||
|
|
||
| def revoke_prior_tokens_for_user_and_app_if_they_exist(user_id: int, app_id: int) -> None: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A more general comment, our method of doing this elsewhere is by using
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like |
||
| """Revoke prior tokens for a user/app id pair to ensure that if a user has reauthorized | ||
| that prior tokens can't be used, in case any of those prior tokens have more scopes than | ||
| the newly created one | ||
|
|
||
| Args: | ||
| user_id (int): ID for the user who just re-authorized an app they have authorized previously | ||
| app_id (int): ID for the application the user just re-authorized for | ||
| """ | ||
| AccessToken = get_access_token_model() | ||
| RefreshToken = get_refresh_token_model() | ||
| prior_access_tokens = list(AccessToken.objects.filter(user=user_id, application=app_id).order_by('-created')) | ||
|
|
||
| # If there is only one access token for a user_id/app_id, we don't need to revoke any prior tokens | ||
| if len(prior_access_tokens) <= 1: | ||
| return | ||
|
|
||
| prior_access_tokens.pop(0) | ||
|
|
||
| for access_token in prior_access_tokens: | ||
| try: | ||
| refresh_token = get_refresh_token_model().objects.get(access_token=access_token.id) | ||
|
JamesDemeryNava marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Only update the access token expires value if it is in the future | ||
|
ryan-morosa marked this conversation as resolved.
Outdated
|
||
| if access_token.expires > timezone.now(): | ||
| access_token.expires = timezone.now() | ||
| access_token.save() | ||
|
|
||
| if refresh_token.revoked is None: | ||
| refresh_token.revoked = timezone.now() | ||
| refresh_token.access_token_id = None | ||
| refresh_token.save() | ||
|
|
||
| except RefreshToken.DoesNotExist: | ||
| # indicates it is a access token created via CAN flow, as it does not have an associated refresh token | ||
| access_token.expires = timezone.now() | ||
| access_token.save() | ||
|
Comment on lines
+367
to
+368
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to match the above and still only do this if expires > now? Might be able to set the access_token.expires before trying to get the refresh token to avoid having to set it in two spots as well.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense to me! |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought there would need to be changes to this file, but in the ended it wound up just being using the HTTPStatus library rather than plain integer status codes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ya I feel like using the HTTPStatus library should be a standard going forward