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) 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 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 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["access_token"]) token.user_data = {**data, **identity_data} return token
def _run_just_complete_login(self, resp_mock): """ Helper function for checking that Error cases are handled correctly. Running only `complete_login` means we can check that the specific erros are raised before they are caught and rendered to generic error HTML """ request = RequestFactory().get( reverse(self.provider.id + "_login"), {"process": "login"}, ) adapter = TwitchOAuth2Adapter(request) app = adapter.get_provider().get_app(request) token = SocialToken(token="this-is-my-fake-token") with mocked_response(resp_mock): adapter = TwitchOAuth2Adapter(request) adapter.complete_login(request, app, token)
def draugiem_complete_login(request, app, code): provider = providers.registry.by_id(DraugiemProvider.id, request) response = requests.get(ACCESS_TOKEN_URL, { 'action': 'authorize', 'app': app.secret, 'code': code }) response.raise_for_status() response_json = response.json() if 'error' in response_json: raise DraugiemApiError(response_json['error']) token = SocialToken(app=app, token=response_json['apikey']) login = provider.sociallogin_from_response(request, response_json) login.token = token return login
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, 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 test_callback(self): with patch('allauth.socialaccount.providers.draugiem.views' '.draugiem_complete_login') as draugiem_complete_login: self.mock_socialaccount_state() response_json = self.get_draugiem_login_response() token = SocialToken(app=self.app, token=response_json['apikey']) login = self.get_socialaccount(response_json, token) draugiem_complete_login.return_value = login response = self.client.get(reverse(views.callback), { 'dr_auth_status': 'ok', 'dr_auth_code': '42' }) self.assertRedirects(response, '/accounts/profile/', fetch_redirect_response=False)
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 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 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 OAuthError as e: raise serializers.ValidationError(str(e)) if not login.is_existing: login.lookup() login.save(request, connect=True) attrs['user'] = login.account.user return attrs
def draugiem_complete_login(request, app, code): provider = providers.registry.by_id(DraugiemProvider.id, request) response = requests.get( ACCESS_TOKEN_URL, { "action": "authorize", "app": app.secret, "code": code }, ) response.raise_for_status() response_json = response.json() if "error" in response_json: raise DraugiemApiError(response_json["error"]) token = SocialToken(app=app, token=response_json["apikey"]) login = provider.sociallogin_from_response(request, response_json) login.token = token return login
def parse_token(self, data): token = SocialToken(token=data["access_token"]) token.token_secret = data.get("refresh_token", "") public_key = self.get_public_key(data["id_token"]) provider = self.get_provider() client_id = self.get_client_id(provider) token.user_data = jwt.decode( data["id_token"], public_key, algorithm="RS256", verify=True, audience=client_id, ) token.user_data["first_name"] = data.get("first_name", "") token.user_data["last_name"] = data.get("last_name", "") 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 test_callback(self): with patch("allauth.socialaccount.providers.draugiem.views" ".draugiem_complete_login") as draugiem_complete_login: self.mock_socialaccount_state() response_json = self.get_draugiem_login_response() token = SocialToken(app=self.app, token=response_json["apikey"]) login = self.get_socialaccount(response_json, token) draugiem_complete_login.return_value = login response = self.client.get( reverse(views.callback), { "dr_auth_status": "ok", "dr_auth_code": "42" }, ) self.assertRedirects(response, "/accounts/profile/", fetch_redirect_response=False)
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 login(self, request): try: original_request = request._request token = request.POST.get(self.token_key, '') google_auth_adapter = GoogleOAuth2Adapter(request=original_request) app = SocialApp.objects.get(provider=self.provider) social_auth_token = SocialToken(app=app, token=token) login = google_auth_adapter.complete_login(request=original_request, app=app, token=social_auth_token) \ if self.provider is 'google' else fb_complete_login(request=request, app=app, token=social_auth_token) extra_data = login.account.extra_data json_error_response = None if 'email' not in extra_data: json_error_response = JsonResponse( dict(message='email is not provided'), status=400) if json_error_response is not None: return json_error_response user = User.objects.filter(email=extra_data['email']).first() if user is not None: token, is_created = Token.objects.get_or_create(user=user) return JsonResponse(dict(key=token.key)) login.token = social_auth_token login.state = SocialLogin.state_from_request(original_request) complete_social_login(original_request, login) token, is_created = Token.objects.get_or_create( user=original_request.user) return JsonResponse(dict(key=token.key)) except HTTPError as e: return JsonResponse(dict(message=str(e)), status=400)
def test_google_compelete_login_401(self): from allauth.socialaccount.providers.google.views import ( GoogleOAuth2Adapter, ) 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 = GoogleOAuth2Adapter(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.google.views" ".requests" ) as patched_requests: patched_requests.get.return_value = response_with_401 with self.assertRaises(HTTPError): adapter.complete_login(request, app, token)
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 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): """Validate social login user.""" 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 if 'account_type' in attrs: account_type = attrs.get('account_type') else: account_type = 'talent' try: login, response = CustomSocialLoginSerializer.get_social_login( self, adapter, app, token, access_token, account_type) # Temp fix because twitter response email is not coming. if login.user.email == '': login.user.email = None complete_social_login(request, login, response) except HTTPError: raise serializers.ValidationError('Incorrect value') if not login.is_existing: login.lookup() login.save(request, connect=True) data = RegisterSerializer().validate_account_type( account_type=account_type) user_account_type = list(data.values())[0] try: temp_user = login.account.user.person typ, created = PersonType.objects.get_or_create( person_type=user_account_type) except User.DoesNotExist: temp_user = login.account.user.company typ, created = CompanyType.objects.get_or_create( company_type=user_account_type) temp_user.typ.add(typ) referral = create_referral(temp_user) temp_user.referral = referral # provide incentive to user who referred this user. request = self.context.get('request') if request and 'referral_code' in request.data: referrer_user = get_referrer_user(request, user=temp_user) attrs['user'] = login.account.user return attrs
def login_user(request): try: req_body = json.loads(request.body.decode()) if request.method == 'POST': user = request.user is_authenticated = user_is_authenticated(user) id_token = json.loads(req_body['id_token']) if user.email == req_body['email'] and user.auth0_identifier.split('.')[1] == id_token['sub'].split('|')[1] and is_authenticated: # email = req_body['email'] # password = user.auth0_identifier.split('.')[1] password = id_token['sub'].split('|')[1] auth0_identifier = req_body['uid'] auth0_uid = auth0_identifier.replace("|", ".") authenticated_user = authenticate(auth0_identifier=auth0_uid, password=password) if authenticated_user is not None: remote_user_auth = request.successful_authenticator.authenticate(request) if remote_user_auth is not None: management_api_oauth_endpoint_result = management_api_oath_endpoint(AUTH0_DOMAIN) management_api_token = json.loads(management_api_oauth_endpoint_result) management_api_jwt = management_api_token['access_token'] management_api_user = get_management_api_user(AUTH0_DOMAIN, management_api_jwt, req_body['uid']) user_django_token = TokenModel.objects.get(user=authenticated_user) social_user = authenticated_user.social_auth.get(provider='auth0') remote_authenticated_user = remote_user_auth[0] if user_django_token is not None: token = user_django_token else: token = TokenModel.objects.create(user=authenticated_user) key = token.key extra_data = req_body['extra_data'] extra_data['access_token'] = remote_user_auth[1] extra_data['id_token__raw'] = id_token['__raw'] nonce = id_token['nonce'] exp = id_token['exp'] iat = id_token['iat'] connection = management_api_user.get('identities')[0] assoc_type = connection.get('connection') provider = social_user.provider if 'csrf_token' in req_body and req_body['csrf_token']: csrf = req_body['csrf_token'] else: csrf = get_token(request) # is_active = user_is_active(authenticated_user) account_email = EmailAddress.objects.get(user_id=remote_authenticated_user.id) user_social_auth = UserSocialAuth.objects.get(user_id=remote_authenticated_user.id) social_account = SocialAccount.objects.get(user_id=remote_authenticated_user.id) social_app = SocialApp.objects.get_or_create( provider=provider, name="Quantum Coasters", secret=SOCIAL_AUTH_AUTH0_SECRET, client_id=AUTH0_CLIENT_ID, key=SOCIAL_AUTH_AUTH0_KEY ) time_now = datetime.datetime.now() # social_token = SocialToken.objects.get_or_create( # account=social_account, # token=user_social_auth.access_token, # token_secret=user_social_auth.tokens, # expires_at = time_now + datetime.timedelta(0, exp), # app = social_app[0] # ) social_token = SocialToken.objects.get(account_id=social_account.id) if SocialToken.objects.filter(account_id=social_account.id).exists() else SocialToken(account=social_account) social_token.token = user_social_auth.access_token social_token.token_secret = user_social_auth.tokens time_now = datetime.datetime.now() expires_at = time_now + datetime.timedelta(0, exp) social_token.expires_at = expires_at social_token.app = social_app[0] social_token.save() # login user, then grab the credentials and newly created session which is going to be called and returned after login. login(request, social_user.user, backend='quantumapi.auth0_backend.Auth0') try: session_user = request.session is_session = Session.objects.filter(session_key=session_user.session_key).exists() if is_session: session = Session.objects.get(session_key=session_user.session_key) # decoded_session = session.get_decoded() # session.save() else: session = Session.objects.create(user=remote_authenticated_user) # session.save() # Get the most recent entry on Credentials, which would have just posted/ updated # from the user logging in thru auth0. (In App.js and Auth0Context) has_credentials = Credential.objects.filter(user_id=authenticated_user.id).exists() credentials = Credential.objects.filter(user_id=authenticated_user.id).latest() if has_credentials else None # To break login... # credentials = Credential.objects.get(user_id=authenticated_user.id) if credentials is not None: # all_transactions = json.loads(credentials.transactions) # transaction_items_keys = all_transactions['transactions'].keys() # transactions_values = all_transactions['transactions'].values() # codes = [c for c in transaction_items_keys] # transactions = [t for t in transactions_values] #handles = [handle for handle in codes] if len(codes) > 0 else {} #code_verifiers = [code['code_verifier'] for code in transactions] if len(transactions) > 0 else {} # handle = transactions[0]['nonce'] if len(transactions) > 0 else {} # code_verifier = transactions[0]['code_verifier'] if len(transactions) > 0 else {} code_verifier = retrieve_user_logs(AUTH0_DOMAIN, management_api_jwt, req_body['uid']) seacft = [l for l in code_verifier if l['type'] == 'seacft'] seacft_details = seacft[0].get('details') code = seacft_details.get('code') #all_backends = backends(request) #user_backends = all_backends.get('backends') #auth0_backend = user_backends['backends'][1] #openId_backend = user_backends['backends'][0] #user_assoc_backends = user_backends.get('associated') if Association.objects.filter(server_url=AUTH0_OPEN_ID_SERVER_URL, handle=nonce).exists(): Association.objects.get(server_url=AUTH0_OPEN_ID_SERVER_URL, handle=nonce) else: Association.objects.create(server_url=AUTH0_OPEN_ID_SERVER_URL, handle=nonce, secret=code, issued=iat, lifetime=exp, assoc_type=assoc_type) auth_user = { "valid": True, "id": user.id, "first_name": user.first_name, "last_name": user.last_name, "email": user.email, "username": user.username, "auth0_identifier": user.auth0_identifier, "QuantumToken": key, "accessToken": remote_user_auth[1], "management_api_token": management_api_token, "session": session.session_key, "csrf": csrf, "user_social_auth": user_social_auth.id, "account_email": account_email.id, "management_user": management_api_user, "social_account": social_account.id, "social_app": social_app[0].id, "email_confirmation": True, "has_credentials": True, "credentials_id": credentials.id, # "user_profile_id": user.user_id, } data = json.dumps(auth_user) return HttpResponse(data, content_type='application/json') else: auth_user = { "valid": True, "id": user.id, "first_name": user.first_name, "last_name": user.last_name, "email": user.email, "username": user.username, "auth0_identifier": user.auth0_identifier, "QuantumToken": key, "accessToken": remote_user_auth[1], "management_api_token": management_api_token, "session": session.session_key, "csrf": csrf, "user_social_auth": user_social_auth.id, "account_email": account_email.id, "management_user": management_api_user, "social_account": social_account.id, "social_app": social_app[0].id, "email_confirmation": True, "has_credentials": False, # "user_profile_id": user.user_id, } data = json.dumps(auth_user) return HttpResponse(data, content_type='application/json') except Exception as ex: return Response({'Final data Validation Error': ex.args}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: data = json.dumps({"valid": False, "Error": 'Remote User un authenticated or None.'}) return HttpResponse(data, content_type='application/json', status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: data = json.dumps({"valid": False, "Error": 'Unable to Authenticate Credentials'}) return HttpResponse(data, content_type='application/json', status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: data = json.dumps({"valid": False, "Message": 'Email did not match email we have for this accout.'}) return HttpResponse(data, content_type='application/json', status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: data = json.dumps({"valid": False, "Error": 'Unable to Authenticate Credentials'}) return HttpResponse(data, content_type='application/json', status=status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as ex: return Response(ex, status=status.HTTP_500_INTERNAL_SERVER_ERROR)