Skip to content

Commit 402b26e

Browse files
authored
Merge branch 'master' into django_5.0
2 parents a13d2e0 + f580e2e commit 402b26e

File tree

7 files changed

+45
-8
lines changed

7 files changed

+45
-8
lines changed

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14-
- uses: actions/checkout@v2
14+
- uses: actions/checkout@v4
1515
with:
1616
fetch-depth: 0
1717

1818
- name: Set up Python
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v4
2020
with:
21-
python-version: 3.8
21+
python-version: '3.12'
2222

2323
- name: Install dependencies
2424
run: |

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
django-version: '4.2'
4747

4848
steps:
49-
- uses: actions/checkout@v3
49+
- uses: actions/checkout@v4
5050

5151
- name: Set up Python ${{ matrix.python-version }}
5252
uses: actions/setup-python@v4

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/psf/black
3-
rev: 23.9.1
3+
rev: 23.10.1
44
hooks:
55
- id: black
66
exclude: ^(oauth2_provider/migrations/|tests/migrations/)
@@ -26,6 +26,6 @@ repos:
2626
- id: flake8
2727
exclude: ^(oauth2_provider/migrations/|tests/migrations/)
2828
- repo: https://github.com/sphinx-contrib/sphinx-lint
29-
rev: v0.6.8
29+
rev: v0.8.1
3030
hooks:
3131
- id: sphinx-lint

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Antoine Laurent
2626
Anvesh Agarwal
2727
Aristóbulo Meneses
2828
Aryan Iyappan
29+
Asaf Klibansky
2930
Ash Christopher
3031
Asif Saif Uddin
3132
Bart Merenda

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
* #1273 Add caching of loading of OIDC private key.
2525
* #1285 Add post_logout_redirect_uris field in application views.
2626
* #1311 Add option to disable client_secret hashing to allow verifying JWTs' signatures.
27+
* #1337 Gracefully handle expired or deleted refresh tokens, in `validate_user`.
2728
* #1350 Support Python 3.12 and Django 5.0
2829

2930
### Fixed

oauth2_provider/oauth2_validators.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,8 +725,10 @@ def get_original_scopes(self, refresh_token, request, *args, **kwargs):
725725
# validate_refresh_token.
726726
rt = request.refresh_token_instance
727727
if not rt.access_token_id:
728-
return AccessToken.objects.get(source_refresh_token_id=rt.id).scope
729-
728+
try:
729+
return AccessToken.objects.get(source_refresh_token_id=rt.id).scope
730+
except AccessToken.DoesNotExist:
731+
return []
730732
return rt.access_token.scope
731733

732734
def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs):

tests/test_authorization_code.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,39 @@ def test_refresh_repeating_requests_non_rotating_tokens(self):
10021002
response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
10031003
self.assertEqual(response.status_code, 200)
10041004

1005+
def test_refresh_with_deleted_token(self):
1006+
"""
1007+
Ensure that using a deleted refresh token returns 400
1008+
"""
1009+
self.client.login(username="test_user", password="123456")
1010+
authorization_code = self.get_auth()
1011+
1012+
token_request_data = {
1013+
"grant_type": "authorization_code",
1014+
"scope": "read write",
1015+
"code": authorization_code,
1016+
"redirect_uri": "http://example.org",
1017+
}
1018+
auth_headers = get_basic_auth_header(self.application.client_id, CLEARTEXT_SECRET)
1019+
1020+
# get a refresh token
1021+
response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
1022+
1023+
content = json.loads(response.content.decode("utf-8"))
1024+
rt = content["refresh_token"]
1025+
1026+
token_request_data = {
1027+
"grant_type": "refresh_token",
1028+
"refresh_token": rt,
1029+
"scope": "read write",
1030+
}
1031+
1032+
# delete the access token
1033+
AccessToken.objects.filter(token=content["access_token"]).delete()
1034+
1035+
response = self.client.post(reverse("oauth2_provider:token"), data=token_request_data, **auth_headers)
1036+
self.assertEqual(response.status_code, 400)
1037+
10051038
def test_basic_auth_bad_authcode(self):
10061039
"""
10071040
Request an access token using a bad authorization code

0 commit comments

Comments
 (0)