server/src/metaeducation/mtdc_oauth_provider/views.py
changeset 1 5f50937893ac
child 6 39cecdd5260e
--- /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