Skip to content

Commit

Permalink
Merge pull request #636 from frankie567/master
Browse files Browse the repository at this point in the history
RFC7592: set default values for `grant_types` and `response_types` when updating client
  • Loading branch information
lepture committed Apr 8, 2024
2 parents dc3d77d + 1856a02 commit f18c816
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 4 deletions.
10 changes: 8 additions & 2 deletions authlib/oauth2/rfc7592/endpoint.py
Expand Up @@ -136,15 +136,21 @@ def _validate_scope(claims, value):
response_types_supported = set(response_types_supported)

def _validate_response_types(claims, value):
return response_types_supported.issuperset(set(value))
# If omitted, the default is that the client will use only the "code"
# response type.
response_types = set(value) if value else {"code"}
return response_types_supported.issuperset(response_types)

options['response_types'] = {'validate': _validate_response_types}

if grant_types_supported is not None:
grant_types_supported = set(grant_types_supported)

def _validate_grant_types(claims, value):
return grant_types_supported.issuperset(set(value))
# If omitted, the default behavior is that the client will use only
# the "authorization_code" Grant Type.
grant_types = set(value) if value else {"authorization_code"}
return grant_types_supported.issuperset(grant_types)

options['grant_types'] = {'validate': _validate_grant_types}

Expand Down
24 changes: 22 additions & 2 deletions tests/flask/test_oauth2/test_client_configuration_endpoint.py
Expand Up @@ -21,7 +21,7 @@ def authenticate_token(self, request):
return Token.query.filter_by(access_token=access_token).first()

def update_client(self, client, client_metadata, request):
client.set_client_metadata({**client.client_metadata, **client_metadata})
client.set_client_metadata(client_metadata)
db.session.add(client)
db.session.commit()
return client
Expand Down Expand Up @@ -195,7 +195,7 @@ def test_update_client(self):
self.assertEqual(resp['client_id'], client.client_id)
self.assertEqual(resp['client_name'], 'NewAuthlib')
self.assertEqual(client.client_name, 'NewAuthlib')
self.assertEqual(client.scope, 'openid profile')
self.assertEqual(client.scope, '')

def test_access_denied(self):
user, client, token = self.prepare_data()
Expand Down Expand Up @@ -382,6 +382,16 @@ def test_response_types_supported(self):
self.assertEqual(resp['client_name'], 'Authlib')
self.assertEqual(resp['response_types'], ['code'])

# https://datatracker.ietf.org/doc/html/rfc7592#section-2.2
# If omitted, the default is that the client will use only the "code"
# response type.
body = {'client_id': 'client_id', 'client_name': 'Authlib'}
rv = self.client.put('/configure_client/client_id', json=body, headers=headers)
resp = json.loads(rv.data)
self.assertIn('client_id', resp)
self.assertEqual(resp['client_name'], 'Authlib')
self.assertNotIn('response_types', resp)

body = {
'client_id': 'client_id',
'response_types': ['code', 'token'],
Expand All @@ -407,6 +417,16 @@ def test_grant_types_supported(self):
self.assertEqual(resp['client_name'], 'Authlib')
self.assertEqual(resp['grant_types'], ['password'])

# https://datatracker.ietf.org/doc/html/rfc7592#section-2.2
# If omitted, the default behavior is that the client will use only
# the "authorization_code" Grant Type.
body = {'client_id': 'client_id', 'client_name': 'Authlib'}
rv = self.client.put('/configure_client/client_id', json=body, headers=headers)
resp = json.loads(rv.data)
self.assertIn('client_id', resp)
self.assertEqual(resp['client_name'], 'Authlib')
self.assertNotIn('grant_types', resp)

body = {
'client_id': 'client_id',
'grant_types': ['client_credentials'],
Expand Down

0 comments on commit f18c816

Please sign in to comment.