def perform_create(self, serializer): user = serializer.save() if serializer.validated_data.get('access_token'): self.request.social_strategy = load_strategy(self.request) if not hasattr(self.request, 'strategy'): self.request.strategy = self.request.social_strategy self.request.backend = load_backend(self.request.social_strategy, "facebook", reverse("accounts:token-auth")) self.request.social_strategy = load_strategy(self.request) self.request.backend = load_backend(self.request.social_strategy, 'facebook', None) self.request.backend.do_auth(serializer.validated_data.get("access_token"), None, user=user, is_new=True) return user
def social_login(request): """ Returns two-tuple of (user, token) if authentication succeeds, or None otherwise. """ token = request.DATA.get('access_token', None) backend = request.DATA.get('backend', None) strategy = load_strategy(request=request) try: backend = load_backend(strategy, backend, reverse(NAMESPACE + ":complete", args=(backend,))) except MissingBackend: msg = 'Invalid token header. Invalid backend.' return Response(str(msg), status=400) try: user = backend.do_auth(access_token=token) except requests.HTTPError as e: msg = e.response.text return Response(str(msg), status=400) if not user: msg = 'Bad credentials.' return Response(str(msg), status=400) login(request, user) serialized = AccountSerializer(user) return Response(serialized.data, status=status.HTTP_200_OK )
def register_by_access_token(request, backend): uri='' strategy = load_strategy(request) backend = load_backend(strategy, backend, uri) # Split by spaces and get the array auth = get_authorization_header(request).split() if not auth: msg= 'No auth provided' return msg if not auth or auth[0].lower() != b'bearer': msg = 'No token header provided.' return msg if len(auth) == 1: msg = 'Invalid token header. No credentials provided.' return msg access_token = auth[1].decode(encoding='UTF-8') user = backend.do_auth(access_token) return user
def get_request_and_strategy(self, auth_entry=None, redirect_uri=None): """Gets a fully-configured request and strategy. These two objects contain circular references, so we create them together. The references themselves are a mixture of normal __init__ stuff and monkey-patching done by python-social-auth. See, for example, social.apps.django_apps.utils.strategy(). """ request = self.request_factory.get( pipeline.get_complete_url(self.backend_name) + '?redirect_state=redirect_state_value&code=code_value&state=state_value' ) request.user = auth_models.AnonymousUser() request.session = cache.SessionStore() request.session[self.backend_name + '_state'] = 'state_value' if auth_entry: request.session[pipeline.AUTH_ENTRY_KEY] = auth_entry strategy = social_utils.load_strategy(request=request) request.social_strategy = strategy request.backend = social_utils.load_backend(strategy, self.backend_name, redirect_uri) return request, strategy
def register_by_access_token(request, *args, **kwargs): # TODO: make me pretty, decorator? api_view # LD: looks fine :) # print request.META social_serializer = SocialTokenSerializer(data=request.data) social_serializer.is_valid(raise_exception=True) try: # TODO: this is really bad! client_id, client_secret = _get_client_id_and_secret(request) try: app = Application.objects.get(client_id=client_id) except ObjectDoesNotExist: return Response({"errors": ["client_id doesn't exist"]}, status=status.HTTP_400_BAD_REQUEST) data = social_serializer.data strategy = load_strategy(request) backend = load_backend(strategy, data['backend'], None) user = backend.do_auth(data['social_token']) if user: if not user.last_login: login(request, user) serializer = UserSerializer(user, context={'request': request}) returned_json = { 'user': serializer.data, 'token': get_access_token(user, app) } return JsonResponse({'data': returned_json}) else: return Response({"errors": ["user already registered"]}, status=status.HTTP_400_BAD_REQUEST) else: return _facebook_login_error("after token user is none") except HTTPError as e: return _facebook_login_error(e.message + " when connecting to " + data['backend'])
def setUp(self): super(AccessTokenExchangeFormTest, self).setUp() self.request = RequestFactory().post("dummy_url") redirect_uri = 'dummy_redirect_url' SessionMiddleware().process_request(self.request) self.request.social_strategy = social_utils.load_strategy(self.request) # pylint: disable=no-member self.request.backend = social_utils.load_backend(self.request.social_strategy, self.BACKEND, redirect_uri)
def setUp(self): super(AccessTokenExchangeFormTest, self).setUp() self.request = RequestFactory().post("dummy_url") redirect_uri = 'dummy_redirect_url' SessionMiddleware().process_request(self.request) self.request.social_strategy = social_utils.load_strategy(self.request) # pylint: disable=no-member self.request.backend = social_utils.load_backend( self.request.social_strategy, self.BACKEND, redirect_uri)
def post(self, request): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): backend = serializer.data['backend'] access_token = serializer.data['access_token'] jwt = serializer.data.get('jwt_token', None) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 讀取python-social-auth strategy strategy = load_strategy(request=request) backend = load_backend(strategy, backend, 'next') try: kwargs = dict({(k, i) for k, i in serializer.data.items() if k != 'backend'}) if jwt: # Get user from provided jwt try: payload = jwt_decode_handler(jwt) user = User.objects.get(id=payload['user_id']) if user.is_authenticated(): kwargs['user'] = user else: raise Exception('not authenticated') except: kwargs['user'] = None pass user = backend.do_auth(**kwargs) except AuthAlreadyAssociated: data = { 'error_code': 'social_already_associated', 'status': 'Auth associated with another user.', } return Response(data, status=status.HTTP_403_FORBIDDEN) if not user: data = { 'error_code': 'social_no_user', 'status': 'No associated user.', } return Response(data, status=status.HTTP_403_FORBIDDEN) if not user.is_active: data = { 'error_code': 'social_inactive', 'status': 'Associated user is inactive.' } return Response(data, status=status.HTTP_403_FORBIDDEN) payload = jwt_payload_handler(user) return Response({'token': jwt_encode_handler(payload), 'username': user.username}) # 回傳JWT token及使用者帳號
def create(self, request, *args, **kwargs): """ Override `create` instead of `perform_create` to access request request is necessary for `load_strategy` """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) provider = request.data['provider'] # If this request was made with an authenticated user, try to associate this social account with it authed_user = request.user if not request.user.is_anonymous() else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): token = { 'oauth_token': request.data['access_token'], 'oauth_token_secret': request.data['access_token_secret'], } elif isinstance(backend, BaseOAuth2): token = request.data['access_token'] try: user = backend.do_auth(token, user=authed_user) except AuthAlreadyAssociated: return Response( {"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user and user.is_active: # if the access token was set to an empty string, then save the access token from the request auth_created = user.social_auth.get(provider=provider) if not auth_created.extra_data['access_token']: auth_created.extra_data['access_token'] = token auth_created.save() # Allow client to send up password to complete auth flow if not authed_user and 'password' in request.data: password = base64.decodestring(request.data['password']) user.set_password(password) user.save() # Set instance since we are not calling `serializer.save()` serializer.instance = user headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): provider = request.data['provider'] # If this request was made with an authenticated user, try to associate this social # account with it authed_user = request.user if not request.user.is_anonymous() else None # `strategy` is a python-social-auth concept referencing the Python framework to # be used (Django, Flask, etc.). By passing `request` to `load_strategy`, PSA # knows to use the Django strategy strategy = load_strategy(request) # Now we get the backend that corresponds to our user's social auth provider # e.g., Facebook, Twitter, etc. backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): # Twitter, for example, uses OAuth1 and requires that you also pass # an `oauth_token_secret` with your authentication request token = { 'oauth_token': request.data['access_token'], 'oauth_token_secret': request.data['access_token_secret'], } elif isinstance(backend, BaseOAuth2): # We're using oauth's implicit grant type (usually used for web and mobile # applications), so all we have to pass here is an access_token token = request.data['access_token'] try: # if `authed_user` is None, python-social-auth will make a new user, # else this social account will be associated with the user you pass in user = backend.do_auth(token, user=authed_user) login(request, user) except AuthAlreadyAssociated: # You can't associate a social account with more than user return Response({"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user and user.is_active: # if the access token was set to an empty string, then save the access token # from the request auth_created = user.social_auth.get(provider=provider) if not auth_created.extra_data['access_token']: # Facebook for example will return the access_token in its response to you. # This access_token is then saved for your future use. However, others # e.g., Instagram do not respond with the access_token that you just # provided. We save it here so it can be used to make subsequent calls. auth_created.extra_data['access_token'] = token auth_created.save() return get_access_token(user) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): if 'backend' not in request.data: return Response({"errors": 'Specify backend type'}, status=status.HTTP_400_BAD_REQUEST) elif request.data['backend'] != 'google': return Response({"errors": 'Wrong backend type'}, status=status.HTTP_400_BAD_REQUEST) else: provider = GOOGLE_PROVIDER if 'access_token' not in request.data or not request.data[ 'access_token']: return Response({"errors": 'Access_token is not provided'}, status=status.HTTP_400_BAD_REQUEST) authed_user = request.user if not request.user.is_anonymous() else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) token = request.data['access_token'] is_new = False try: user = backend.do_auth(token, user=authed_user) is_new = user.is_new except AuthAlreadyAssociated: return Response( {"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) except HTTPError: try: user = User.objects.get(token=token) user.social_auth.get(provider=provider).refresh_token(strategy) except: return Response({"errors": "Unauthorized token for url"}, status=status.HTTP_403_FORBIDDEN) if user and user.is_active: auth_created = user.social_auth.get(provider=provider) if auth_created.access_token != user.token: user.token = auth_created.access_token user.save() resp = {'token': user.token, 'is_new': is_new, 'user_id': user.id} serializer = self.get_serializer(data=resp) serializer.is_valid(raise_exception=True) headers = self.get_success_headers(serializer.data) status_response = status.HTTP_201_CREATED if is_new else status.HTTP_200_OK return Response(serializer.data, status=status_response, headers=headers) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST)
def auth_by_token(request, backend): uri = '' strategy = load_strategy(request) backend = load_backend(strategy, backend, uri) user = request.user user = backend.do_auth( access_token=request.data.get('access_token'), user=user.is_authenticated() and user or None ) if user and user.is_active: return user# Return anything that makes sense here else: return None
def register_by_access_token(request, backend): uri = '' strategy = load_strategy(request) backend = load_backend(strategy, backend, uri) # Split by spaces and get the array if request.data['accessToken'] is None: msg = 'No access token provided.' return msg else: access_token = request.data['accessToken'] # Real authentication takes place here user = backend.do_auth(access_token) return user
def create(self, request, *args, **kwargs): """ Override `create` instead of `perform_create` to access request request is necessary for `load_strategy` """ serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) provider = request.data['provider'] # If this request was made with an authenticated user, try to associate this social account with it authed_user = request.user if not request.user.is_anonymous() else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): token = { 'oauth_token': request.data['access_token'], 'oauth_token_secret': request.data['access_token_secret'], } elif isinstance(backend, BaseOAuth2): token = request.data['access_token'] try: user = backend.do_auth(token, user=authed_user) except AuthAlreadyAssociated: return Response({"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user and user.is_active: # if the access token was set to an empty string, then save the access token from the request auth_created = user.social_auth.get(provider=provider) if not auth_created.extra_data['access_token']: auth_created.extra_data['access_token'] = token auth_created.save() # Allow client to send up password to complete auth flow if not authed_user and 'password' in request.data: password = base64.decodestring(request.data['password']) user.set_password(password) user.save() # Set instance since we are not calling `serializer.save()` serializer.instance = user headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST)
def do_auth(oauth_token): strategy = load_strategy() path = NAMESPACE + ":complete" backend = 'github' backend = load_backend(strategy, backend, reverse(path, args=(backend,))) try: user = backend.do_auth(access_token=oauth_token) except requests.HTTPError as e: raise AuthenticationFailed(e.response.json()) if not user: raise AuthenticationFailed('Bad credentials') social = user.social_auth.get(provider='github') social.extra_data['access_token'] = oauth_token social.save() return user
def saml_metadata_view(request): """ Get the Service Provider metadata for this edx-platform instance. You must send this XML to any Shibboleth Identity Provider that you wish to use. """ if not SAMLConfiguration.is_enabled(): raise Http404 complete_url = reverse('social:complete', args=("tpa-saml", )) if settings.APPEND_SLASH and not complete_url.endswith('/'): complete_url = complete_url + '/' # Required for consistency saml_backend = load_backend(load_strategy(request), "tpa-saml", redirect_uri=complete_url) metadata, errors = saml_backend.generate_metadata_xml() if not errors: return HttpResponse(content=metadata, content_type='text/xml') return HttpResponseServerError(content=', '.join(errors))
def social_register(request): auth_token = request.data.get('access_token', None) backend = request.data.get('backend', None) if auth_token and backend: try: user = auth_by_token(request, backend) except Exception, err: return Response(str(err), status=400) if user: uri = '' strategy = load_strategy(request) backend = load_backend(strategy, backend, uri) _do_login(backend , user, strategy) return Response( "User logged in", status=status.HTTP_200_OK ) else: return Response("Bad Credentials", status=403)
def get(self, request, *args, **kwargs): from social.apps.django_app.utils import load_backend, load_strategy complete_url = reverse('social:complete', args=('saml', )) saml_backend = load_backend( load_strategy(request), 'saml', redirect_uri=complete_url, ) try: metadata, errors = saml_backend.generate_metadata_xml() except Exception as e: logger.exception('unable to generate SAML metadata') errors = e if not errors: return HttpResponse(content=metadata, content_type='text/xml') else: return HttpResponse(content=str(errors), content_type='text/plain')
def authenticate(self, request): """ Returns two-tuple of (user, token) if authentication succeeds, or None otherwise. """ auth_header = get_authorization_header(request).decode( HTTP_HEADER_ENCODING) auth = auth_header.split() if not auth or auth[0].lower() != 'bearer': return None if len(auth) == 1: msg = 'Invalid token header. No backend provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) == 2: msg = 'Invalid token header. No credentials provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) > 3: msg = 'Invalid token header. Token string should not contain spaces.' raise exceptions.AuthenticationFailed(msg) token = auth[2] backend = auth[1] strategy = load_strategy(request=request) try: backend = load_backend( strategy, backend, reverse(SOCIAL_AUTH_NAMESPACE + ':complete', args=(backend, ))) except MissingBackend: msg = 'Invalid token header. Invalid backend.' raise exceptions.AuthenticationFailed(msg) try: user = backend.do_auth(access_token=token) except requests.HTTPError as e: msg = e.response.text raise exceptions.AuthenticationFailed(msg) if not user: msg = 'Bad credentials.' raise exceptions.AuthenticationFailed(msg) return user, token
def signin_by_access_token(request, backend): auth_token = request.GET.get('access_token') backend = load_backend(load_strategy(request=request), backend, None) response = { 'status': False, } try: user = backend.do_auth(auth_token) if user: login(request, user) response.update({'status': True}) response.update(dict(user={'id': user.id})) except Exception: pass return HttpResponse(json.dumps(response), content_type='application/json')
def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.DATA, files=request.FILES) if serializer.is_valid(): self.pre_save(serializer.object) provider = request.DATA['provider'] # If this request was made with an authenticated user, try to associate this social account with it authed_user = request.user if not request.user.is_anonymous( ) else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): token = { 'oauth_token': request.DATA['access_token'], 'oauth_token_secret': request.DATA['access_token_secret'], } elif isinstance(backend, BaseOAuth2): token = request.DATA['access_token'] user = backend.do_auth(token, user=authed_user) serializer.object = user if user and user.is_active: if not authed_user and request.DATA['password']: password = base64.decodestring(request.DATA['password']) user.set_password(password) user.save() self.post_save(serializer.object, created=True) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, *args, **kwargs): """ :param request:here we get post request with access token :return:this function use that access token and authenticate with backend and create a user and return response code 201 for created """ try: provider = 'google-oauth2' authed_user = request.user if not request.user.is_anonymous else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): token = { 'oauth_token': request.data['access_token'], 'oauth_token_secret': request.data['access_token_secret'], } elif isinstance(backend, BaseOAuth2): token = request.data['access_token'] try: user = backend.do_auth(token, user=authed_user) except AuthAlreadyAssociated: return Response( {"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user and user.is_active: return Response('logged in', status=status.HTTP_201_CREATED) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST) except Exception: smd = Smd_Response() return smd
def authenticate(self, request): """ Returns two-tuple of (user, token) if authentication succeeds, or None otherwise. """ auth_header = get_authorization_header(request).decode(HTTP_HEADER_ENCODING) auth = auth_header.split() if not auth or auth[0].lower() != 'bearer': return None if len(auth) == 1: msg = 'Invalid token header. No backend provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) == 2: msg = 'Invalid token header. No credentials provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) > 3: msg = 'Invalid token header. Token string should not contain spaces.' raise exceptions.AuthenticationFailed(msg) token = auth[2] backend = auth[1] strategy = load_strategy(request=request) try: backend = load_backend(strategy, backend, reverse(NAMESPACE + ":complete", args=(backend,))) except MissingBackend: msg = 'Invalid token header. Invalid backend.' raise exceptions.AuthenticationFailed(msg) try: user = backend.do_auth(access_token=token) except requests.HTTPError as e: msg = e.response.text raise exceptions.AuthenticationFailed(msg) if not user: msg = 'Bad credentials.' raise exceptions.AuthenticationFailed(msg) return user, token
def create(self, validated_data): backend = 'facebook' redirect_uri = reverse('social:complete', args=(backend,)) social_strategy = load_strategy(self.context['request']) backend = load_backend(social_strategy, backend, redirect_uri) backend.invite_code = validated_data.get('invite_code') try: user = backend.do_auth(validated_data['token']) except SocialAuthBaseException as ex: raise serializers.ValidationError({'non_field_errors': str(ex)}) except HTTPError as ex: logger.info('Invalid access token: %s', ex.response.json()) raise serializers.ValidationError({'access_token': 'Invalid access token'}) if user: return Token.objects.get_or_create(user=user)[0] else: logger.info('Unkown reason for social auth failure') raise serializers.ValidationError({'non_field_errors': ['Something went wrong.']})
def social_sign_up(request): data = {} status = 400 try: provider = request.data['provider'] a_user = request.user if not request.user.is_anonymous() else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): access_token = { 'oauth_token': request.data['access_token'], 'oauth_token_secret': request.data['access_token_secret'], } else: # We assume that if our backend is not instance of BaseOAuth1, # it is instance of BaseOAuth2 access_token = request.data['access_token'] user = backend.do_auth(access_token, user=a_user) if user and user.is_active: social = user.social_auth.get(provider=provider) if social.extra_data['access_token']: social.extra_data['access_token'] = access_token social.save() login(request, user) token = Token.objects.get(user=user) data = {'username': user.username, 'id': user.id, 'token': token.key} status = 200 except KeyError as k: data['detail'] = ['{} parameter is missed'.format(k)] except Exception as exc: data['detail'] = [str(exc)] finally: return Response(data, status=status)
def authenticate(self, request): """ Returns two-tuple of (user, token) if authentication succeeds, or None otherwise. """ auth = get_authorization_header(request).split() if not auth or auth[0].lower() != b'bearer': return None if len(auth) == 1: msg = 'Invalid token header. No backend provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) == 2: msg = 'Invalid token header. No credentials provided.' raise exceptions.AuthenticationFailed(msg) elif len(auth) > 3: msg = 'Invalid token header. Token string should not contain spaces.' raise exceptions.AuthenticationFailed(msg) token = auth[2] backend = auth[1] strategy = load_strategy(request=request) try: backend = load_backend(strategy, backend, reverse(NAMESPACE + ":complete", args=(backend,))) except MissingBackend: msg = 'Invalid token header. Invalid backend.' raise exceptions.AuthenticationFailed(msg) user = backend.do_auth(access_token=token) if not user: msg = 'Bad credentials.' raise exceptions.AuthenticationFailed(msg) return user, token
def facebook(self, request): serializer = HunterFacebookSerializer(data=request.data) serializer.is_valid(raise_exception=True) psa_backend = 'facebook' access_token = serializer.data['access_token'] redirect_uri = reverse('social:complete', args=(psa_backend,)) social_strategy = load_strategy(request) psa_backend = load_backend(social_strategy, psa_backend, redirect_uri) try: user = psa_backend.do_auth(access_token) except SocialAuthBaseException as ex: return Response({'non_field_errors': [str(ex)]}, status=status.HTTP_400_BAD_REQUEST) except HTTPError as ex: logger.info('Invalid access token. %s', ex.response.json()) return Response({'access_token': ['Invalid access token']}, status=status.HTTP_400_BAD_REQUEST) if user: return Response({'token': TimedAuthToken.objects.create(user=user).key}) else: logger.info('Unkown reason for social auth failure') return Response({'non_field_errors': ['Something went wrong.']}, status=status.HTTP_400_BAD_REQUEST)
def get_request_and_strategy(self, auth_entry=None, redirect_uri=None): """Gets a fully-configured request and strategy. These two objects contain circular references, so we create them together. The references themselves are a mixture of normal __init__ stuff and monkey-patching done by python-social-auth. See, for example, social.apps.django_apps.utils.strategy(). """ request = self.request_factory.get( pipeline.get_complete_url(self.backend_name) + '?redirect_state=redirect_state_value&code=code_value&state=state_value') request.user = auth_models.AnonymousUser() request.session = cache.SessionStore() request.session[self.backend_name + '_state'] = 'state_value' if auth_entry: request.session[pipeline.AUTH_ENTRY_KEY] = auth_entry strategy = social_utils.load_strategy(request=request) request.social_strategy = strategy request.backend = social_utils.load_backend(strategy, self.backend_name, redirect_uri) return request, strategy
def social_register(request): auth_token = request.data.get('access_token', None) backend = request.data.get('backend', None) if auth_token and backend: try: user = auth_by_token(request, backend) except Exception, err: return Response(str(err), status=400) if user: strategy = load_strategy(request) uri = '' backend = load_backend(strategy, backend, uri) _do_login(backend, user, strategy) print("apunto de salir") pdb.set_trace() data = { 'name': user.username, 'id': user.id, 'status': user.status } return Response(data, status=status.HTTP_200_OK) else: return Response("Bad Credentials", status=403)
def social_login(request): """View function for handling fb authentication.""" if request.method == 'POST': access_token = request.data['accessToken'] backend = request.data['backend'] if access_token: strategy = load_strategy(request) backend = load_backend( strategy=strategy, name=backend, redirect_uri=None) try: user = backend.do_auth(access_token) except AuthAlreadyAssociated: return Response( {"errors": "This social account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user: login(request, user) return Response( {'user': user.username}, status=status.HTTP_200_OK) else: return Response("Bad credentials", status=403) else: return Response("Bad request", status=400)
def social_register(request): """Viewset for handling facebook authentication""" if request.method == 'POST': auth_token = request.data['access_token'] backend = request.data['backend'] if auth_token and backend: strategy = load_strategy(request) backend = load_backend( strategy=strategy, name=backend, redirect_uri=None) # do backend authentication and check if account is already associated try: user = backend.do_auth(auth_token) except AuthAlreadyAssociated: return Response({"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) # if a user has been created log the user in if user: login(request, user) return Response( {'user' : user.username}, status=status.HTTP_200_OK ) else: return Response("Bad Credentials", status=403) else: return Response("Bad request", status=400)
def social_login(request): """View function for handling fb authentication.""" if request.method == 'POST': access_token = request.data['accessToken'] backend = request.data['backend'] if access_token: strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=backend, redirect_uri=None) try: user = backend.do_auth(access_token) except AuthAlreadyAssociated: return Response( {"errors": "This social account is already in use"}, status=status.HTTP_400_BAD_REQUEST) if user: login(request, user) return Response({'user': user.username}, status=status.HTTP_200_OK) else: return Response("Bad credentials", status=403) else: return Response("Bad request", status=400)
def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.DATA, files=request.FILES) if serializer.is_valid(): self.pre_save(serializer.object) provider = request.DATA['provider'] # If this request was made with an authenticated user, try to associate this social account with it authed_user = request.user if not request.user.is_anonymous() else None strategy = load_strategy(request) backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) if isinstance(backend, BaseOAuth1): token = { 'oauth_token': request.DATA['access_token'], 'oauth_token_secret': request.DATA['access_token_secret'], } elif isinstance(backend, BaseOAuth2): token = request.DATA['access_token'] user = backend.do_auth(token, user=authed_user) serializer.object = user if user and user.is_active: if not authed_user and request.DATA['password']: password = base64.decodestring(request.DATA['password']) user.set_password(password) user.save() self.post_save(serializer.object, created=True) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def post(self, request): """ POST /api/tams_api/accounts email, username, name, uid """ # Only superusers can create an account if not request.user.is_superuser: return Response(status=status.HTTP_403_FORBIDDEN) data = request.POST.copy() email = data.get('email') # Handle duplicate email conflicts = check_account_exists(email=email) if conflicts: errorMsg = " and ".join(conflicts) return Response({ 'code': status.HTTP_409_CONFLICT, 'message': "{} already used for another account.".format(errorMsg) }, status=status.HTTP_409_CONFLICT) redirect_uri = '' backend_name = 'azuread-oauth2' request.social_strategy = social_utils.load_strategy(request) request.backend = social_utils.load_backend(request.social_strategy, backend_name, redirect_uri) username = get_username(strategy=request.social_strategy, details=data) data["username"] = username['username'] data["honor_code"] = True; data["terms_of_service"] = True; try: user = create_user_account(request, data) except AccountValidationError as err: return Response({ 'code': status.HTTP_400_BAD_REQUEST, 'field': [{"user_message": err.message}] }, status=status.HTTP_400_BAD_REQUEST) except ValidationError as err: errors = { 'field': [{"user_message": error} for error in error_list] for field, error_list in err.message_dict.items() } return Response(errors, status=status.HTTP_400_BAD_REQUEST) except AuthAlreadyAssociated as err: return Response({ 'code': status.HTTP_400_BAD_REQUEST, 'message': err.message }, status=status.HTTP_400_BAD_REQUEST) except TamsApiInternalError as err: return Response({ 'code': status.HTTP_500_INTERNAL_SERVER_ERROR, 'message': err.message }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) course_id = data.get('course_id') if course_id: try: username = user['username'] log.info("Enrolling course {} for user {}".format(course_id, username)) enrollment = create_user_enrollment(username, course_id) user['enrolledCourseId'] = enrollment['course_details']['course_id'] except Exception as err: log.error(err.message) return Response(user)
def post(self, request, *args, **kwargs): # request.POST bodge # The backend tries to get data from either request.POST # or request.GET. These are empty though as DRF uses # request.DATA. We need to assing request.POST. request._request.POST = request._request.POST.copy() for key, value in request.data.items(): request._request.POST[key] = value serializer = self.get_serializer(data=request.data) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) backend = serializer.data['backend'] uri = reverse('auth:complete', args=(backend,)) strategy = load_strategy(request=request._request) try: backend = load_backend(strategy, backend, uri) except MissingBackend: raise Http404('Backend not found') data = backend.strategy.request_data() user = request.user is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None partial = partial_pipeline_data(backend, user, *args, **kwargs) if partial: xargs, xkwargs = partial user = backend.continue_pipeline(*xargs, **xkwargs) else: user = backend.complete(user=user, *args, **kwargs) # pop redirect value before the session is trashed on login(), but after # the pipeline so that the pipeline can change the redirect if needed redirect_value = backend.strategy.session_get(REDIRECT_FIELD_NAME, '') or data.get(REDIRECT_FIELD_NAME, '') user_model = backend.strategy.storage.user.user_model() if user and not isinstance(user, user_model): return user if is_authenticated: if not user: url = setting_url(backend, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, redirect_value, 'NEW_ASSOCIATION_REDIRECT_URL', 'LOGIN_REDIRECT_URL') elif user: if user_is_active(user): # catch is_new/social_user in case login() resets the instance is_new = getattr(user, 'is_new', False) if is_new: url = setting_url(backend, 'NEW_USER_REDIRECT_URL', redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, 'INACTIVE_USER_URL', 'LOGIN_ERROR_URL', 'LOGIN_URL') return Response({ 'status': 'Unauthorized', 'message': 'The user account is disabled.', 'redirect_url': url }, status=status.HTTP_401_UNAUTHORIZED) else: url = setting_url(backend, 'LOGIN_ERROR_URL', 'LOGIN_URL') if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + '{0}={1}'.format(REDIRECT_FIELD_NAME, redirect_value) if backend.setting('SANITIZE_REDIRECTS', True): url = sanitize_redirect(backend.strategy.request_host(), url) or backend.setting('LOGIN_REDIRECT_URL') # Get the JWT payload for the user. payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return Response({ 'token': token, 'redirect_url': url })
def post(self, request, *args, **kwargs): # request.POST bodge # The backend tries to get data from either request.POST # or request.GET. These are empty though as DRF uses # request.DATA. We need to assing request.POST. request.POST = request.DATA serializer = self.get_serializer(data=request.DATA) if not serializer.is_valid(): return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) backend = serializer.data['backend'] uri = reverse('auth:complete', args=(backend, )) strategy = load_strategy(request=request) try: backend = load_backend(strategy, backend, uri) except MissingBackend: raise Http404('Backend not found') data = backend.strategy.request_data() user = request.user is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None partial = partial_pipeline_data(backend, user, *args, **kwargs) if partial: xargs, xkwargs = partial user = backend.continue_pipeline(*xargs, **xkwargs) else: user = backend.complete(user=user, *args, **kwargs) # pop redirect value before the session is trashed on login(), but after # the pipeline so that the pipeline can change the redirect if needed redirect_value = backend.strategy.session_get( REDIRECT_FIELD_NAME, '') or data.get(REDIRECT_FIELD_NAME, '') user_model = backend.strategy.storage.user.user_model() if user and not isinstance(user, user_model): return user if is_authenticated: if not user: url = setting_url(backend, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, redirect_value, 'NEW_ASSOCIATION_REDIRECT_URL', 'LOGIN_REDIRECT_URL') elif user: if user_is_active(user): # catch is_new/social_user in case login() resets the instance is_new = getattr(user, 'is_new', False) if is_new: url = setting_url(backend, 'NEW_USER_REDIRECT_URL', redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(backend, 'INACTIVE_USER_URL', 'LOGIN_ERROR_URL', 'LOGIN_URL') return Response( { 'status': 'Unauthorized', 'message': 'The user account is disabled.', 'redirect_url': url }, status=status.HTTP_401_UNAUTHORIZED) else: url = setting_url(backend, 'LOGIN_ERROR_URL', 'LOGIN_URL') if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + '{0}={1}'.format( REDIRECT_FIELD_NAME, redirect_value) if backend.setting('SANITIZE_REDIRECTS', True): url = sanitize_redirect( backend.strategy.request_host(), url) or backend.setting('LOGIN_REDIRECT_URL') # Get the JWT payload for the user. payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return Response({'token': token, 'redirect_url': url})
def social_signup(self, request, pk=None): """ Override `create` instead of `perform_create` to access request request is necessary for `load_strategy` """ provider = request.data.get('provider') if provider == 'skip': # TODO: create skip and none also as backend if request.user and not request.user.is_anonymous(): user = request.user else: data = dict(request.data) if not data.get('source') and request.META.get('HTTP_SOURCE'): data['source'] = Source.objects.filter( source=self.request.META.get('HTTP_SOURCE')).first() user = userManager.create_user(data) if user: token = user.get_drf_token() result = { 'token': token.key, 'user': userSerializer.UserSerializer( user, remove_fields=['referral', 'active_devices']).data } response = Response(result, status=status.HTTP_201_CREATED) else: response = Response(status=status.HTTP_403_FORBIDDEN) return response # If this request was made with an authenticated user, try to associate this social # account with it authed_user = request.user if not request.user.is_anonymous() else None # `strategy` is a python-social-auth concept referencing the Python framework to # be used (Django, Flask, etc.). By passing `request` to `load_strategy`, PSA # knows to use the Django strategy strategy = load_strategy(request) # Now we get the backend that corresponds to our user's social auth provider # e.g., Facebook, Twitter, etc. backend = load_backend(strategy=strategy, name=provider, redirect_uri=None) token = None if isinstance(backend, BaseOAuth1): # Twitter, for example, uses OAuth1 and requires that you also pass # an `oauth_token_secret` with your authentication request token = { 'oauth_token': request.data.get('access_token'), 'oauth_token_secret': request.data.get('access_token_secret'), } elif isinstance(backend, BaseOAuth2): # We're using oauth's implicit grant type (usually used for web and mobile # applications), so all we have to pass here is an access_token token = request.data.get('access_token') try: # if `authed_user` is None, python-social-auth will make a new user, # else this social account will be associated with the user you pass in user = backend.do_auth(token, user=authed_user) except AuthAlreadyAssociated: # You can't associate a social account with more than user return Response( {"errors": "That social media account is already in use"}, status=status.HTTP_400_BAD_REQUEST) except: logger.exception("Exception in social signup:%s" % provider) return Response({"errors": "Some problem in signing up"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) if user and user.is_active: # if the access token was set to an empty string, then save the access token # from the request auth_created = user.social_auth.get(provider=provider) if not auth_created.extra_data['access_token']: # Facebook for example will return the access_token in its response to you. # This access_token is then saved for your future use. However, others # e.g., Instagram do not respond with the access_token that you just # provided. We save it here so it can be used to make subsequent calls. auth_created.extra_data['access_token'] = token auth_created.save() #return jwt_token and user id jwt_token = user.get_jwt_token() result = { 'token': jwt_token, 'user': userSerializer.UserSerializer(user).data } return Response(result, status=status.HTTP_201_CREATED) else: return Response({"errors": "Error with social authentication"}, status=status.HTTP_400_BAD_REQUEST)
def validate_token_request(self, request): # This method's code is based on the parent method's code # We removed the original comments to replace with ours # explaining our modifications. # We need to set these at None by default otherwise # we are going to get some AttributeError later request._params.setdefault("backend", None) request._params.setdefault("client_secret", None) if request.grant_type != 'convert_token': raise errors.UnsupportedGrantTypeError(request=request) # We check that a token parameter is present. # It should contain the social token to be used with the backend if request.token is None: raise errors.InvalidRequestError( description='Missing token parameter.', request=request) # We check that a backend parameter is present. # It should contain the name of the social backend to be used if request.backend is None: raise errors.InvalidRequestError( description='Missing backend parameter.', request=request) if not request.client_id: raise errors.MissingClientIdError(request=request) if not self.request_validator.validate_client_id(request.client_id, request): raise errors.InvalidClientIdError(request=request) # Existing code to retrieve the application instance from the client id if self.request_validator.client_authentication_required(request): log.debug('Authenticating client, %r.', request) if not self.request_validator.authenticate_client(request): log.debug('Invalid client (%r), denying access.', request) raise errors.InvalidClientError(request=request) elif not self.request_validator.authenticate_client_id(request.client_id, request): log.debug('Client authentication failed, %r.', request) raise errors.InvalidClientError(request=request) # Ensure client is authorized use of this grant type # We chose refresh_token as a grant_type # as we don't want to modify all the codebase. # It is also the most permissive and logical grant for our needs. request.grant_type = "refresh_token" self.validate_grant_type(request) self.validate_scopes(request) # TODO: Find a better way to pass the django request object strategy = load_strategy(request=request.django_request) try: backend = load_backend(strategy, request.backend, reverse(NAMESPACE + ":complete", args=(request.backend,))) except MissingBackend: raise errors.InvalidRequestError( description='Invalid backend parameter.', request=request) try: user = backend.do_auth(access_token=request.token) except requests.HTTPError as e: raise errors.InvalidRequestError( description="Backend responded with HTTP{0}: {1}.".format(e.response.status_code, e.response.text), request=request) if not user: raise errors.InvalidGrantError('Invalid credentials given.', request=request) request.user = user log.debug('Authorizing access to user %r.', request.user)
def validate_token_request(self, request): # This method's code is based on the parent method's code # We removed the original comments to replace with ours # explaining our modifications. # We need to set these at None by default otherwise # we are going to get some AttributeError later request._params.setdefault("backend", None) request._params.setdefault("client_secret", None) if request.grant_type != "convert_token": raise errors.UnsupportedGrantTypeError(request=request) # We check that a token parameter is present. # It should contain the social token to be used with the backend if request.token is None: raise errors.InvalidRequestError(description="Missing token parameter.", request=request) # We check that a backend parameter is present. # It should contain the name of the social backend to be used if request.backend is None: raise errors.InvalidRequestError(description="Missing backend parameter.", request=request) if not request.client_id: raise errors.MissingClientIdError(request=request) if not self.request_validator.validate_client_id(request.client_id, request): raise errors.InvalidClientIdError(request=request) # Existing code to retrieve the application instance from the client id if self.request_validator.client_authentication_required(request): log.debug("Authenticating client, %r.", request) if not self.request_validator.authenticate_client(request): log.debug("Invalid client (%r), denying access.", request) raise errors.InvalidClientError(request=request) elif not self.request_validator.authenticate_client_id(request.client_id, request): log.debug("Client authentication failed, %r.", request) raise errors.InvalidClientError(request=request) # Ensure client is authorized use of this grant type # We chose refresh_token as a grant_type # as we don't want to modify all the codebase. # It is also the most permissive and logical grant for our needs. request.grant_type = "refresh_token" self.validate_grant_type(request) self.validate_scopes(request) # TODO: Find a better way to pass the django request object strategy = load_strategy(request=request.django_request) try: backend = load_backend(strategy, request.backend, reverse(NAMESPACE + ":complete", args=(request.backend,))) except MissingBackend: raise errors.InvalidRequestError(description="Invalid backend parameter.", request=request) try: user = backend.do_auth(access_token=request.token) except requests.HTTPError as e: raise errors.InvalidRequestError( description="Backend responded with HTTP{0}: {1}.".format(e.response.status_code, e.response.text), request=request, ) if not user: raise errors.InvalidGrantError("Invalid credentials given.", request=request) request.user = user log.debug("Authorizing access to user %r.", request.user)