Skip to content

Commit 55e1eab

Browse files
author
Jaap Roes
committed
Work around double parsing of ui_locales
1 parent 34912ff commit 55e1eab

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232

3333
### Fixed
3434
* #1443 Query strings with invalid hex values now raise a SuspiciousOperation exception (in DRF extension) instead of raising a 500 ValueError: Invalid hex encoding in query string.
35+
* #1468 `ui_locales` request parameter triggers `AttributeError` under certain circumstances
3536
### Security
3637

3738
## [2.4.0] - 2024-05-13

oauth2_provider/views/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ def get(self, request, *args, **kwargs):
186186
# a successful response depending on "approval_prompt" url parameter
187187
require_approval = request.GET.get("approval_prompt", oauth2_settings.REQUEST_APPROVAL_PROMPT)
188188

189+
if "ui_locales" in credentials and isinstance(credentials["ui_locales"], list):
190+
# Make sure ui_locales a space separated string for oauthlib to handle it correctly.
191+
credentials["ui_locales"] = " ".join(credentials["ui_locales"])
192+
189193
try:
190194
# If skip_authorization field is True, skip the authorization screen even
191195
# if this is the first use of the application and there was no previous authorization.

tests/test_ui_locales.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from django.contrib.auth import get_user_model
2+
from django.test import TestCase, override_settings
3+
from django.urls import reverse
4+
5+
from oauth2_provider.models import get_application_model
6+
7+
UserModel = get_user_model()
8+
Application = get_application_model()
9+
10+
11+
@override_settings(OAUTH2_PROVIDER={
12+
"OIDC_ENABLED": True,
13+
"PKCE_REQUIRED": False,
14+
"SCOPES": {
15+
"openid": "OpenID connect",
16+
},
17+
})
18+
class TestUILocalesParam(TestCase):
19+
@classmethod
20+
def setUpTestData(cls):
21+
cls.application = Application.objects.create(
22+
name="Test Application",
23+
client_id="test",
24+
redirect_uris="https://www.example.com/",
25+
client_type=Application.CLIENT_PUBLIC,
26+
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
27+
)
28+
cls.trusted_application = Application.objects.create(
29+
name="Trusted Application",
30+
client_id="trusted",
31+
redirect_uris="https://www.example.com/",
32+
client_type=Application.CLIENT_PUBLIC,
33+
authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
34+
skip_authorization=True,
35+
)
36+
cls.user = UserModel.objects.create_user("test_user")
37+
cls.url = reverse("oauth2_provider:authorize")
38+
39+
def setUp(self):
40+
self.client.force_login(self.user)
41+
42+
def test_application_ui_locales_param(self):
43+
response = self.client.get(
44+
f"{self.url}?response_type=code&client_id=test&scope=openid&ui_locales=de",
45+
)
46+
self.assertEqual(response.status_code, 200)
47+
self.assertTemplateUsed(response, "oauth2_provider/authorize.html")
48+
49+
def test_trusted_application_ui_locales_param(self):
50+
response = self.client.get(
51+
f"{self.url}?response_type=code&client_id=trusted&scope=openid&ui_locales=de",
52+
)
53+
self.assertEqual(response.status_code, 302)
54+
self.assertRegex(response.url, r"https://www\.example\.com/\?code=[a-zA-Z0-9]+")

0 commit comments

Comments
 (0)