Skip to content

Commit da0f147

Browse files
committed
fix: token throws an error when client is provided as a string
instead of the client_id, cleaner implementation
1 parent f450855 commit da0f147

File tree

2 files changed

+52
-14
lines changed

2 files changed

+52
-14
lines changed

oauth2_provider/oauth2_validators.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -202,22 +202,32 @@ def _load_application(self, client_id, request):
202202
If request.client was not set, load application instance for given
203203
client_id and store it in request.client
204204
"""
205-
206-
# we want to be sure that request has the client attribute!
207-
assert hasattr(request, "client"), '"request" instance has no "client" attribute'
208-
209-
try:
205+
if request.client:
206+
""" check for cached client, to save the db hit if this has alredy been loaded """
210207
if not isinstance(request.client, Application):
211-
log.debug("invalid client type, Loading application for client_id %r", client_id)
212-
request.client = Application.objects.get(client_id=client_id)
213-
# Check that the application can be used (defaults to always True)
214-
if not request.client.is_usable(request):
215-
log.debug("Failed body authentication: Application %r is disabled" % (client_id))
208+
log.debug("request.client is not an Application, something else set request.client erroroneously, resetting request.client.")
209+
request.client = None
210+
elif request.client.client_id != client_id:
211+
log.debug("request.client client_id does not match the given client_id, resetting request.client.")
212+
request.client = None
213+
elif not request.client.is_usable(request):
214+
log.debug("request.client is a valid Application, but is not usable, resetting request.client.")
215+
request.client = None
216+
else:
217+
log.debug("request.client is a valid Application, reusing it.")
218+
return request.client
219+
try:
220+
""" cache wasn't hit, load from db """
221+
log.debug("cache not hit, Loading application from database for client_id %r", client_id)
222+
client = Application.objects.get(client_id=client_id)
223+
if not client.is_usable(request):
224+
log.debug("Failed to load application: Application %r is not usable" % (client_id))
216225
return None
226+
log.debug("Loaded application %r from database", client)
227+
request.client = client
217228
return request.client
218229
except Application.DoesNotExist:
219-
log.debug("Failed body authentication: Application %r does not exist" % (client_id))
220-
request.client = None
230+
log.debug("Failed to load application: Application %r does not exist" % (client_id))
221231
return None
222232

223233
def _set_oauth2_error_on_request(self, request, access_token, scopes):

tests/test_oauth2_validators.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,36 @@ def test_client_authentication_required(self):
210210
self.request.client = ""
211211
self.assertTrue(self.validator.client_authentication_required(self.request))
212212

213-
def test_load_application_fails_when_request_has_no_client(self):
214-
self.assertRaises(AssertionError, self.validator.authenticate_client_id, "client_id", {})
213+
def test_load_application_loads_client_id_when_request_has_no_client(self):
214+
self.request.client = None
215+
application = self.validator._load_application("client_id", self.request)
216+
self.assertEqual(application, self.application)
217+
218+
def test_load_application_uses_cached_when_request_has_valid_client_matching_client_id(self):
219+
self.request.client = self.application
220+
application = self.validator._load_application("client_id", self.request)
221+
self.assertIs(application, self.application)
222+
self.assertIs(self.request.client, self.application)
223+
224+
def test_load_application_succeeds_when_request_has_invalid_client_valid_client_id(self):
225+
self.request.client = 'invalid_client'
226+
application = self.validator._load_application("client_id", self.request)
227+
self.assertEqual(application, self.application)
228+
self.assertEqual(self.request.client, self.application)
229+
230+
def test_load_application_overwrites_client_on_client_id_mismatch(self):
231+
another_application = Application.objects.create(
232+
client_id="another_client_id",
233+
client_secret=CLEARTEXT_SECRET,
234+
user=self.user,
235+
client_type=Application.CLIENT_PUBLIC,
236+
authorization_grant_type=Application.GRANT_PASSWORD,
237+
)
238+
self.request.client = another_application
239+
application = self.validator._load_application("client_id", self.request)
240+
self.assertEqual(application, self.application)
241+
self.assertEqual(self.request.client, self.application)
242+
another_application.delete()
215243

216244
def test_rotate_refresh_token__is_true(self):
217245
self.assertTrue(self.validator.rotate_refresh_token(mock.MagicMock()))

0 commit comments

Comments
 (0)