def get_object(self): user = self.request.user manual_redirect_uri = self.request.auth_data.pop('redirect_uri', None) manual_redirect_uri = self.get_redirect_uri(manual_redirect_uri) if manual_redirect_uri: self.request.backend.redirect_uri = manual_redirect_uri elif DOMAIN_FROM_ORIGIN: origin = self.request.strategy.request.META.get('HTTP_ORIGIN') if origin: relative_path = urlparse( self.request.backend.redirect_uri).path url = urlparse(origin) origin_scheme_host = "%s://%s" % (url.scheme, url.netloc) location = urljoin(origin_scheme_host, relative_path) self.request.backend.redirect_uri = iri_to_uri(location) is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None # skip checking state by setting following params to False # it is responsibility of front-end to check state # TODO: maybe create an additional resource, where front-end will # store the state before making a call to oauth provider # so server can save it in session and consequently check it before # sending request to acquire access token. # In case of token authentication we need a way to store an anonymous # session to do it. self.request.backend.REDIRECT_STATE = False self.request.backend.STATE_PARAMETER = False user = self.request.backend.complete(user=user) return user
def do_complete(strategy, login, user=None, redirect_name='next', *args, **kwargs): # pop redirect value before the session is trashed on login() data = strategy.request_data() redirect_value = strategy.session_get(redirect_name, '') or \ data.get(redirect_name, '') is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None partial = partial_pipeline_data(strategy, user, *args, **kwargs) if partial: xargs, xkwargs = partial user = strategy.continue_pipeline(*xargs, **xkwargs) else: user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) if user and not isinstance(user, strategy.storage.user.user_model()): return user if is_authenticated: if not user: url = setting_url(strategy, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(strategy, 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) social_user = user.social_user login(strategy, user, social_user) # store last login backend name in session strategy.session_set('social_auth_last_login_backend', social_user.provider) if is_new: url = setting_url(strategy, redirect_value, 'NEW_USER_REDIRECT_URL', 'LOGIN_REDIRECT_URL') else: url = setting_url(strategy, redirect_value, 'LOGIN_REDIRECT_URL') else: url = setting_url(strategy, 'INACTIVE_USER_URL', 'LOGIN_ERROR_URL', 'LOGIN_URL') else: url = setting_url(strategy, '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_name, redirect_value) if strategy.setting('SANITIZE_REDIRECTS', True): url = sanitize_redirect(strategy.request_host(), url) or \ strategy.setting('LOGIN_REDIRECT_URL') return strategy.redirect(url)
def user_backends_data(user, backends, storage): """ Will return backends data for given user, the return value will have the following keys: associated: UserSocialAuth model instances for currently associated accounts not_associated: Not associated (yet) backend names backends: All backend names. If user is not authenticated, then 'associated' list is empty, and there's no difference between 'not_associated' and 'backends'. """ available = list(load_backends(backends).keys()) values = { 'associated': [], 'not_associated': available, 'backends': available } if user_is_authenticated(user): associated = storage.user.get_social_auth_for_user(user) not_associated = list(set(available) - set(associated.provider)) # set(associated.provider for assoc in associated)) values['associated'] = associated values['not_associated'] = not_associated return values
def get_object(self): user = self.request.user manual_redirect_uri = self.request.auth_data.pop('redirect_uri', None) manual_redirect_uri = self.get_redirect_uri(manual_redirect_uri) if manual_redirect_uri: self.request.backend.redirect_uri = manual_redirect_uri elif DOMAIN_FROM_ORIGIN: origin = self.request.strategy.request.META.get('HTTP_ORIGIN') if origin: relative_path = urlparse(self.request.backend.redirect_uri).path url = urlparse(origin) origin_scheme_host = "%s://%s" % (url.scheme, url.netloc) location = urljoin(origin_scheme_host, relative_path) self.request.backend.redirect_uri = iri_to_uri(location) is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None # skip checking state by setting following params to False # it is responsibility of front-end to check state # TODO: maybe create an additional resource, where front-end will # store the state before making a call to oauth provider # so server can save it in session and consequently check it before # sending request to acquire access token. # In case of token authentication we need a way to store an anonymous # session to do it. self.request.backend.REDIRECT_STATE = False self.request.backend.STATE_PARAMETER = False user = self.request.backend.complete(user=user) return user
def context_value(): keys = [key for key in get_backends().keys()] accounts = dict(zip(keys, [None] * len(keys))) user = request.user if user_is_authenticated(user): accounts.update((assoc.provider, assoc) for assoc in UserSocialAuth.get_social_auth_for_user(user)) return accounts
def context_value(): keys = [key for key in get_backends().keys()] accounts = dict(zip(keys, [None] * len(keys))) user = request.user if user_is_authenticated(user): accounts.update( (assoc.provider, assoc) for assoc in UserSocialAuth.get_social_auth_for_user(user)) return accounts
def do_complete(strategy, login, user=None, redirect_name="next", *args, **kwargs): # pop redirect value before the session is trashed on login() data = strategy.request_data() redirect_value = strategy.session_get(redirect_name, "") or data.get(redirect_name, "") is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None default_redirect = strategy.setting("LOGIN_REDIRECT_URL") url = default_redirect login_error_url = strategy.setting("LOGIN_ERROR_URL") or strategy.setting("LOGIN_URL") partial = partial_pipeline_data(strategy, user, *args, **kwargs) if partial is not None: idx, backend, xargs, xkwargs = partial if backend == strategy.backend.name: user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) else: user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) if user and not isinstance(user, strategy.storage.user.user_model()): return user if is_authenticated: if not user: url = redirect_value or default_redirect else: url = redirect_value or strategy.setting("NEW_ASSOCIATION_REDIRECT_URL") or default_redirect 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) social_user = user.social_user login(strategy, user) # store last login backend name in session strategy.session_set("social_auth_last_login_backend", social_user.provider) # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting("NEW_USER_REDIRECT_URL") if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or default_redirect else: url = strategy.setting("INACTIVE_USER_URL", login_error_url) else: url = login_error_url if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ("?" in url and "&" or "?") + "{0}={1}".format(redirect_name, redirect_value) if strategy.setting("SANITIZE_REDIRECTS", True): url = sanitize_redirect(strategy.request_host(), url) or strategy.setting("LOGIN_REDIRECT_URL") return strategy.redirect(url)
def do_complete_with_response(backend, login, user=None, redirect_name='next', response=None, *args, **kwargs): data = backend.strategy.request_data() 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.auth_complete_with_response(user=user, response=response, *args, **kwargs) return finish_complete(backend, login, user, is_authenticated, data, redirect_name, *args, **kwargs)
def do_complete(backend, login, user=None, redirect_name="next", *args, **kwargs): # pop redirect value before the session is trashed on login() data = backend.strategy.request_data() redirect_value = backend.strategy.session_get(redirect_name, "") or data.get(redirect_name, "") 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) 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) social_user = user.social_user login(backend, user, social_user) # store last login backend name in session backend.strategy.session_set("social_auth_last_login_backend", social_user.provider) 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") 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_name, redirect_value) if backend.setting("SANITIZE_REDIRECTS", True): url = sanitize_redirect(backend.strategy.request_host(), url) or backend.setting("LOGIN_REDIRECT_URL") return backend.strategy.redirect(url)
def user_backends_data(user, backends, storage): """ Will return backends data for given user, the return value will have the following keys: associated: UserSocialAuth model instances for currently associated accounts not_associated: Not associated (yet) backend names backends: All backend names. If user is not authenticated, then 'associated' list is empty, and there's no difference between 'not_associated' and 'backends'. """ available = list(load_backends(backends).keys()) values = {'associated': [], 'not_associated': available, 'backends': available} if user_is_authenticated(user): associated = storage.user.get_social_auth_for_user(user) not_associated = list(set(available) - set(associated.provider)) # set(associated.provider for assoc in associated)) values['associated'] = associated values['not_associated'] = not_associated return values
def do_complete(strategy, login, user=None, redirect_name="next", *args, **kwargs): # pop redirect value before the session is trashed on login() data = strategy.request_data() redirect_value = strategy.session_get(redirect_name, "") or data.get(redirect_name, "") is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None partial = partial_pipeline_data(strategy, user, *args, **kwargs) if partial: xargs, xkwargs = partial user = strategy.continue_pipeline(*xargs, **xkwargs) else: user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) try: is_api_call = strategy.request.COOKIES.get("is_api_call") except: try: is_api_call = strategy.session_get("is_api_call") except: is_api_call = None if user and not isinstance(user, strategy.storage.user.user_model()): return user if is_authenticated: if not user: url = setting_url(strategy, redirect_value, "LOGIN_REDIRECT_URL") else: url = setting_url(strategy, redirect_value, "NEW_ASSOCIATION_REDIRECT_URL", "LOGIN_REDIRECT_URL") if is_api_call is not None: url = "/api/login/social/success/" 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) social_user = user.social_user login(strategy, user) # store last login backend name in session strategy.session_set("social_auth_last_login_backend", social_user.provider) if is_new: url = setting_url(strategy, redirect_value, "NEW_USER_REDIRECT_URL", "LOGIN_REDIRECT_URL") else: url = setting_url(strategy, redirect_value, "LOGIN_REDIRECT_URL") if is_api_call is not None: url = "/api/login/social/success/" else: url = setting_url(strategy, "INACTIVE_USER_URL", "LOGIN_ERROR_URL", "LOGIN_URL") if strategy.setting("INACTIVE_USER_REDIRECT_WITH_ID") is True: url += "?user_id=" + str(user.id) if is_api_call is not None: url = "/api/login/social/fail/" url += "?user_id=" + str(user.id) + "&reason=user_already_exist" else: url = setting_url(strategy, "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_name, redirect_value) if strategy.setting("SANITIZE_REDIRECTS", True): url = sanitize_redirect(strategy.request_host(), url) or strategy.setting("LOGIN_REDIRECT_URL") return strategy.redirect(url)
def do_complete(strategy, login, user=None, redirect_name='next', *args, **kwargs): # pop redirect value before the session is trashed on login() data = strategy.request_data() redirect_value = strategy.session_get(redirect_name, '') or \ data.get(redirect_name, '') is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None default_redirect = strategy.setting('LOGIN_REDIRECT_URL') url = default_redirect login_error_url = strategy.setting('LOGIN_ERROR_URL') or \ strategy.setting('LOGIN_URL') partial = strategy.session_get('partial_pipeline', None) if partial is not None: idx, backend, xargs, xkwargs = strategy.from_session(partial) if backend == strategy.backend_name: kwargs = kwargs.copy() kwargs.setdefault('user', user) kwargs.update(xkwargs) user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) else: user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) if user and not isinstance(user, strategy.storage.user.user_model()): return user if is_authenticated: if not user: url = redirect_value or default_redirect else: url = redirect_value or \ strategy.setting('NEW_ASSOCIATION_REDIRECT_URL') or \ default_redirect 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) social_user = user.social_user login(strategy, user) # store last login backend name in session strategy.session_set('social_auth_last_login_backend', social_user.provider) # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting('NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or default_redirect else: url = strategy.setting('INACTIVE_USER_URL', login_error_url) else: url = login_error_url if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + \ '{0}={1}'.format(redirect_name, redirect_value) return strategy.redirect(url)
def do_complete(strategy, login, user=None, redirect_name='next', *args, **kwargs): # pop redirect value before the session is trashed on login() data = strategy.request_data() redirect_value = strategy.session_get(redirect_name, '') or \ data.get(redirect_name, '') is_authenticated = user_is_authenticated(user) user = is_authenticated and user or None default_redirect = strategy.setting('LOGIN_REDIRECT_URL') url = default_redirect login_error_url = strategy.setting('LOGIN_ERROR_URL') or \ strategy.setting('LOGIN_URL') partial = strategy.session_get('partial_pipeline', None) if partial is not None: idx, backend, xargs, xkwargs = strategy.from_session(partial) if backend == strategy.backend_name: kwargs = kwargs.copy() kwargs.setdefault('user', user) kwargs.update(xkwargs) user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) else: user = strategy.complete(user=user, request=strategy.request, *args, **kwargs) if user and not isinstance(user, strategy.storage.user.user_model()): return user if is_authenticated: if not user: url = redirect_value or default_redirect else: url = redirect_value or \ strategy.setting('NEW_ASSOCIATION_REDIRECT_URL') or \ default_redirect 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) social_user = user.social_user login(strategy, user) # store last login backend name in session strategy.session_set('social_auth_last_login_backend', social_user.provider) # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting('NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or default_redirect else: url = strategy.setting('INACTIVE_USER_URL', login_error_url) else: url = login_error_url if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + \ '%s=%s' % (redirect_name, redirect_value) return strategy.redirect(url)
def _complete(self, backend, *args, **kwargs): strategy = self.strategy # pop redirect value before the session is trashed on login() redirect_value = self.session.get('next', '') or \ self.data.get('next', '') url = strategy.setting('LOGIN_REDIRECT_URL') user = self.get_current_user() is_authenticated = user_is_authenticated(user) if not is_authenticated: user = None if self.session.get('partial_pipeline'): data = self.session.pop('partial_pipeline') kwargs = kwargs.copy() kwargs.setdefault('user', user) idx, xargs, xkwargs = strategy.from_session(data, request=web.ctx, *args, **kwargs) if xkwargs.get('backend', '') == backend: user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=web.ctx, *args, **kwargs) else: user = strategy.complete(user=user, request=web.ctx, *args, **kwargs) if isinstance(user, web.Storage): return user if is_authenticated: if not user: url = redirect_value or strategy.setting('LOGIN_REDIRECT_URL') else: url = redirect_value or \ strategy.setting('NEW_ASSOCIATION_REDIRECT_URL') or \ strategy.setting('LOGIN_REDIRECT_URL') elif user: if user_is_active(user): # catch is_new flag before login() resets the instance is_new = getattr(user, 'is_new', False) self.login_user(user) # user.social_user is the used UserSocialAuth instance defined # in authenticate process social_user = user.social_user # store last login backend name in session self.session['social_auth_last_login_backend'] = \ social_user.provider # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting('NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or \ strategy.setting('LOGIN_REDIRECT_URL') else: url = strategy.setting('INACTIVE_USER_URL') or \ strategy.setting('LOGIN_ERROR_URL') or \ strategy.setting('LOGIN_URL') else: url = strategy.setting('LOGIN_ERROR_URL') or \ strategy.setting('LOGIN_URL') if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + \ '%s=%s' % ('next', redirect_value) return web.seeother(url)
def do_complete(backend, login, user=None, redirect_name='next', *args, **kwargs): data = backend.strategy.request_data() 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_name, '') or \ data.get(redirect_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) social_user = user.social_user login(backend, user, social_user) # store last login backend name in session backend.strategy.session_set('social_auth_last_login_backend', social_user.provider) 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: if backend.setting('INACTIVE_USER_LOGIN', False): social_user = user.social_user login(backend, user, social_user) url = setting_url(backend, 'INACTIVE_USER_URL', 'LOGIN_ERROR_URL', 'LOGIN_URL') 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_name, redirect_value) if backend.setting('SANITIZE_REDIRECTS', True): allowed_hosts = backend.setting('ALLOWED_REDIRECT_HOSTS', []) + \ [backend.strategy.request_host()] url = sanitize_redirect(allowed_hosts, url) or \ backend.setting('LOGIN_REDIRECT_URL') return backend.strategy.redirect(url)
def test_user_has_is_authenticated(self): class User(object): is_authenticated = True self.assertEqual(user_is_authenticated(User()), True)
def test_user_has_is_authenticated(self): class User(object): is_authenticated = True expect(user_is_authenticated(User())).to.equal(True)
def test_user_has_is_authenticated_callable(self): class User(object): def is_authenticated(self): return True expect(user_is_authenticated(User())).to.equal(True)
def test_user_is_none(self): expect(user_is_authenticated(None)).to.equal(False)
def test_user_is_not_none(self): expect(user_is_authenticated(object())).to.equal(True)
def test_user_is_none(self): self.assertEqual(user_is_authenticated(None), False)
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 test_user_is_not_none(self): self.assertEqual(user_is_authenticated(object()), True)
def test_user_has_is_authenticated_callable(self): class User(object): def is_authenticated(self): return True self.assertEqual(user_is_authenticated(User()), True)
def complete(backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" strategy = g.strategy # pop redirect value before the session is trashed on login() redirect_value = session.get("next", "") or request.form.get("next", "") or request.args.get("next", "") is_authenticated = user_is_authenticated(g.user) user = is_authenticated and g.user or None url = strategy.setting("LOGIN_REDIRECT_URL") if session.get("partial_pipeline"): data = session.pop("partial_pipeline") kwargs = kwargs.copy() kwargs.setdefault("user", user) idx, xargs, xkwargs = strategy.from_session(data, request=request, *args, **kwargs) if xkwargs.get("backend", "") == backend: user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=request, *args, **kwargs) else: user = strategy.complete(user=user, request=request, *args, **kwargs) if isinstance(user, Response): return user if is_authenticated: if not user: url = redirect_value or strategy.setting("LOGIN_REDIRECT_URL") else: url = ( redirect_value or strategy.setting("NEW_ASSOCIATION_REDIRECT_URL") or strategy.setting("LOGIN_REDIRECT_URL") ) elif user: if user_is_active(user): # catch is_new flag before login() resets the instance is_new = getattr(user, "is_new", False) login_user(user) # user.social_user is the used UserSocialAuth instance defined # in authenticate process social_user = user.social_user # store last login backend name in session session["social_auth_last_login_backend"] = social_user.provider # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting("NEW_USER_REDIRECT_URL") if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or strategy.setting("LOGIN_REDIRECT_URL") else: url = ( strategy.setting("INACTIVE_USER_URL") or strategy.setting("LOGIN_ERROR_URL") or strategy.setting("LOGIN_URL") ) else: url = strategy.setting("LOGIN_ERROR_URL") or strategy.setting("LOGIN_URL") if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ("?" in url and "&" or "?") + "%s=%s" % ("next", redirect_value) return redirect(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 complete(request, backend, *args, **kwargs): """Authentication complete view, override this view if transaction management doesn't suit your needs.""" strategy = request.strategy # pop redirect value before the session is trashed on login() redirect_value = request.session.get(REDIRECT_FIELD_NAME, '') or \ request.REQUEST.get(REDIRECT_FIELD_NAME, '') is_authenticated = user_is_authenticated(request.user) user = is_authenticated and request.user or None url = DEFAULT_REDIRECT if request.session.get('partial_pipeline'): data = request.session.pop('partial_pipeline') kwargs = kwargs.copy() kwargs.setdefault('user', user) idx, xargs, xkwargs = strategy.from_session(data, request=request, *args, **kwargs) if xkwargs.get('backend', '') == backend: user = strategy.continue_pipeline(pipeline_index=idx, *xargs, **xkwargs) else: strategy.clean_partial_pipeline() user = strategy.complete(user=user, request=request, *args, **kwargs) else: user = strategy.complete(user=user, request=request, *args, **kwargs) if isinstance(user, HttpResponse): return user if is_authenticated: if not user: url = redirect_value or DEFAULT_REDIRECT else: url = redirect_value or \ strategy.setting('NEW_ASSOCIATION_REDIRECT_URL') or \ DEFAULT_REDIRECT elif user: if user_is_active(user): # catch is_new flag before login() resets the instance is_new = getattr(user, 'is_new', False) login(request, user) # Hack django.auth backend loading since they create an instance # that won't know about the strategy/storage layout being used request.session['original_' + BACKEND_SESSION_KEY] = \ request.session[BACKEND_SESSION_KEY] request.session[BACKEND_SESSION_KEY] = '%s.%s' % ( BackendWrapper.__module__, BackendWrapper.__name__ ) # user.social_user is the used UserSocialAuth instance defined # in authenticate process social_user = user.social_user if setting('SESSION_EXPIRATION', True): # Set session expiration date if present and not disabled # by setting. Use last social-auth instance for current # provider, users can associate several accounts with # a same provider. expiration = social_user.expiration_datetime() if expiration: try: request.session.set_expiry(expiration) except OverflowError: # Handle django time zone overflow request.session.set_expiry(None) # store last login backend name in session request.session['social_auth_last_login_backend'] = \ social_user.provider # Remove possible redirect URL from session, if this is a new # account, send him to the new-users-page if defined. new_user_redirect = strategy.setting('NEW_USER_REDIRECT_URL') if new_user_redirect and is_new: url = new_user_redirect else: url = redirect_value or strategy.setting('LOGIN_REDIRECT_URL') else: url = strategy.setting('INACTIVE_USER_URL', LOGIN_ERROR_URL) else: url = strategy.setting('LOGIN_ERROR_URL', LOGIN_ERROR_URL) if redirect_value and redirect_value != url: redirect_value = quote(redirect_value) url += ('?' in url and '&' or '?') + \ '%s=%s' % (REDIRECT_FIELD_NAME, redirect_value) return HttpResponseRedirect(url)