def validate_access_token(self, attrs, source): access_token = attrs[source] view = self.context.get('view') request = self.context.get('request') if not view: raise serializers.ValidationError('View is not defined, pass it ' + 'as a context variable') self.adapter_class = getattr(view, 'adapter_class', None) if not self.adapter_class: raise serializers.ValidationError('Define adapter_class in view') self.adapter = self.adapter_class() app = self.adapter.get_provider().get_app(request) token = self.adapter.parse_token({'access_token': access_token}) token.app = app try: login = self.adapter.complete_login(request, app, token, response=access_token) token.account = login.account login.token = token complete_social_login(request, login) except HTTPError: raise serializers.ValidationError('Incorrect value') if not login.is_existing: login.lookup() login.save(request, connect=True) self.object = {'user': login.account.user} return attrs
def _create_request(self, provider, process, user, url, method, data=None): factory = RequestFactory() request = factory.get('/accounts/login/callback/') factory = RequestFactory() if method == 'GET': request = factory.get(url) else: request = factory.post(url, data) request.user = AnonymousUser() SessionMiddleware().process_request(request) MessageMiddleware().process_request(request) user = LocalUser(username='******', email='*****@*****.**') account = SocialAccount(user=user, provider=provider, uid='123') sociallogin = SocialLogin(user=user, account=account) if process is not None: sociallogin.state['process'] = process complete_social_login(request, sociallogin) return request
def post (self,request): original_request = request._request data = JSONParser().parse(request) access_token = data.get('access_token', '') try: app = SocialApp.objects.get(provider='facebook') fb_auth_token = SocialToken(app=app, token=access_token) login = fb_complete_login(original_request, app, fb_auth_token) login.token = fb_auth_token login.state = SocialLogin.state_from_request(original_request) complete_social_login(original_request, login) token, _ = Token.objects.get_or_create(user=original_request.user) data_response ={ 'username': original_request.user.username, 'objectId': original_request.user.pk, 'firstName': original_request.user.first_name, 'lastName': original_request.user.last_name, 'email': original_request.user.email, 'sessionToken': token.key, } return Response(status=status.HTTP_200_OK, data=data_response) except: return Response(status=status.HTTP_401_UNAUTHORIZED,data={ 'detail': 'Bad Access Token', })
def validate(self, attrs): access_token = attrs.get('access_token') view = self.context.get('view') request = self.context.get('request') if not isinstance(request, HttpRequest): request = request._request if not view: raise serializers.ValidationError( 'View is not defined, pass it as a context variable' ) self.adapter_class = getattr(view, 'adapter_class', None) if not self.adapter_class: raise serializers.ValidationError('Define adapter_class in view') self.adapter = self.adapter_class() app = self.adapter.get_provider().get_app(request) token = self.adapter.parse_token({'access_token': access_token}) token.app = app try: login = self.adapter.complete_login(request, app, token, response=access_token) login.token = token complete_social_login(request, login) except HTTPError: raise serializers.ValidationError('Incorrect value') except NoReverseMatch: """ Here we catch because all_auth wants to send us to a signup form to enter a new email address """ pass if not login.is_existing: login.lookup() try: login.save(request, connect=True) except IntegrityError: """ here we catch the IntegrityError because there is already an user with the same email address. Therefore we save login.account on our own and relate it to the already registered user """ user = get_user_model().objects.get( email=login.account.extra_data['email'] ) login.account.user = user login.account.save() attrs['user'] = login.account.user return attrs
def login(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): token = form.cleaned_data['access_token'] g = GraphAPI(token) facebook_me = g.get_object("me") email = valid_email_or_none(facebook_me.get('email')) social_id = facebook_me['id'] try: account = FacebookAccount.objects.get(social_id=social_id) except FacebookAccount.DoesNotExist: account = FacebookAccount(social_id=social_id) account.link = facebook_me['link'] account.name = facebook_me['name'] if account.pk: account.save() data = dict(email=email, facebook_me=facebook_me) # some facebook accounts don't have this data data.update((k,v) for (k,v) in facebook_me.items() if k in ['username', 'first_name', 'last_name']) ret = complete_social_login(request, data, account) if not ret: ret = render_authentication_error(request) return ret
def post(self, request): data = JSONParser().parse(request) access_token = data.get('access_token', '') try: app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) # return SocialLogin(account) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) # add or update the user ret = complete_social_login(request, login) # if we get here we've succeeded return Response(status=200, data={ 'success': True, 'username': request.user.username, 'user_id': request.user.pk, 'csrf_token': unicode(csrf(request)['csrf_token']) }) except: # FIXME: Catch only what is needed #, HttpForbidden return Response(status=401 ,data={ 'success': False, 'reason': "Bad Access Token", })
def persona_login(request): assertion = request.POST.get('assertion', '') audience = request.build_absolute_uri('/') resp = requests.post('https://verifier.login.persona.org/verify', {'assertion': assertion, 'audience': audience}) if resp.json()['status'] != 'okay': return render_authentication_error(request) email = resp.json()['email'] user = get_adapter() \ .populate_new_user(email=email) extra_data = resp.json() account = SocialAccount(uid=email, provider=PersonaProvider.id, extra_data=extra_data, user=user) # TBD: Persona e-mail addresses are verified, so we could check if # a matching local user account already exists with an identical # verified e-mail address and short-circuit the social login. Then # again, this holds for all social providers that guarantee # verified e-mail addresses, so if at all, short-circuiting should # probably not be handled here... login = SocialLogin(account) 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: return HttpResponseRedirect(reverse('socialaccount_login_cancelled')) extra_context = dict(oauth_client=client) return render_authentication_error(request, 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'], token_secret=access_token['oauth_token_secret']) login = self.adapter.complete_login(request, app, token) token.account = login.account login.token = token login.state = SocialLogin.unmarshall_state \ (request.session.pop('oauth_login_state', None)) return complete_social_login(request, login) except OAuthError: return render_authentication_error(request)
def login(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): token = form.cleaned_data['access_token'] g = GraphAPI(token) data = g.get_object("me") email = valid_email_or_none(data.get('email')) social_id = data['id'] try: account = FacebookAccount.objects.get(social_id=social_id) except FacebookAccount.DoesNotExist: account = FacebookAccount(social_id=social_id) account.link = data['link'] account.name = data['name'] #adding the storing of users accesstoken account.access_token = token if account.pk: account.save() data = dict(email=email,facebook_me=data) ret = complete_social_login(request, data, account) if not ret: ret = render_authentication_error(request) return ret
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): if 'error' in request.GET or not 'code' in request.GET: # TODO: Distinguish cancel from error return render_authentication_error(request) app = self.adapter.get_provider().get_app(self.request) client = self.get_client(request, app) try: r = praw.Reddit('OAuth Sketchdaily Schedule by u/davidwinters ver 0.1.') r.set_oauth_app_info(client.consumer_key, client.consumer_secret, 'http://themes.sketchdaily.net/accounts/redditprovider/login/callback/') access_token = r.get_access_information(request.GET['code']) user = r.get_me() extra = r.get_my_moderation() # access_token = client.get_access_token(request.GET['code']) token = SocialToken(token=access_token) #token = self.adapter.parse_token(access_token) token.app = app login = self.adapter.complete_login(request, app, token, response=access_token, user=user, extra=extra) token.account = login.account login.token = token login.state = SocialLogin.unmarshall_state(request.REQUEST .get('uniqueKey')) return complete_social_login(request, login) except OAuth2Error: return render_authentication_error(request)
def validate(self, attrs): access_token = attrs.get('access_token') view = self.context.get('view') request = self.context.get('request') if not isinstance(request, HttpRequest): request = request._request if not view: raise serializers.ValidationError( 'View is not defined, pass it as a context variable' ) self.adapter_class = getattr(view, 'adapter_class', None) if not self.adapter_class: raise serializers.ValidationError('Define adapter_class in view') self.adapter = self.adapter_class() app = self.adapter.get_provider().get_app(request) token = self.adapter.parse_token({'access_token': access_token}) token.app = app try: login = self.adapter.complete_login(request, app, token, response=access_token) login.token = token """ If the adapter is customised, we can get immediate responses specified here. """ response = complete_social_login(request, login) if response.__class__ in (HttpResponseBadRequest,): raise serializers.ValidationError(response.content) except HTTPError,e: raise serializers.ValidationError(e.response.content)
def login_by_token(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): # try: print 'trying' app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) access_token = form.cleaned_data['access_token'] token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) print access_token, token, login.token ret = complete_social_login(request, login) print ret # except: # print 'error' # FIXME: Catch only what is needed # pass if not ret: ret = render_authentication_error(request) return ret
def api_twitter_connect_by_token(request): ret = None if request.method == 'POST': try: adapter = TwitterOAuthAdapter() app = adapter.get_provider().get_app(request) access_token = request.POST.get('access_token') access_token_secret = request.POST.get('access_token_secret') token = SocialToken(app=app, token=access_token) login = twitter_complete_login(request, app, access_token, access_token_secret) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except Exception as e: # FIXME: Catch only what is needed pass if not ret: raise Http404 profile = Profile.objects.get_or_create(user=request.user)[0] profile.avatar_url = login.account.get_avatar_url() profile.save() user_source = UserResource() bundle = user_source.build_bundle(obj=request.user, request=request) bundle = user_source.full_dehydrate(bundle) bundle = user_source.alter_detail_data_to_serialize(request, bundle) return user_source.create_response(request, bundle)
def callback(request): if 'dr_auth_status' not in request.GET: return render_authentication_error( request, DraugiemProvider.id, error=AuthError.UNKNOWN) if request.GET['dr_auth_status'] != 'ok': return render_authentication_error( request, DraugiemProvider.id, error=AuthError.DENIED) if 'dr_auth_code' not in request.GET: return render_authentication_error( request, DraugiemProvider.id, error=AuthError.UNKNOWN) ret = None auth_exception = None try: app = providers.registry.by_id( DraugiemProvider.id, request).get_app(request) login = draugiem_complete_login( request, app, request.GET['dr_auth_code']) login.state = SocialLogin.unstash_state(request) ret = complete_social_login(request, login) except (requests.RequestException, DraugiemApiError) as e: auth_exception = e if not ret: ret = render_authentication_error( request, DraugiemProvider.id, exception=auth_exception) return ret
def login_by_token(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: provider = providers.registry.by_id(FacebookProvider.id) app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) access_token = form.cleaned_data['access_token'] info = requests.get( 'https://graph.facebook.com/oauth/access_token_info', params={'client_id': app.client_id, 'access_token': access_token}) nonce = provider.get_nonce(request, pop=True) if nonce and nonce == info.json().get('auth_nonce'): 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: logger.exception('Error accessing FB user profile') if not ret: ret = render_authentication_error(request) return ret
def login_by_token(request): log.debug("login_by_token") ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): log.debug("Form is valid") try: app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) log.debug("App exists") access_token = form.cleaned_data['access_token'] log.debug("access token exists") token = SocialToken(app=app, token=access_token) log.debug("social token created") login = fb_complete_login(app, token) log.debug("fb login complete") login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except: # FIXME: Catch only what is needed pass if not ret: log.debug("authentication error") ret = render_authentication_error(request) return ret
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'], token_secret=access_token['oauth_token_secret']) login = self.adapter.complete_login(request, app, 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): if 'error' in request.GET or not 'code' in request.GET: # TODO: Distinguish cancel from error return render_authentication_error(request) 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 # jp 6/1/2014 get open id from qq using the access token open_id = client.get_open_id(token.token) login = self.adapter.complete_login(request, app, token, response=access_token, consumer_key=client.consumer_key, openid=open_id) token.account = login.account login.token = token if self.adapter.supports_state: login.state = SocialLogin \ .verify_and_unstash_state( request, request.REQUEST.get('state')) else: login.state = SocialLogin.unstash_state(request) return complete_social_login(request, login) except OAuth2Error as e: return render_authentication_error(request)
def login_by_token(request): ret = None auth_exception = None if request.method == 'POST': form = KakaoConnectForm(request.POST) if form.is_valid(): try: provider = providers.registry.by_id(KakaoProvider.id) app = providers.registry.by_id(KakaoProvider.id).get_app(request) access_token = form.cleaned_data['access_token'] token = SocialToken(app=app, token=access_token) login = kakao_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 KAKAO user profile') auth_exception = e if not ret: ret = render_authentication_error(request, KakaoProvider.id, exception+auth_exception) return ret
def api_facebook_connect_by_token(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: app = providers.registry.by_id(FacebookProvider.id)\ .get_app(request) access_token = form.cleaned_data['access_token'] token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except: # FIXME: Catch only what is needed pass if not ret: raise Http404 profile = Profile.objects.get_or_create(user=request.user)[0] profile.avatar_url = login.account.get_avatar_url() profile.save() user_source = UserResource() bundle = user_source.build_bundle(obj=request.user, request=request) bundle = user_source.full_dehydrate(bundle) bundle = user_source.alter_detail_data_to_serialize(request, bundle) return user_source.create_response(request, bundle)
def post(self, request): data = JSONParser().parse(request) access_token = data.get('access_token', '') try: app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) # check token against facebook login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) # add or update the user into users table ret = complete_social_login(request, login) # if we get here we've succeeded return Response(status=200, data={ 'success': True, 'username': request.user.username, 'user_id': request.user.pk, }) except: return Response(status=401 ,data={ 'success': False, 'reason': "Bad Access Token", })
def post(self, request, provider=None, params=None, **kwargs): from requests import RequestException from allauth.socialaccount import providers from allauth.socialaccount.helpers import complete_social_login from allauth.socialaccount.models import SocialLogin, SocialToken from allauth.socialaccount.providers.facebook.provider import FacebookProvider if provider == 'facebook': try: app = providers.registry.by_id(FacebookProvider.id).get_app(request) token = SocialToken(app=app, token=params.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 RequestException: return http.HttpBadRequest('Error accessing FB user profile') else: # If user does not exist if login.account.user.id is None: return http.HttpBadRequest('Not registered') return self._construct_login_response(login.account.user) return http.HttpBadRequest('Invalid provider')
def post(self, request): print "posting data" data = JSONParser().parse(request) access_token = data.get('access_token', '') try: print request app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) print login ret = complete_social_login(request, login) return Response(status=200, data={ 'success': True, 'username': request.user.username, 'user_id': request.user.pk, }) except: return Response(status=401 ,data={ 'success': False, 'reason': "Bad Access Token", })
def dispatch(self, request): if 'error' in request.GET or 'code' not in request.GET: # TODO: Distinguish cancel from error return render_authentication_error(request) 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) token.account = login.account login.token = token if self.adapter.supports_state: login.state = SocialLogin \ .verify_and_unstash_state( request, request.REQUEST.get('state')) else: login.state = SocialLogin.unstash_state(request) return complete_social_login(request, login) except (OAuth2Error, PermissionDenied): if self.adapter.getErrorTemplate() is not None: return render_authentication_error(request, error_template=self.adapter.getErrorTemplate()) else: return render_authentication_error(request)
def login(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: token = form.cleaned_data['access_token'] g = GraphAPI(token) facebook_me = g.get_object("me") email = valid_email_or_none(facebook_me.get('email')) social_id = facebook_me['id'] try: account = FacebookAccount.objects.get(social_id=social_id) except FacebookAccount.DoesNotExist: account = FacebookAccount(social_id=social_id) data = dict(email=email, facebook_access_token=token, facebook_me=facebook_me) # some facebook accounts don't have this data data.update((k,v) for (k,v) in facebook_me.items() if k in ['username', 'first_name', 'last_name']) # Don't save partial/temporary accounts that haven't # gone through the full signup yet, as there is no # User attached yet. if account.pk: account.sync(data) ret = complete_social_login(request, data, account) except (GraphAPIError, IOError): pass if not ret: ret = render_authentication_error(request) return ret
def get(self, request, *args, **kwargs): try: original_request = request._request auth_token = crypt.Cipher.decrypt(self.request.query_params.get('auth_token').replace(' ', '+').encode()) #request.GET.get('auth_token', '') # Find the token matching the passed Auth token app = SocialApp.objects.get(provider='vk') vk_auth_token = SocialToken(app=app, token=auth_token) #account = SocialToken.objects.get(token=vk_auth_token).account # check token against facebook adapter = VKOAuth2Adapter(request) login = adapter.complete_login(original_request, app, vk_auth_token, **{'response':{'user_id': None}}) #login = fb_complete_login(original_request, app, vk_auth_token) login.token = vk_auth_token login.state = SocialLogin.state_from_request(original_request) # add or update the user into users table complete_social_login(original_request, login) # Create or fetch the session id for this user token, _ = Token.objects.get_or_create(user=original_request.user) # if we get here we've succeeded social_account = SocialAccount.objects.filter(user=original_request.user)[0] jenc = bytes(crypt.Cipher.pad(str(token.key).replace(' ', '+')), 'utf-8') enc = crypt.Cipher.encrypt(jenc) data = { 'username': original_request.user.username, 'objectId': original_request.user.pk, 'firstName': original_request.user.first_name, 'lastName': original_request.user.last_name, 'sessionToken': enc.decode(), 'avatar': str(social_account.extra_data['photo_big']).split('?')[0], 'email': original_request.user.email, } return Response( status=200, data=data ) except: return Response(status=401, data={ 'detail': 'Bad Access Token', })
def _wrapped_view(request, *args, **kwargs): if request.user.is_authenticated(): return view_func(request, *args, **kwargs) access_token = request.REQUEST.get('access_token', '') try: app = SocialApp.objects.get(provider='facebook') token = SocialToken(app=app, token=access_token) login = fb_complete_login(request, app, token) login.token = token login.state = SocialLogin.state_from_request(request) complete_social_login(request, login) return view_func(request, *args, **kwargs) # TODO: what to except here? except: context = {'error': 'Unable to get or create facebook user.'} return render_response(request, 'assassin/login.html', context)
def get(self, request, *args, **kwargs): request.encoding = "utf-8" try: original_request = request._request auth_token = request.GET.get('auth_token', '') # Find the token matching the passed Auth token app = SocialApp.objects.get(provider='facebook') fb_auth_token = SocialToken(app=app, token=auth_token) # check token against facebook login = fb_complete_login(original_request, app, fb_auth_token) login.token = fb_auth_token login.state = SocialLogin.state_from_request(original_request) # add or update the user into users table complete_social_login(original_request, login) # Create or fetch the session id for this user token, _ = Token.objects.get_or_create(user=original_request.user) # if we get here we've succeeded data = { 'username': original_request.user.username, 'objectId': original_request.user.pk, 'firstName': original_request.user.first_name, 'lastName': original_request.user.last_name, 'sessionToken': token.key, 'email': original_request.user.email, } print(data) return Response( status=200, data=data ) except: traceback.print_exc(file=sys.stdout) return Response(status=401, data={ 'detail': 'Bad Access Token', })
def validate(self, attrs): view = self.context.get('view') request = self._get_request() if not view: raise serializers.ValidationError( 'View is not defined, pass it as a context variable' ) adapter_class = getattr(view, 'adapter_class', None) if not adapter_class: raise serializers.ValidationError('Define adapter_class in view') adapter = adapter_class() app = adapter.get_provider().get_app(request) if('access_token' in attrs) and ('token_secret' in attrs): access_token = attrs.get('access_token') token_secret = attrs.get('token_secret') else: raise serializers.ValidationError('Incorrect input. access_token and token_secret are required.') request.session['oauth_api.twitter.com_access_token'] = { 'oauth_token': access_token, 'oauth_token_secret': token_secret, } token = SocialToken(token=access_token, token_secret=token_secret) token.app = app try: login = self.get_social_login(adapter, app, token, access_token) complete_social_login(request, login) except HTTPError: raise serializers.ValidationError('Incorrect value') if not login.is_existing: login.lookup() login.save(request, connect=True) attrs['user'] = login.account.user return attrs
def dispatch(self, request): if 'error' in request.GET or not 'code' in request.GET: # TODO: Distinguish cancel from error return render_authentication_error(request) 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 = SocialToken(app=app, token=access_token) login = self.adapter.complete_login(request, app, token) token.account = login.account login.token = token login.state = SocialLogin.unmarshall_state( request.REQUEST.get('state')) return complete_social_login(request, login) except OAuth2Error: return render_authentication_error(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, request) login_options = provider.get_fb_login_options(request) app = provider.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 and provider.get_settings().get('EXCHANGE_TOKEN'): resp = requests.get(GRAPH_API_URL + '/oauth/access_token', params={ 'grant_type': 'fb_exchange_token', 'client_id': app.client_id, 'client_secret': app.secret, 'fb_exchange_token': access_token }).json() access_token = resp['access_token'] 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
def dispatch(self, request): if 'error' in request.GET or 'access_token' 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: # Parse the access token access_token = { 'access_token': request.GET['access_token'], 'expires_in': request.GET['expires_in'] } token = self.adapter.parse_token(access_token) token.app = app login = self.adapter.complete_login(request, app, token, response=access_token) login.token = token SocialLogin.stash_state(request) 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) # Make sure the user is initiated with some training in the DB request.session['initial_training'] = 'e' return complete_social_login(request, login) except (PermissionDenied, OAuth2Error, RequestException, ProviderException) as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
def telegram_login(request): provider = providers.registry.by_id(TelegramProvider.id, request) data = dict(request.GET.items()) hash = data.pop('hash') payload = '\n'.join(sorted(['{}={}'.format(k, v) for k, v in data.items()])) token = provider.get_settings()['TOKEN'] token_sha256 = hashlib.sha256(token.encode()).digest() expected_hash = hmac.new(token_sha256, payload.encode(), hashlib.sha256).hexdigest() auth_date = int(data.pop('auth_date')) if hash != expected_hash or time.time() - auth_date > 30: return render_authentication_error(request, provider_id=provider.id, extra_context={'response': data}) login = provider.sociallogin_from_response(request, data) return complete_social_login(request, login)
def dispatch(self, 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 = self.provider.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, self.provider.id, error=error) return ret
def callback(request): client = _openid_consumer(request) response = client.complete(dict(request.REQUEST.items()), request.build_absolute_uri(request.path)) if response.status == consumer.SUCCESS: email = _get_email_from_response(response) identity = response.identity_url try: account = OpenIDAccount.objects.get(identity=identity) except OpenIDAccount.DoesNotExist: account = OpenIDAccount(identity=identity) data = dict(email=email) ret = complete_social_login(request, data, account) elif response.status == consumer.CANCEL: ret = HttpResponseRedirect(reverse('socialaccount_login_cancelled')) else: ret = render_authentication_error(request) return ret
def oauth_callback(request, *args, **kwargs): try: is_google = request.GET['provider'] == 'google' adapter = GoogleOAuth2Adapter(request) if is_google else FacebookOAuth2Adapter(request) provider = adapter.get_provider() app = adapter.get_provider().get_app(request) try: if is_google: callback_url = adapter.get_callback_url(request, app) scope = provider.get_scope(request) client = OAuth2Client(request, app.client_id, app.secret, adapter.access_token_method, adapter.access_token_url, callback_url, scope, scope_delimiter=adapter.scope_delimiter, headers=adapter.headers, basic_auth=adapter.basic_auth) access_token = client.get_access_token(request.GET['code']) token = adapter.parse_token(access_token) else: access_token = request.GET['code'] token = adapter.parse_token({'access_token': access_token, 'token_type': 'bearer', 'expires_in': 5179237}) # hard-coded properties to make allauth happy token.app = app login = adapter.complete_login(request, app, token, response=access_token) login.token = token return complete_social_login(request, login) except (PermissionDenied, OAuth2Error, RequestException, ProviderException) as e: return render_authentication_error( request, adapter.provider_id, exception=e) except ImmediateHttpResponse as e: return e.response
def dispatch(self, request, *args, **kwargs): """ This overloading is necessary to manage the case when the user clicks on "Cancel" once on the "Mire de connexion PE Connect". Original code: https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/providers/oauth2/views.py#L113 """ 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 elif auth_error is None and "state" in request.GET: # This custom case happens when the user clicks "Cancel" on the # "Mire de connexion PE Connect". 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, RequestException, ProviderException) as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
def login_by_token(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): try: app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) access_token = form.cleaned_data['access_token'] token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except requests.RequestException: logger.exception('Error accessing FB user profile') if not ret: ret = render_authentication_error(request) return ret
def dispatch(self, request, *args, **kwargs): 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, RequestException, ProviderException) as e: if isinstance(e, PermissionDenied) or isinstance(e, OAuth2Error): # One of these errors are raised when a user authenticated through dataporten # uses the browser back button. Simply redirect to ``/``. return HttpResponseRedirect('/') return render_authentication_error( request, self.adapter.provider_id, exception=e)
def dispatch(self, request, *args, **kwargs): logger.info("start login") if 'error' in request.GET or 'code' not in request.GET: # Distinguish cancel from error auth_error = request.GET.get('error', None) logger.info("auth_error %s " % auth_error) if auth_error == self.adapter.login_cancelled_error: error = AuthError.CANCELLED logger.info("AuthError.CANCELLED %s " % error) else: error = AuthError.UNKNOWN logger.info("AuthError.UNKNOWN %s %s" % (error, auth_error)) return render_authentication_error(request, self.adapter.provider_id, error=error) app = self.adapter.get_provider().get_app(self.request) logger.info("app %s " % app) client = self.get_client(request, app) try: access_token = client.get_access_token(request.GET['code']) logger.info("access_token %s " % access_token) token = self.adapter.parse_token(access_token) logger.info("parse_token %s " % token) token.app = app login = self.adapter.complete_login(request, app, token, response=access_token) logger.info("logged in %s " % login) 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, RequestException, ProviderException) as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
def login_by_token(request, access_token): ret = None if request.method == 'POST': try: app = providers.registry.by_id(FacebookProvider.id) \ .get_app(request) access_token = access_token token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except: # FIXME: Catch only what is needed pass if not ret: ret = render_authentication_error(request) return ret
def callback(request): client = _openid_consumer(request) response = client.complete(dict(request.REQUEST.items()), request.build_absolute_uri(request.path)) if response.status == consumer.SUCCESS: user = get_adapter() \ .populate_new_user(email=_get_email_from_response(response)) account = SocialAccount(uid=response.identity_url, provider=OpenIDProvider.id, user=user, extra_data={}) login = SocialLogin(account) login.state = SocialLogin.unstash_state(request) ret = complete_social_login(request, login) elif response.status == consumer.CANCEL: ret = HttpResponseRedirect(reverse('socialaccount_login_cancelled')) else: ret = render_authentication_error(request) return ret
def persona_complete(request): assertion = request.session.pop('sociallogin_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}) if resp.json()['status'] != 'okay': return render_authentication_error(request) extra_data = resp.json() 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 wykop_login_by_token(request): ret = None if request.method == 'GET': form = WykopConnectForm(request.GET) if form.is_valid(): try: app = providers.registry.by_id(WykopProvider.id).get_app(request) connectData = form.cleaned_data['connectData'] connectData = ast.literal_eval(base64.b64decode(connectData)) token = SocialToken(app=app, token=connectData['token']) login = wykop_complete_login(app, connectData) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except AttributeError: # FIXME: Catch only what is needed pass if not ret: ret = render_authentication_error(request) return ret
def dispatch(self, request): """ The CAS server redirects the user to this view after a successful authentication. On redirect, CAS server should add a ticket whose validity is verified here. If ticket is valid, CAS server may also return extra attributes about user. """ client = self.get_client(request) # CAS server should let a ticket. try: ticket = request.GET['ticket'] except KeyError: raise CASAuthenticationError( "CAS server didn't respond with a ticket." ) # Check ticket validity. # Response format on: # - success: username, attributes, pgtiou # - error: None, {}, None response = client.verify_ticket(ticket) uid, extra, _ = response if not uid: raise CASAuthenticationError( "CAS server doesn't validate the ticket." ) # Keep tracks of the last used CAS provider. request.session[CAS_PROVIDER_SESSION_KEY] = self.provider.id data = (uid, extra or {}) # Finish the login flow. login = self.adapter.complete_login(request, data) login.state = SocialLogin.unstash_state(request) return complete_social_login(request, login)
def callback(request): client = _openid_consumer(request) response = client.complete( dict(request.REQUEST.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 dispatch(self, request, *args, **kwargs): 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(self.request, app) try: access_token = self.adapter.get_access_token_data( request, app, client) 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, RequestException, ProviderException, ) as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
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 telegram_login(request): provider = providers.registry.by_id(CustomTelegramProvider.id, request) data = dict(request.GET.items()) hash = data.pop("hash") payload = "\n".join(sorted(["{}={}".format(k, v) for k, v in data.items()])) token = provider.get_settings()["TOKEN"] token_sha256 = hashlib.sha256(token.encode()).digest() expected_hash = hmac.new(token_sha256, payload.encode(), hashlib.sha256).hexdigest() auth_date = int(data.pop("auth_date")) if hash != expected_hash or time.time() - auth_date > 30: return render_authentication_error(request, provider_id=provider.id, extra_context={"response": data}) login = provider.sociallogin_from_response(request, data) if request.COOKIES.get("process") == 'connect': login.state['process'] = AuthProcess.CONNECT login.state['next'] = request.COOKIES.get('next') return complete_social_login(request, login)
def dispatch(self, request): if 'error' in request.GET or not 'code' in request.GET: # TODO: Distinguish cancel from error return render_authentication_error(request) app = self.adapter.get_app(self.request) client = self.get_client(request, app) provider_id = self.adapter.provider_id try: access_token = client.get_access_token(request.GET['code']) uid, data, extra_data = self.adapter.get_user_info( request, app, access_token) except OAuth2Error: return render_authentication_error(request) # TODO: DRY, duplicates OAuth logic try: account = SocialAccount.objects.get(provider=provider_id, uid=uid) except SocialAccount.DoesNotExist: account = SocialAccount(provider=provider_id, uid=uid) account.extra_data = extra_data if account.pk: account.save() return complete_social_login(request, data, account)
def callback(request): token = request.POST.get('Token', '') if not token: return render_authentication_error( request, ServiceKontoProvider.id, error=AuthError.UNKNOWN) try: login = _complete_login(request, token) except ServiceKontoApiError as e: return render_authentication_error( request, ServiceKontoProvider.id, exception=e.__cause__, error=e.error) except ValueError as e: return render_authentication_error( request, ServiceKontoProvider.id, exception=e, error=AuthError.UNKNOWN) ret = complete_social_login(request, login) if not ret: ret = render_authentication_error(request, ServiceKontoProvider.id) return ret
def dispatch(self, request, *args, **kwargs): """ Copied from base class to be able to pass the app to parse_token to use its data to match up to token claims. """ 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, app=app) 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, RequestException, ProviderException) as e: return render_authentication_error(request, self.adapter.provider_id, exception=e)
def login(request): ret = None if request.method == 'POST': form = FacebookConnectForm(request.POST) if form.is_valid(): token = form.cleaned_data['access_token'] g = GraphAPI(token) data = g.get_object("me") email = valid_email_or_none(data.get('email')) social_id = data['id'] try: account = FacebookAccount.objects.get(social_id=social_id) except FacebookAccount.DoesNotExist: account = FacebookAccount(social_id=social_id) account.link = data['link'] account.name = data['name'] if account.pk: account.save() data = dict(email=email, facebook_me=data) ret = complete_social_login(request, data, account) if not ret: ret = render_authentication_error(request) return ret
def mobile_facebook_login(request): if request.method == "POST": response = HttpResponse access_token = str(request.POST['access_token']) #email=str(request.POST['email']) try: app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) # Check token against facebook login = fb_complete_login(request, app, token) login.token = token login.state = SocialLogin.state_from_request(request) # Add or update the user into users table ret = complete_social_login(request, login) a = SocialToken.objects.get(token=access_token) try: account = a.account user = account.user tuple = UserProfile.objects.get_or_create( user=user, dp=account.get_avatar_url(), fullName=user.get_full_name()) if tuple[1] == True: Token.objects.create(user=user) UserProfile.objects.update(user=user, isNew=False) else: UserProfile.objects.update(user=user, isNew=False) x = UserProfile.objects.filter(user=user).values('isNew') return JsonResponse({'results': list(x)}) except User.DoesNotExist: return HttpResponse("User Dosent Exist") return HttpResponse("wuhoo") except Exception as e: # If we get here we've failed return HttpResponse(str(e) + "")
def interoves_telegram_login(request): # resp = requests.post('https://verifier.login.persona.org/verify', # {'assertion': assertion, # 'audience': audience}) settings = app_settings.PROVIDERS.get(InterovesTelegramProvider.id, {}) resp = requests.post( 'https://oauth.telegram.org/embed/interoves_bot', { 'origin': settings['domain'], 'size': settings['size'], 'request_access': settings['request_access'], }) print(resp) try: resp.raise_for_status() except (ValueError, requests.RequestException) as e: return render_authentication_error( request, provider_id=InterovesTelegramProvider.id, exception=e) login = providers.registry \ .by_id(InterovesTelegramProvider.id, request) \ .sociallogin_from_response(request, {}) login.state = SocialLogin.state_from_request(request) return complete_social_login(request, login)
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, request.REQUEST.get('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 facebook_login(self, request, **kwargs): self.method_check(request, allowed=['post']) data = self.deserialize(request, request.raw_post_data, format=request.META.get( 'CONTENT_TYPE', 'application/json')) access_token = data.get('access_token', '') from allauth.socialaccount import providers from allauth.socialaccount.models import SocialLogin, SocialToken, SocialApp from allauth.socialaccount.providers.facebook.views import fb_complete_login from allauth.socialaccount.helpers import complete_social_login try: app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) login = fb_complete_login(app, token) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) #if we get here we've succeeded return self.create_response( request, { 'success': True, 'username': request.user.username, 'user_id': request.user.pk, 'api_key': request.user.api_key.key, }) except: # FIXME: Catch only what is needed return self.create_response(request, { 'success': False, 'reason': "Bad Access Token", }, HttpForbidden)
def validate(self, attrs): view = self.context.get('view') request = self._get_request() if not view: raise serializers.ValidationError( _("View is not defined, pass it as a context variable")) adapter_class = getattr(view, 'adapter_class', None) if not adapter_class: raise serializers.ValidationError( _("Define adapter_class in view")) adapter = adapter_class(request) app = adapter.get_provider().get_app(request) # More info on code vs access_token # http://stackoverflow.com/questions/8666316/facebook-oauth-2-0-code-and-token # Case 1: We received the access_token if attrs.get('access_token'): access_token = attrs.get('access_token') # Case 2: We received the authorization code elif attrs.get('code'): self.callback_url = getattr(view, 'callback_url', None) self.client_class = getattr(view, 'client_class', None) if not self.callback_url: raise serializers.ValidationError( _("Define callback_url in view")) if not self.client_class: raise serializers.ValidationError( _("Define client_class in view")) code = attrs.get('code') provider = adapter.get_provider() scope = provider.get_scope(request) client = self.client_class(request, app.client_id, app.secret, adapter.access_token_method, adapter.access_token_url, self.callback_url, scope) token = client.get_access_token(code) access_token = token['access_token'] else: raise serializers.ValidationError( _("Incorrect input. access_token or code is required.")) social_token = adapter.parse_token({'access_token': access_token}) social_token.app = app try: login = self.get_social_login(adapter, app, social_token, access_token) complete_social_login(request, login) except HTTPError: raise serializers.ValidationError(_("Incorrect value")) if not login.is_existing: # We have an account already signed up in a different flow # with the same email address: raise an exception. # This needs to be handled in the frontend. We can not just # link up the accounts due to security constraints if allauth_settings.UNIQUE_EMAIL: # Do we have an account already with this email address? account_exists = get_user_model().objects.filter( email=login.user.email, ).exists() if account_exists: raise serializers.ValidationError( _("User is already registered with this e-mail address." )) login.lookup() login.save(request, connect=True) attrs['user'] = login.account.user return attrs
def validate(self, attrs): view = self.context.get('view') request = self._get_request() if not view: raise serializers.ValidationError( _('View is not defined, pass it as a context variable')) adapter_class = getattr(view, 'adapter_class', None) if not adapter_class: raise serializers.ValidationError( _('Define adapter_class in view')) adapter = adapter_class(request) app = adapter.get_provider().get_app(request) # More info on code vs access_token # http://stackoverflow.com/questions/8666316/facebook-oauth-2-0-code-and-token # Case 1: We received the access_token if ('access_token' in attrs): access_token = attrs.get('access_token') # Case 2: We received the authorization code elif ('code' in attrs): self.callback_url = getattr(view, 'callback_url', None) self.client_class = getattr(view, 'client_class', None) if not self.callback_url: raise serializers.ValidationError( _('Define callback_url in view')) if not self.client_class: raise serializers.ValidationError( _('Define client_class in view')) code = attrs.get('code') provider = adapter.get_provider() scope = provider.get_scope(request) client = self.client_class(request, app.client_id, app.secret, adapter.access_token_method, adapter.access_token_url, self.callback_url, scope) token = client.get_access_token(code) access_token = token['access_token'] else: raise serializers.ValidationError( _('Incorrect input. access_token or code is required.')) token = adapter.parse_token({'access_token': access_token}) token.app = app try: login = self.get_social_login(adapter, app, token, access_token) complete_social_login(request, login) except HTTPError: raise serializers.ValidationError(_('Incorrect value')) if not login.is_existing: login.lookup() login.save(request, connect=True) attrs['user'] = login.account.user return attrs