def parse_token(self, data, app=None): # parse token header and get relevant public key unverified_header, unverified_claims = jwt.process_jwt( data['id_token']) public_key = self.get_public_key(unverified_header.get('kid')) # verify signature, iat, exp header, claims = jwt.verify_jwt(data['id_token'], public_key, ['RS256'], timedelta(minutes=1), checks_optional=True) # Verify we are the intended audience for the token intended_audiences = [self.intended_aud] if app is not None: intended_audiences.append(app.client_id) if claims.get('aud') is not None and claims.get( 'aud') not in intended_audiences: raise OAuth2Error( "JWT aud {} does not match intended audience {}".format( claims.get('aud'), self.intended_aud)) social_token = SocialToken(token=data['id_token']) social_token.expires_at = datetime.fromtimestamp(claims['iat'], tz=timezone.utc) return social_token
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 parse_token(self, data): token = SocialToken(token=data["access_token"]) token.token_secret = data.get("refresh_token", "") expires_in = data.get(self.expires_in_key, None) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) return token
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 parse_token(self, data): token = SocialToken(token=data['access_token']) token.token_secret = data.get('refresh_token', '') expires_in = data.get(self.expires_in_key, None) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) return token
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 post(self, request): serializer = OAuthTokenSerializer(data=request.data) non_field_error_key = getattr( settings, "NON_FIELD_ERRORS_KEY", "non_field_errors" ) provider = self.provider(request) err_r = JsonResponse({non_field_error_key: {"error": "Access token invalid"}}) if not serializer.is_valid(): return err_r data = serializer.validated_data # Create the token # from allauth.socialaccount.providers.oauth2.views.OAuth2Adapter.parse_token token = SocialToken(token=data["access_token"]) token.token_secret = data.get("refresh_token", "") token.app = provider.get_app(request) expires_in = data.get(self.expires_in_key, None) if expires_in: token.expires_at = timezone.now() + timedelta(seconds=int(expires_in)) # Verify the access token works resp = requests.get( self.profile_url, params={"access_token": token.token, "alt": "json"}, ) if resp.status_code > 299: # We've got a problem return err_r extra_data = resp.json() login = provider.sociallogin_from_response(request, extra_data) login.lookup() if not login.is_existing: login.save(request) # Create SimpleJWT tokens for consumer authentication purposes simple_token = RefreshToken.for_user(login.user) def save_info_in_simple_token(_token): _token["provider_id"] = provider.id _token["provider_access_token"] = data["access_token"] _token["provider_refresh_token"] = token.token_secret return str(_token) return JsonResponse( { "access_token": save_info_in_simple_token(simple_token.access_token), "refresh_token": save_info_in_simple_token(simple_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(request) app = adapter.get_provider().get_app(request) access_token = attrs.get('access_token') token_secret = attrs.get('token_secret') 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 OAuthError as e: raise serializers.ValidationError(str(e)) 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 test_get_redir_user_demo(self): payload = {"user": {"username": self.demo["username"]}} self.client.login(username=payload["user"]["username"], password="******") sapp = SocialApp(provider='github', name='Github', client_id='<test>', secret='<test>') sapp.save() sacc = SocialAccount(uid=1001, user=self.test_user, provider="github") sacc.save() stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual( first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001" ) self.client.login(username=payload["user"]["username"], password="******") stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual( first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001" )
def parse_token(self, data): token = SocialToken(token=data["access_token"], ) token.token_secret = data.get("refresh_token", "") expires_in = data.get(self.expires_in_key) if expires_in: token.expires_at = timezone.now() + timedelta( seconds=int(expires_in)) # `user_data` is a big flat dictionary with the parsed JWT claims # access_tokens, and user info from the apple post. identity_data = self.get_verified_identity_data(data["id_token"]) token.user_data = {**data, **identity_data} return token
def get_sociallogin(self, request, data): app = SocialApp.objects.get(provider='facebook') fb_auth_token = SocialToken(app=app, token=data['token']['token']) login = fb_complete_login(request, app, fb_auth_token) login.token = fb_auth_token login.state = SocialLogin.state_from_request(request) return login
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, format=None): """ 透過 Facebook access token 建立 Facebook 帳號或是登入 """ serializer = self.serializer_class(data=request.DATA) if serializer.is_valid(): access_token = serializer.data.get('access_token') try: st = SocialToken.objects.get(token=access_token) user = st.account.user user.backend = 'django.contrib.auth.backends.ModelBackend' if user.is_active: login(request, user) serializer = UserInfoSerializer(request.user) return Response(serializer.data, status=status.HTTP_200_OK) except SocialToken.DoesNotExist: pass try: app = providers.registry.by_id(FacebookProvider.id).get_app(request) token = SocialToken(app=app, token=access_token) fb_login = fb_complete_login(request, app, token) complete_login(request, fb_login, app, token) serializer = UserInfoSerializer(request.user) return Response(serializer.data, status=status.HTTP_200_OK) except requests.RequestException as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
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): """ 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 save(self, request): user = self.validated_data['user'] if user: return user else: app = SocialApp.objects.get(provider='facebook') social_token = SocialToken(app=app, token=self.validated_data['fcb_token']) try: # Check token against Facebook original_request = request._request login = fb_complete_login(original_request, app, social_token) login.token = social_token login.state = SocialLogin.state_from_request(original_request) complete_social_login(original_request, login) except HTTPError: # 400 Client Error raise exceptions.AuthenticationFailed( _('Facebook authentication failed.')) else: self.cleaned_data = self.validated_data # Needed by save_user() return get_socialaccount_adapter().save_user( request, login, self)
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 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): ret = None if (request.method == 'POST'): form = TwitterConnectForm(request.POST) if form.is_valid(): try: app = providers.registry.by_id( TwitterProvider.id).get_app(request) oauth_token = form.cleaned_data['oauth_token'] oauth_token_secret = form.cleaned_data['oauth_token_secret'] token = SocialToken(app=app, token=oauth_token, token_secret=oauth_token_secret) auth = OAuth1(app.client_id, app.secret, token.token, token.token_secret) resp = requests.get(VERIFY_CREDENTIALS_URL, auth=auth) resp.raise_for_status() extra_data = resp.json() login = twitter_complete_login(extra_data) login.token = token login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, login) except requests.RequestException: logger.exception('Error accessing Twitter user profile') if not ret: ret = render_authentication_error(request) return ret
def create_game(request): if request.method=="POST": lon=str(request.POST['longitude']) lat=str(request.POST['latitude']) access_token =str(request.POST['access_token']) type=str(request.POST['type']) #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 location = Point(lon, lat) game=Game.objects.create(host=user,location=location,type=type) return HttpResponse("done") except User.DoesNotExist: return HttpResponse("User Dosent Exist") return HttpResponse("wuhoo") except Exception as e: # If we get here we've failed return HttpResponse("ASdsa "+str(e))
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 user.backend = 'django.contrib.auth.backends.ModelBackend' profile=UserProfile.objects.get_or_create(user=user,dp=account.get_avatar_url(),fullName=user.get_full_name())[0] return HttpResponse(serializers.serialize("json",[profile])) except User.DoesNotExist: return HttpResponse("User Dosent Exist") return HttpResponse("wuhoo") except Exception as e: # If we get here we've failed return HttpResponse("ASdsa "+str(e))
def join_game(request): if request.method=="POST": id=str(request.POST['uuid']) access_token =str(request.POST['access_token']) type=str(request.POST['type']) #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 game=Game.objects.create(id=id) game.participants.add(user) return HttpResponse(serializers.serialize("json",[game])) except User.DoesNotExist: return HttpResponse("User Dosent Exist") return HttpResponse("wuhoo") except Exception as e: # If we get here we've failed return HttpResponse("ASdsa "+str(e))
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 test_google_compelete_login_401(self): class LessMockedResponse(MockedResponse): def raise_for_status(self): if self.status_code != 200: raise HTTPError(None) request = RequestFactory().get(reverse(self.provider.id + '_login'), dict(process='login')) app = self.provider.get_app(request) token = SocialToken(token='some_token') response_with_401 = LessMockedResponse( 401, """ {"error": { "errors": [{ "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } }""") with patch('allauth.socialaccount.providers.common.google.provider' '.requests') as patched_requests: patched_requests.get.return_value = response_with_401 with self.assertRaises(HTTPError): self.provider.complete_login(request, app, token)
def facebook_signup(self, request, access_token): try: app = SocialApp.objects.get(provider="facebook") token = SocialToken(app=app, token=access_token) fb_login = fb_complete_login(request, app, token) fb_login.token = token fb_login.state = SocialLogin.state_from_request(request) ret = complete_social_login(request, fb_login) response_data = {} if request.user.is_authenticated(): if request.user.username == "": request.user.username = request.data['email'] request.user.email = request.data['email'] request.user.first_name = request.data['fname'] request.user.last_name = request.data['lname'] request.user.save() data = UserProfileSerializer(request.user).data return data else: return {'error': "User with this email already exists."} except Exception as e: return {'error': str(e)}
def _create_social_user(self, emails, provider, uid, token=None): factory = RequestFactory() request = factory.get("/me/login/callback/") request.user = AnonymousUser() SessionMiddleware().process_request(request) MessageMiddleware().process_request(request) user = User( username=emails[0].email.split("@")[0], first_name=emails[0].email.split("@")[0], last_name=emails[0].email.split("@")[1], email=emails[0].email, ) account = SocialAccount(provider=provider, uid=uid) if token is not None: token = SocialToken( token=token, account=account, app=SocialApp.objects.get(provider=provider), ) sociallogin = SocialLogin(account=account, user=user, email_addresses=emails, token=token) complete_social_login(request, sociallogin)
def test_ynab_compelete_login_401(self): from allauth.socialaccount.providers.ynab.views import ( YNABOAuth2Adapter, ) class LessMockedResponse(MockedResponse): def raise_for_status(self): if self.status_code != 200: raise HTTPError(None) request = RequestFactory().get(reverse(self.provider.id + "_login"), dict(process="login")) adapter = YNABOAuth2Adapter(request) app = adapter.get_provider().get_app(request) token = SocialToken(token="some_token") response_with_401 = LessMockedResponse( 401, """ {"error": { "errors": [{ "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } }""", ) with patch("allauth.socialaccount.providers.ynab.views.requests" ) as patched_requests: patched_requests.get.return_value = response_with_401 with self.assertRaises(HTTPError): adapter.complete_login(request, app, token)
def social(self, request, access_token): 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 (request, login.user)
def set_up_social(self): self.social_app = SocialApp(provider='GitHub', name='GitHub', client_id='B', secret='A') self.social_app.save() self.social_account = SocialAccount(user=self.user, provider='github', uid='A') self.social_account.save() self.social_token = SocialToken(app=self.social_app, account=self.social_account, token='A', token_secret='B') self.social_token.save()
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 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 return complete_social_login(request, login) except OAuth2Error: return render_authentication_error(request)
def complete_login(self, request, app, token, email_addresses=[]): client = TwitterAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() uid = extra_data['id'] user = User.objects.filter(username=extra_data.get('screen_name')) if user: return user else: user = get_adapter() \ .populate_new_user(username=extra_data.get('screen_name'), name=extra_data.get('name')) user.save() account = SocialAccount(user=user, uid=uid, provider=TwitterProvider.id, extra_data=extra_data) account.save() application = SocialApp.objects.get(secret=app.secret) sample_token = SocialToken.objects.filter(app=application, account=account) if sample_token: token = sample_token[0] else: token = SocialToken( app=application, account=account, token=request.session["oauth_api.twitter.com_access_token"] ["oauth_token"], token_secret=request. session["oauth_api.twitter.com_access_token"] ["oauth_token_secret"]) token.save() mail = send_email_confirmation(request=request, user=user, signup=True) return SocialLogin(account=account, token=token, email_addresses=email_addresses)
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"] expires_at = None 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"] expires_in = resp.get("expires_in") if expires_in: expires_at = timezone.now() + timedelta( seconds=int(expires_in)) if ok: token = SocialToken(app=app, token=access_token, expires_at=expires_at) 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 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, refresh_token = client.get_access_token(request.GET['code']) token = SocialToken(app=app, token=access_token, token_secret=refresh_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')) login.redirect_account_url = request.session.pop('redirect_account_url', None) return complete_social_login(request, login) except OAuth2Error: return render_authentication_error(request)
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 complete_login(self, request, app, token, email_addresses=[]): client = TwitterAPI(request, app.client_id, app.secret, self.request_token_url) extra_data = client.get_user_info() uid = extra_data['id'] user = User.objects.filter(username=extra_data.get('screen_name')) if user: return user else: user = get_adapter() \ .populate_new_user(username=extra_data.get('screen_name'), name=extra_data.get('name')) user.save() account = SocialAccount(user=user, uid=uid, provider=TwitterProvider.id, extra_data=extra_data) account.save() application = SocialApp.objects.get(secret=app.secret) sample_token = SocialToken.objects.filter(app=application, account=account) if sample_token: token = sample_token[0] else: token = SocialToken(app=application, account=account, token=request.session["oauth_api.twitter.com_access_token"]["oauth_token"], token_secret=request.session["oauth_api.twitter.com_access_token"][ "oauth_token_secret"]) token.save() mail = send_email_confirmation(request=request, user=user, signup=True) return SocialLogin(account=account, token=token, email_addresses=email_addresses)
def test_get_redir_user_demo(self): payload = {"user": {"username": self.demo["username"]}} self.client.login(username=payload["user"]["username"], password="******") sapp = SocialApp(provider='github', name='Github', client_id='<test>', secret='<test>') sapp.save() sacc = SocialAccount(uid=1001, user=self.test_user, provider="github") sacc.save() stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual(first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001") self.client.login(username=payload["user"]["username"], password="******") stoken = SocialToken(app=sapp, account=sacc, token="test_token") stoken.save() response = self.client.post('/accounts/profile', follow=True) first_url, first_response = response.redirect_chain[0] self.assertEqual(first_url, "/login?status=passed&token=test_token&username=testname&user_id=1001")