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)
def persona_login(request): assertion = request.POST.get('assertion', '') settings = app_settings.PROVIDERS.get(PersonaProvider.id, {}) audience = settings.get('AUDIENCE', None) if audience is None: raise ImproperlyConfigured("No Persona audience configured. Please " "add an AUDIENCE item to the " "SOCIALACCOUNT_PROVIDERS['persona'] setting.") resp = requests.post('https://verifier.login.persona.org/verify', {'assertion': assertion, 'audience': audience}) try: resp.raise_for_status() extra_data = resp.json() if extra_data['status'] != 'okay': return render_authentication_error( request, provider_id=PersonaProvider.id, extra_context={'response': extra_data}) except (ValueError, requests.RequestException) as e: return render_authentication_error( request, provider_id=PersonaProvider.id, exception=e) login = providers.registry \ .by_id(PersonaProvider.id) \ .sociallogin_from_response(request, extra_data) login.state = SocialLogin.state_from_request(request) return complete_social_login(request, login)
def dispatch(self, request): """ View to handle final steps of OAuth based authentication where the user gets redirected back to from the service provider """ login_done_url = reverse(self.adapter.provider_id + "_callback") client = self._get_client(request, login_done_url) if not client.is_valid(): if 'denied' in request.GET: error = AuthError.CANCELLED else: error = AuthError.UNKNOWN extra_context = dict(oauth_client=client) return render_authentication_error( request, self.adapter.provider_id, error=error, extra_context=extra_context) app = self.adapter.get_provider().get_app(request) try: access_token = client.get_access_token() token = SocialToken( app=app, token=access_token['oauth_token'], # .get() -- e.g. Evernote does not feature a secret token_secret=access_token.get('oauth_token_secret', '')) login = self.adapter.complete_login(request, app, token, response=access_token) login.token = token login.state = SocialLogin.unstash_state(request) return complete_social_login(request, login) except OAuthError as e: return render_authentication_error( request, self.adapter.provider_id, exception=e)
def dispatch(self, request): callback_url = reverse(self.adapter.provider_id + "_callback") SocialLogin.stash_state(request) action = request.GET.get('action', AuthAction.AUTHENTICATE) provider = self.adapter.get_provider() auth_url = provider.get_auth_url(request, action) or self.adapter.authorize_url client = self._get_client(request, callback_url) try: return client.get_redirect(auth_url) except OAuthError as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
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)
def callback(request): client = _openid_consumer(request) response = client.complete( dict(list(request.GET.items()) + list(request.POST.items())), request.build_absolute_uri(request.path)) if response.status == consumer.SUCCESS: login = providers.registry \ .by_id(OpenIDProvider.id) \ .sociallogin_from_response(request, response) login.state = SocialLogin.unstash_state(request) ret = complete_social_login(request, login) else: if response.status == consumer.CANCEL: error = AuthError.CANCELLED else: error = AuthError.UNKNOWN ret = render_authentication_error(request, OpenIDProvider.id, error=error) return ret
def login(request): if 'openid' in request.GET or request.method == 'POST': form = LoginForm( dict(list(request.GET.items()) + list(request.POST.items()))) if form.is_valid(): client = _openid_consumer(request) try: auth_request = client.begin(form.cleaned_data['openid']) if QUERY_EMAIL: sreg = SRegRequest() for name in SRegFields: sreg.requestField(field_name=name, required=True) auth_request.addExtension(sreg) ax = FetchRequest() for name in AXAttributes: ax.add(AttrInfo(name, required=True)) auth_request.addExtension(ax) callback_url = reverse(callback) SocialLogin.stash_state(request) redirect_url = auth_request.redirectURL( request.build_absolute_uri('/'), request.build_absolute_uri(callback_url)) return HttpResponseRedirect(redirect_url) # UnicodeDecodeError: # see https://github.com/necaris/python3-openid/issues/1 except (UnicodeDecodeError, DiscoveryFailure) as e: if request.method == 'POST': form._errors["openid"] = form.error_class([e]) else: return render_authentication_error(request, OpenIDProvider.id, exception=e) else: form = LoginForm(initial={ 'next': request.GET.get('next'), 'process': request.GET.get('process') }) d = dict(form=form) return render_to_response('openid/login.html', d, context_instance=RequestContext(request))
def login_by_token(request): ret = None auth_exception = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: provider = providers.registry.by_id(FacebookProvider.id) login_options = provider.get_fb_login_options(request) app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) access_token = form.cleaned_data['access_token'] if login_options.get('auth_type') == 'reauthenticate': info = requests.get(GRAPH_API_URL + '/oauth/access_token_info', params={ 'client_id': app.client_id, 'access_token': access_token }).json() nonce = provider.get_nonce(request, pop=True) ok = nonce and nonce == info.get('auth_nonce') else: ok = True if ok: token = SocialToken(app=app, token=access_token) login = fb_complete_login(request, app, token) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except requests.RequestException as e: logger.exception('Error accessing FB user profile') auth_exception = e if not ret: ret = render_authentication_error(request, FacebookProvider.id, exception=auth_exception) return ret