Skip to content

Commit 32dc9af

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

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
@@ -214,22 +214,32 @@ def _load_application(self, client_id, request):
214214
If request.client was not set, load application instance for given
215215
client_id and store it in request.client
216216
"""
217-
218-
# we want to be sure that request has the client attribute!
219-
assert hasattr(request, "client"), '"request" instance has no "client" attribute'
220-
221-
try:
217+
if request.client:
218+
""" check for cached client, to save the db hit if this has alredy been loaded """
222219
if not isinstance(request.client, Application):
223-
log.debug("invalid client type, Loading application for client_id %r", client_id)
224-
request.client = Application.objects.get(client_id=client_id)
225-
# Check that the application can be used (defaults to always True)
226-
if not request.client.is_usable(request):
227-
log.debug("Failed body authentication: Application %r is disabled" % (client_id))
220+
log.debug("request.client is not an Application, something else set request.client erroroneously, resetting request.client.")
221+
request.client = None
222+
elif request.client.client_id != client_id:
223+
log.debug("request.client client_id does not match the given client_id, resetting request.client.")
224+
request.client = None
225+
elif not request.client.is_usable(request):
226+
log.debug("request.client is a valid Application, but is not usable, resetting request.client.")
227+
request.client = None
228+
else:
229+
log.debug("request.client is a valid Application, reusing it.")
230+
return request.client
231+
try:
232+
""" cache wasn't hit, load from db """
233+
log.debug("cache not hit, Loading application from database for client_id %r", client_id)
234+
client = Application.objects.get(client_id=client_id)
235+
if not client.is_usable(request):
236+
log.debug("Failed to load application: Application %r is not usable" % (client_id))
228237
return None
238+
log.debug("Loaded application %r from database", client)
239+
request.client = client
229240
return request.client
230241
except Application.DoesNotExist:
231-
log.debug("Failed body authentication: Application %r does not exist" % (client_id))
232-
request.client = None
242+
log.debug("Failed to load application: Application %r does not exist" % (client_id))
233243
return None
234244

235245
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
@@ -216,8 +216,36 @@ def test_client_authentication_required(self):
216216
self.request.client = ""
217217
self.assertTrue(self.validator.client_authentication_required(self.request))
218218

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

222250
def test_rotate_refresh_token__is_true(self):
223251
self.assertTrue(self.validator.rotate_refresh_token(mock.MagicMock()))

0 commit comments

Comments
 (0)