openedx.core.djangoapps.auth_exchange package#

Submodules#

openedx.core.djangoapps.auth_exchange.forms module#

Forms to support third-party to first-party OAuth 2.0 access token exchange

class openedx.core.djangoapps.auth_exchange.forms.AccessTokenExchangeForm(request, oauth2_adapter, *args, **kwargs)#

Bases: Form

Form for access token exchange endpoint

OAUTH2_PROVIDER = {'DEFAULT_SCOPES': {'email': 'Know your email address', 'profile': 'Know your name and username', 'read': 'Read access', 'write': 'Write access'}, 'ERROR_RESPONSE_WITH_SCOPES': True, 'OAUTH2_VALIDATOR_CLASS': 'openedx.core.djangoapps.oauth_dispatch.dot_overrides.validators.EdxOAuth2Validator', 'REFRESH_TOKEN_EXPIRE_SECONDS': 7776000, 'REQUEST_APPROVAL_PROMPT': 'auto_even_if_expired', 'SCOPES': {'certificates:read': 'Retrieve your course certificates', 'email': 'Know your email address', 'grades:read': 'Retrieve your grades for your enrolled courses', 'profile': 'Know your name and username', 'read': 'Read access', 'tpa:read': 'Retrieve your third-party authentication username mapping', 'user_id': 'Know your user identifier', 'write': 'Write access'}, 'SCOPES_BACKEND_CLASS': 'openedx.core.djangoapps.oauth_dispatch.scopes.ApplicationModelScopes'}#
base_fields = {'access_token': <django.forms.fields.CharField object>, 'client_id': <django.forms.fields.CharField object>, 'scope': <openedx.core.djangoapps.auth_exchange.forms.ScopeChoiceField object>}#
clean()#

Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named ‘__all__’.

clean_access_token()#

Validates and returns the “access_token” field.

clean_client_id()#

Validates and returns the “client_id” field.

clean_scope()#

The scope is assembled by combining all the set flags into a single integer value which we can later check again for set bits. If no scope is set, we return the default scope which is the first defined scope in provider.constants.SCOPES.

declared_fields = {'access_token': <django.forms.fields.CharField object>, 'client_id': <django.forms.fields.CharField object>, 'scope': <openedx.core.djangoapps.auth_exchange.forms.ScopeChoiceField object>}#
property media#

Return all media required to render the widgets on this form.

scope_choices = dict_items([('read', 'Read access'), ('write', 'Write access'), ('email', 'Know your email address'), ('profile', 'Know your name and username'), ('certificates:read', 'Retrieve your course certificates'), ('grades:read', 'Retrieve your grades for your enrolled courses'), ('tpa:read', 'Retrieve your third-party authentication username mapping'), ('user_id', 'Know your user identifier')])#
exception openedx.core.djangoapps.auth_exchange.forms.OAuthValidationError#

Bases: Exception

Exception to throw inside AccessTokenExchangeForm if any OAuth2 related errors are encountered such as invalid grant type, invalid client, etc. OAuthValidationError expects a dictionary outlining the OAuth error as its first argument when instantiating. :example:

class GrantValidationForm(AccessTokenExchangeForm):
    grant_type = forms.CharField()
    def clean_grant(self):
        if not self.cleaned_data.get('grant_type') == 'code':
            raise OAuthValidationError({
                'error': 'invalid_grant',
                'error_description': "%s is not a valid grant type" % (
                    self.cleaned_data.get('grant_type'))
            })
class openedx.core.djangoapps.auth_exchange.forms.ScopeChoiceField(*, choices=(), **kwargs)#

Bases: ChoiceField

Custom form field that seperates values on space

to_python(value)#

Return a string.

validate(value)#

Validates that the input is a list or tuple.

widget#

alias of SelectMultiple

openedx.core.djangoapps.auth_exchange.views module#

Views to support exchange of authentication credentials. The following are currently implemented:

  1. AccessTokenExchangeView: 3rd party (social-auth) OAuth 2.0 access token -> 1st party (open-edx) OAuth 2.0 access token

  2. LoginWithAccessTokenView: 1st party (open-edx) OAuth 2.0 access token -> session cookie

class openedx.core.djangoapps.auth_exchange.views.AccessTokenExchangeBase(**kwargs)#

Bases: APIView

View for token exchange from 3rd party OAuth access token to 1st party OAuth access token.

Note: This base class was originally created to support multiple libraries,

but we currently only support django-oauth-toolkit (DOT).

allowed_methods = ['POST']#
authentication_classes = []#
dispatch(*args, **kwargs)#

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

exchange_access_token(request, user, scope, client)#

Exchange third party credentials for an edx access token, and return a serialized access token response.

post(request, _backend)#

Handle POST requests to get a first-party access token.

class openedx.core.djangoapps.auth_exchange.views.DOTAccessTokenExchangeView(**kwargs)#

Bases: AccessTokenExchangeBase, TokenView

View for token exchange from 3rd party OAuth access token to 1st party OAuth access token. Uses django-oauth-toolkit (DOT) to manage access tokens.

access_token_response(token)#

Wrap an access token in an appropriate response

create_access_token(request, user, scopes, client)#

Create and return a new access token.

error_response(form_errors, **kwargs)#

Return an error response consisting of the errors in the form

oauth2_adapter = <openedx.core.djangoapps.oauth_dispatch.adapters.dot.DOTAdapter object>#
class openedx.core.djangoapps.auth_exchange.views.LoginWithAccessTokenView(**kwargs)#

Bases: APIView

View for exchanging an access token for session cookies

authentication_classes = (<class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>)#
permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
post(request)#

Handler for the POST method to this view.

Module contents#