--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/metaeducation/mtdc_oauth_provider/views.py Tue Feb 16 15:43:00 2016 +0100
@@ -0,0 +1,136 @@
+import requests
+
+from datetime import timedelta
+
+from django.core.exceptions import PermissionDenied
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect
+from django.utils import timezone
+
+from allauth.socialaccount.providers.oauth2.views import (OAuth2Adapter,
+ OAuth2View,
+ OAuth2LoginView,
+ OAuth2CallbackView)
+from allauth.socialaccount.providers.oauth2.client import (OAuth2Client,
+ OAuth2Error)
+
+from allauth.socialaccount.helpers import complete_social_login, render_authentication_error
+from allauth.socialaccount.models import SocialToken, SocialLogin
+from allauth.utils import get_request_param
+from allauth.socialaccount.providers.base import AuthAction, AuthError
+from django.conf import settings
+from urllib.parse import urlparse
+
+from .provider import MtdcProvider
+
+
+class MtdcOAuth2Adapter(OAuth2Adapter):
+ provider_id = MtdcProvider.id
+ supports_state = False
+
+ access_token_url = ""
+ authorize_url = ""
+ profile_url = ""
+
+ def __init__(self, request):
+ oauth_base_url = request.GET.get("context", None)
+ if oauth_base_url is None:
+ parsed_referer = urlparse(request.META.get("HTTP_REFERER",""))
+ oauth_base_url = '{uri.scheme}://{uri.netloc}'.format(uri=parsed_referer)
+ print(oauth_base_url)
+ self.access_token_url = oauth_base_url + settings.MTDC_ACCESS_TOKEN_URL
+ self.authorize_url = oauth_base_url + settings.MTDC_AUTHORIZE_URL
+ self.profile_url = oauth_base_url + settings.MTDC_PROFILE_URL
+ print(oauth_base_url)
+
+ #def pre_social_login(self, request, sociallogin):
+ # base_url = request.GET.get("context")
+ # print(base_url)
+ # self.oauth_base_url = base_url
+ # self.access_token_url = self.oauth_base_url + settings.ITOP_ACCESS_TOKEN_URL
+ # self.authorize_url = self.oauth_base_url + settings.ITOP_AUTHORIZE_URL
+ # self.profile_url = self.oauth_base_url + settings.ITOP_PROFILE_URL
+
+ def get_login_redirect_url(self, request):
+ print("GET_LOGIN_REDIRECT_URL?")
+ return super(MtdcOAuth2Adapter, self).get_login_redirect_url(self, request)
+
+ def complete_login(self, request, app, token, **kwargs):
+ print("COMPLETE_LOGIN")
+ resp = requests.get(self.profile_url,
+ params={'access_token': token.token})
+ extra_data = resp.json()
+ return self.get_provider().sociallogin_from_response(request,
+ extra_data)
+
+class MtdcOAuth2View(OAuth2View):
+ @classmethod
+ def adapter_view(cls, adapter):
+ def view(request, *args, **kwargs):
+ self = cls()
+ self.request = request
+ self.adapter = adapter(request)
+ return self.dispatch(request, *args, **kwargs)
+ return view
+
+
+class MtdcOAuth2LoginView(MtdcOAuth2View):
+ def dispatch(self, request):
+ provider = self.adapter.get_provider()
+ app = provider.get_app(self.request)
+ client = self.get_client(request, app)
+ action = request.GET.get('action', AuthAction.AUTHENTICATE)
+ auth_url = self.adapter.authorize_url
+ auth_params = provider.get_auth_params(request, action)
+ client.state = SocialLogin.stash_state(request)
+ try:
+ return HttpResponseRedirect(client.get_redirect_url(
+ auth_url, auth_params))
+ except OAuth2Error as e:
+ return render_authentication_error(
+ request,
+ provider.id,
+ exception=e)
+
+
+class MtdcOAuth2CallbackView(MtdcOAuth2View):
+ def dispatch(self, request):
+ if 'error' in request.GET or 'code' not in request.GET:
+ # Distinguish cancel from error
+ auth_error = request.GET.get('error', None)
+ if auth_error == self.adapter.login_cancelled_error:
+ error = AuthError.CANCELLED
+ else:
+ error = AuthError.UNKNOWN
+ return render_authentication_error(
+ request,
+ self.adapter.provider_id,
+ error=error)
+ app = self.adapter.get_provider().get_app(self.request)
+ client = self.get_client(request, app)
+ try:
+ access_token = client.get_access_token(request.GET['code'])
+ token = self.adapter.parse_token(access_token)
+ token.app = app
+ login = self.adapter.complete_login(request,
+ app,
+ token,
+ response=access_token)
+ login.token = token
+ if self.adapter.supports_state:
+ login.state = SocialLogin \
+ .verify_and_unstash_state(
+ request,
+ get_request_param(request, 'state'))
+ else:
+ login.state = SocialLogin.unstash_state(request)
+ return complete_social_login(request, login)
+ except (PermissionDenied, OAuth2Error) as e:
+ return render_authentication_error(
+ request,
+ self.adapter.provider_id,
+ exception=e)
+
+
+oauth2_login = MtdcOAuth2LoginView.adapter_view(MtdcOAuth2Adapter)
+oauth2_callback = MtdcOAuth2CallbackView.adapter_view(MtdcOAuth2Adapter)
\ No newline at end of file