|
3 | 3 | from django.utils.encoding import smart_unicode |
4 | 4 | from django.utils.translation import ugettext as _ |
5 | 5 |
|
6 | | -from provider import constants, scope |
| 6 | +from provider import scope |
7 | 7 | from provider.constants import RESPONSE_TYPE_CHOICES, SCOPES |
8 | 8 | from provider.forms import OAuthForm, OAuthValidationError |
9 | 9 | from provider.oauth2.models import Client, Grant, RefreshToken |
@@ -38,7 +38,7 @@ def clean(self): |
38 | 38 | data = self.cleaned_data |
39 | 39 | try: |
40 | 40 | client = Client.objects.get(client_id=data.get('client_id'), |
41 | | - client_secret=data.get('client_secret')) |
| 41 | + client_secret=data.get('client_secret')) |
42 | 42 | except Client.DoesNotExist: |
43 | 43 | raise forms.ValidationError(_("Client could not be validated with " |
44 | 44 | "key pair.")) |
@@ -146,7 +146,7 @@ def clean_response_type(self): |
146 | 146 |
|
147 | 147 | if not response_type: |
148 | 148 | raise OAuthValidationError({'error': 'invalid_request', |
149 | | - 'error_description': "No 'response_type' supplied."}) |
| 149 | + 'error_description': "No 'response_type' supplied."}) |
150 | 150 |
|
151 | 151 | types = response_type.split(" ") |
152 | 152 |
|
@@ -209,7 +209,7 @@ def clean_refresh_token(self): |
209 | 209 |
|
210 | 210 | try: |
211 | 211 | token = RefreshToken.objects.get(token=token, |
212 | | - expired=False, client=self.client) |
| 212 | + expired=False, client=self.client) |
213 | 213 | except RefreshToken.DoesNotExist: |
214 | 214 | raise OAuthValidationError({'error': 'invalid_grant'}) |
215 | 215 |
|
@@ -302,7 +302,7 @@ def clean(self): |
302 | 302 | data = self.cleaned_data |
303 | 303 |
|
304 | 304 | user = authenticate(username=data.get('username'), |
305 | | - password=data.get('password')) |
| 305 | + password=data.get('password')) |
306 | 306 |
|
307 | 307 | if user is None: |
308 | 308 | raise OAuthValidationError({'error': 'invalid_grant'}) |
@@ -340,10 +340,18 @@ def clean(self): |
340 | 340 |
|
341 | 341 | class ClientCredentialsGrantForm(ScopeMixin, OAuthForm): |
342 | 342 | """ Validate a client credentials grant request. """ |
| 343 | + scope = forms.CharField(required=False) |
343 | 344 |
|
344 | | - def clean(self): |
345 | | - cleaned_data = super(ClientCredentialsGrantForm, self).clean() |
346 | | - # We do not fully support scopes for this grant type; however, a scope is required |
347 | | - # in order to create an access token. Default to read-only access. |
348 | | - cleaned_data['scope'] = constants.READ |
349 | | - return cleaned_data |
| 345 | + def clean_scope(self): |
| 346 | + if not self.cleaned_data.get('scope'): |
| 347 | + # NOTE (CCB): This is a horrible hack, like much of our OAuth work. The scopes are declared in |
| 348 | + # edx-oauth2-provider. (See edx_oauth2_provider/constants.py.) However, we need to provide a default scope |
| 349 | + # that (a) gives the token basic read access and (b) allows access to the user info endpoint. This value |
| 350 | + # represents the following scopes: openid (1), profile (2), email (4), permissions (32). At present, this is |
| 351 | + # all scopes except course_staff and course_instructor. These scopes are normally associated with actual |
| 352 | + # users, whereas the client credentials grant will primarily be used by service users. |
| 353 | + # |
| 354 | + # In the future, we should limit the allowable scopes either at a global or per-client level. |
| 355 | + return 39 |
| 356 | + |
| 357 | + return super(ClientCredentialsGrantForm, self).clean_scope() |
0 commit comments