feat: add user_id in the default scopes
This commit is contained in:
@@ -94,11 +94,13 @@ class EdxOAuth2Validator(OAuth2Validator):
|
||||
def get_default_scopes(self, client_id, request, *args, **kwargs):
|
||||
"""
|
||||
If the request payload does not have `scopes` attribute for a grant_type of
|
||||
client credentials, it should use available scopes as default.
|
||||
client credentials, it should add `user_id` in the default scopes.
|
||||
"""
|
||||
default_scopes = super().get_default_scopes(client_id, request, *args, **kwargs)
|
||||
if request.grant_type == 'client_credentials' and not request.scopes:
|
||||
return get_scopes_backend().get_available_scopes(application=request.client, request=request)
|
||||
return super().get_default_scopes(client_id, request, *args, **kwargs)
|
||||
if get_scopes_backend().has_user_id_in_application_scopes(application=request.client):
|
||||
default_scopes.append('user_id')
|
||||
return default_scopes
|
||||
|
||||
def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -22,3 +22,15 @@ class ApplicationModelScopes(SettingsScopes):
|
||||
default_scopes = self.get_default_scopes()
|
||||
all_scopes = list(self.get_all_scopes().keys())
|
||||
return set(application_scopes + default_scopes).intersection(all_scopes)
|
||||
|
||||
def has_user_id_in_application_scopes(self, application):
|
||||
"""
|
||||
Returns the user id associated with the given application.
|
||||
"""
|
||||
try:
|
||||
application_scopes = ApplicationAccess.get_scopes(application)
|
||||
if 'user_id' in application_scopes:
|
||||
return True
|
||||
except ApplicationAccess.DoesNotExist:
|
||||
return False
|
||||
return False
|
||||
|
||||
@@ -5,6 +5,7 @@ Test of custom django-oauth-toolkit behavior
|
||||
# pylint: disable=protected-access
|
||||
|
||||
import datetime
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import RequestFactory, TestCase
|
||||
@@ -77,6 +78,40 @@ class CustomValidationTestCase(TestCase):
|
||||
request = self.request_factory.get('/')
|
||||
assert self.validator.validate_user('darkhelmet', self.TEST_PASSWORD, client=None, request=request)
|
||||
|
||||
@mock.patch(
|
||||
'openedx.core.djangoapps.oauth_dispatch.scopes.ApplicationModelScopes.has_user_id_in_application_scopes'
|
||||
)
|
||||
@mock.patch('oauth2_provider.oauth2_validators.OAuth2Validator.get_default_scopes')
|
||||
def test_get_updated_default_scopes(self, mock_get_default_scopes, mock_has_user_id_in_application_scopes):
|
||||
"""
|
||||
Test that get_default_scopes returns the default scopes plus the user_id scope if it's available.
|
||||
"""
|
||||
default_scopes = ['profile', 'email']
|
||||
mock_get_default_scopes.return_value = default_scopes.copy()
|
||||
mock_has_user_id_in_application_scopes.return_value = True
|
||||
|
||||
request = mock.Mock(grant_type='client_credentials', client=None, scopes=None)
|
||||
overriden_default_scopes = self.validator.get_default_scopes(request=request, client_id='client_id')
|
||||
|
||||
self.assertEqual(overriden_default_scopes, default_scopes + ['user_id'])
|
||||
|
||||
@mock.patch(
|
||||
'openedx.core.djangoapps.oauth_dispatch.scopes.ApplicationModelScopes.has_user_id_in_application_scopes'
|
||||
)
|
||||
@mock.patch('oauth2_provider.oauth2_validators.OAuth2Validator.get_default_scopes')
|
||||
def test_get_default_scopes(self, mock_get_default_scopes, mock_has_user_id_in_application_scopes):
|
||||
"""
|
||||
Test that get_default_scopes returns the default scopes if user_id scope is not available.
|
||||
"""
|
||||
default_scopes = ['profile', 'email']
|
||||
mock_get_default_scopes.return_value = default_scopes.copy()
|
||||
mock_has_user_id_in_application_scopes.return_value = False
|
||||
|
||||
request = mock.Mock(grant_type='client_credentials', client=None, scopes=None)
|
||||
overriden_default_scopes = self.validator.get_default_scopes(request=request, client_id='client_id')
|
||||
|
||||
self.assertEqual(overriden_default_scopes, default_scopes)
|
||||
|
||||
|
||||
@skip_unless_lms
|
||||
class CustomAuthorizationViewTestCase(TestCase):
|
||||
|
||||
@@ -30,4 +30,13 @@ class ApplicationModelScopesTestCase(TestCase):
|
||||
application_access = ApplicationAccessFactory(scopes=application_scopes)
|
||||
scopes = ApplicationModelScopes()
|
||||
assert set(scopes.get_available_scopes(application_access.application)) == \
|
||||
set(list(settings.OAUTH2_DEFAULT_SCOPES.keys()) + expected_additional_scopes)
|
||||
set(list(settings.OAUTH2_DEFAULT_SCOPES.keys()) + expected_additional_scopes)
|
||||
|
||||
def test_has_user_id_in_application_scopes(self):
|
||||
""" Verify the settings backend correctly identifies whether the user_id scope is available. """
|
||||
application_access = ApplicationAccessFactory(scopes=['user_id'])
|
||||
scopes = ApplicationModelScopes()
|
||||
assert scopes.has_user_id_in_application_scopes(application_access.application)
|
||||
application_access.scopes = []
|
||||
application_access.save()
|
||||
assert not scopes.has_user_id_in_application_scopes(application_access.application)
|
||||
|
||||
Reference in New Issue
Block a user