Configure LMS to select oauth2 providing library.
Available backends: * django-oauth-toolkit (DOT) * django-oauth2-provider (DOP) * Use provided client ID to select backend for * AccessToken requests * third party auth-token exchange * Create adapters to isolate library-dependent functionality * Handle django-oauth-toolkit tokens in edX DRF authenticator class MA-1998 MA-2000
This commit is contained in:
89
lms/djangoapps/oauth_dispatch/views.py
Normal file
89
lms/djangoapps/oauth_dispatch/views.py
Normal file
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
Views that dispatch processing of OAuth requests to django-oauth2-provider or
|
||||
django-oauth-toolkit as appropriate.
|
||||
"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.views.generic import View
|
||||
from edx_oauth2_provider import views as dop_views # django-oauth2-provider views
|
||||
from oauth2_provider import models as dot_models, views as dot_views # django-oauth-toolkit
|
||||
|
||||
from auth_exchange import views as auth_exchange_views
|
||||
|
||||
from . import adapters
|
||||
|
||||
|
||||
class _DispatchingView(View):
|
||||
"""
|
||||
Base class that route views to the appropriate provider view. The default
|
||||
behavior routes based on client_id, but this can be overridden by redefining
|
||||
`select_backend()` if particular views need different behavior.
|
||||
"""
|
||||
# pylint: disable=no-member
|
||||
|
||||
dot_adapter = adapters.DOTAdapter()
|
||||
dop_adapter = adapters.DOPAdapter()
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
"""
|
||||
Dispatch the request to the selected backend's view.
|
||||
"""
|
||||
backend = self.select_backend(request)
|
||||
view = self.get_view_for_backend(backend)
|
||||
return view(request, *args, **kwargs)
|
||||
|
||||
def select_backend(self, request):
|
||||
"""
|
||||
Given a request that specifies an oauth `client_id`, return the adapter
|
||||
for the appropriate OAuth handling library. If the client_id is found
|
||||
in a django-oauth-toolkit (DOT) Application, use the DOT adapter,
|
||||
otherwise use the django-oauth2-provider (DOP) adapter, and allow the
|
||||
calls to fail normally if the client does not exist.
|
||||
"""
|
||||
|
||||
if dot_models.Application.objects.filter(client_id=self._get_client_id(request)).exists():
|
||||
return self.dot_adapter.backend
|
||||
else:
|
||||
return self.dop_adapter.backend
|
||||
|
||||
def get_view_for_backend(self, backend):
|
||||
"""
|
||||
Return the appropriate view from the requested backend.
|
||||
"""
|
||||
if backend == self.dot_adapter.backend:
|
||||
return self.dot_view.as_view()
|
||||
elif backend == self.dop_adapter.backend:
|
||||
return self.dop_view.as_view()
|
||||
else:
|
||||
raise KeyError('Failed to dispatch view. Invalid backend {}'.format(backend))
|
||||
|
||||
def _get_client_id(self, request):
|
||||
"""
|
||||
Return the client_id from the provided request
|
||||
"""
|
||||
return request.POST.get('client_id')
|
||||
|
||||
|
||||
class AccessTokenView(_DispatchingView):
|
||||
"""
|
||||
Handle access token requests.
|
||||
"""
|
||||
dot_view = dot_views.TokenView
|
||||
dop_view = dop_views.AccessTokenView
|
||||
|
||||
|
||||
class AuthorizationView(_DispatchingView):
|
||||
"""
|
||||
Part of the authorization flow.
|
||||
"""
|
||||
dop_view = dop_views.Capture
|
||||
dot_view = dot_views.AuthorizationView
|
||||
|
||||
|
||||
class AccessTokenExchangeView(_DispatchingView):
|
||||
"""
|
||||
Exchange a third party auth token.
|
||||
"""
|
||||
dop_view = auth_exchange_views.DOPAccessTokenExchangeView
|
||||
dot_view = auth_exchange_views.DOTAccessTokenExchangeView
|
||||
Reference in New Issue
Block a user