예제 #1
0
def do_disconnect(backend,
                  user,
                  association_id=None,
                  redirect_name='next',
                  *args,
                  **kwargs):
    partial = partial_pipeline_data(backend, user, *args, **kwargs)
    if partial:
        xargs, xkwargs = partial
        if association_id and not xkwargs.get('association_id'):
            xkwargs['association_id'] = association_id
        response = backend.disconnect(*xargs, **xkwargs)
    else:
        response = backend.disconnect(user=user,
                                      association_id=association_id,
                                      *args,
                                      **kwargs)

    if isinstance(response, dict):
        response = backend.strategy.redirect(
            backend.strategy.absolute_uri(
                backend.strategy.request_data().get(redirect_name, '')
                or backend.setting('DISCONNECT_REDIRECT_URL')
                or backend.setting('LOGIN_REDIRECT_URL')))
    return response
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
파일: test_utils.py 프로젝트: 2070616d/TP3
 def test_kwargs_included_in_result(self):
     backend = self._backend()
     key, val = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(backend, None,
                                        *(), **dict([(key, val)]))
     self.assertTrue(key in xkwargs)
     self.assertEqual(xkwargs[key], val)
예제 #5
0
def do_disconnect(strategy,
                  user,
                  association_id=None,
                  redirect_name='next',
                  *args,
                  **kwargs):
    partial = partial_pipeline_data(strategy, user, *args, **kwargs)
    if partial is not None:
        idx, backend, xargs, xkwargs = partial
        if backend == strategy.backend_name:
            out = strategy.disconnect(pipeline_index=idx,
                                      user=user,
                                      association_id=association_id,
                                      *args,
                                      **kwargs)
        else:
            strategy.clean_partial_pipeline()
            out = strategy.disconnect(user=user,
                                      association_id=association_id,
                                      *args,
                                      **kwargs)
    else:
        out = strategy.disconnect(user=user,
                                  association_id=association_id,
                                  *args,
                                  **kwargs)
    if not isinstance(out, dict):
        return out
    else:
        data = strategy.request_data()
        return strategy.redirect(
            data.get(redirect_name, '')
            or strategy.setting('DISCONNECT_REDIRECT_URL')
            or strategy.setting('LOGIN_REDIRECT_URL'))
예제 #6
0
 def test_kwargs_included_in_result(self):
     backend = self._backend()
     key, val = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(backend, None, *(),
                                        **dict([(key, val)]))
     self.assertTrue(key in xkwargs)
     self.assertEqual(xkwargs[key], val)
예제 #7
0
 def test_update_user(self):
     user = object()
     backend = self._backend(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(backend, user)
     self.assertTrue('user' in xkwargs)
     self.assertEqual(xkwargs['user'], user)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
예제 #8
0
 def test_update_user(self):
     user = object()
     backend = self._backend(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(backend, user)
     self.assertTrue('user' in xkwargs)
     self.assertEqual(xkwargs['user'], user)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
예제 #9
0
    def test_update_user(self):
        strategy = mock.Mock()
        strategy.session_get.return_value = object()
        partial_from_session = (object(), object(), [], {'user': None})
        strategy.partial_from_session.return_value = partial_from_session
        user = object()

        _, _, _, xkwargs = partial_pipeline_data(strategy, user)
        xkwargs.should.have.key('user').being.equal(user)
예제 #10
0
    def test_update_user(self):
        strategy = mock.Mock()
        strategy.session_get.return_value = object()
        partial_from_session = (object(), object(), [], {'user': None})
        strategy.partial_from_session.return_value = partial_from_session
        user = object()

        _, _, _, xkwargs = partial_pipeline_data(strategy, user)
        xkwargs.should.have.key('user').being.equal(user)
예제 #11
0
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)
예제 #12
0
 def test_clean_pipeline_when_uid_does_not_match(self):
     backend = self._backend({'uid': '*****@*****.**'})
     backend.strategy.request_data.return_value = {
         backend.ID_KEY: '*****@*****.**'
     }
     key, val = ('foo', 'bar')
     ret = partial_pipeline_data(backend, None, *(), **dict([(key, val)]))
     self.assertIsNone(ret)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 1)
예제 #13
0
 def test_returns_partial_when_uid_and_email_do_match(self):
     email = '*****@*****.**'
     backend = self._backend({'uid': email})
     backend.strategy.request_data.return_value = {backend.ID_KEY: email}
     key, val = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(backend, None, *(),
                                        **dict([(key, val)]))
     self.assertTrue(key in xkwargs)
     self.assertEqual(xkwargs[key], val)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
예제 #14
0
 def test_clean_pipeline_when_uid_does_not_match(self):
     backend = self._backend({'uid': '*****@*****.**'})
     backend.strategy.request_data.return_value = {
         backend.ID_KEY: '*****@*****.**'
     }
     key, val = ('foo', 'bar')
     ret = partial_pipeline_data(backend, None,
                                        *(), **dict([(key, val)]))
     self.assertIsNone(ret)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 1)
예제 #15
0
    def test_kwargs_included_in_result(self):
        strategy = mock.Mock()
        strategy.session_get.return_value = object()
        partial_from_session = (object(), object(), [], {})
        strategy.partial_from_session.return_value = partial_from_session
        kwargitem = ('foo', 'bar')

        _, _, _, xkwargs = partial_pipeline_data(strategy, None,
                                                 **dict([kwargitem]))

        xkwargs.should.have.key(kwargitem[0]).being.equal(kwargitem[1])
예제 #16
0
    def test_kwargs_included_in_result(self):
        strategy = mock.Mock()
        strategy.session_get.return_value = object()
        partial_from_session = (object(), object(), [], {})
        strategy.partial_from_session.return_value = partial_from_session
        kwargitem = ('foo', 'bar')

        _, _, _, xkwargs = partial_pipeline_data(strategy, None,
                                                 **dict([kwargitem]))

        xkwargs.should.have.key(kwargitem[0]).being.equal(kwargitem[1])
예제 #17
0
 def test_returns_partial_when_uid_and_email_do_match(self):
     email = '*****@*****.**'
     backend = self._backend({'uid': email})
     backend.strategy.request_data.return_value = {
         backend.ID_KEY: email
     }
     key, val = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(backend, None,
                                        *(), **dict([(key, val)]))
     self.assertTrue(key in xkwargs)
     self.assertEqual(xkwargs[key], val)
     self.assertEqual(backend.strategy.clean_partial_pipeline.call_count, 0)
예제 #18
0
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)
예제 #19
0
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)
예제 #20
0
def do_disconnect(strategy, user, association_id=None, redirect_name="next", *args, **kwargs):
    partial = partial_pipeline_data(strategy, user, *args, **kwargs)
    if partial:
        xargs, xkwargs = partial
        response = strategy.disconnect(association_id=association_id, *xargs, **xkwargs)
    else:
        response = strategy.disconnect(user=user, association_id=association_id, *args, **kwargs)

    if isinstance(response, dict):
        response = strategy.redirect(
            strategy.request_data().get(redirect_name, "")
            or strategy.setting("DISCONNECT_REDIRECT_URL")
            or strategy.setting("LOGIN_REDIRECT_URL")
        )
    return response
예제 #21
0
def do_disconnect(backend, user, association_id=None, redirect_name="next", *args, **kwargs):
    partial = partial_pipeline_data(backend, user, *args, **kwargs)
    if partial:
        xargs, xkwargs = partial
        if association_id and not xkwargs.get("association_id"):
            xkwargs["association_id"] = association_id
        response = backend.disconnect(*xargs, **xkwargs)
    else:
        response = backend.disconnect(user=user, association_id=association_id, *args, **kwargs)

    if isinstance(response, dict):
        response = backend.strategy.redirect(
            backend.strategy.request_data().get(redirect_name, "")
            or backend.setting("DISCONNECT_REDIRECT_URL")
            or backend.setting("LOGIN_REDIRECT_URL")
        )
    return response
예제 #22
0
def do_disconnect(strategy, user, association_id=None, redirect_name="next", *args, **kwargs):
    partial = partial_pipeline_data(strategy, user, *args, **kwargs)
    out = None
    if partial is not None:
        idx, backend, xargs, xkwargs = partial
        if backend == strategy.backend.name:
            out = strategy.disconnect(pipeline_index=idx, user=user, association_id=association_id, *args, **kwargs)
    if out is None:
        strategy.clean_partial_pipeline()
        out = strategy.disconnect(user=user, association_id=association_id, *args, **kwargs)
    if not isinstance(out, dict):
        return out
    else:
        data = strategy.request_data()
        return strategy.redirect(
            data.get(redirect_name, "")
            or strategy.setting("DISCONNECT_REDIRECT_URL")
            or strategy.setting("LOGIN_REDIRECT_URL")
        )
예제 #23
0
def do_disconnect(strategy, user, association_id=None, redirect_name='next',
                  *args, **kwargs):
    partial = partial_pipeline_data(strategy, user, *args, **kwargs)
    if partial:
        xargs, xkwargs = partial
        if association_id and not xkwargs.get('association_id'):
            xkwargs['association_id'] = association_id
        response = strategy.disconnect(*xargs, **xkwargs)
    else:
        response = strategy.disconnect(user=user,
                                       association_id=association_id,
                                       *args, **kwargs)

    if isinstance(response, dict):
        response = strategy.redirect(
            strategy.request_data().get(redirect_name, '') or
            strategy.setting('DISCONNECT_REDIRECT_URL') or
            strategy.setting('LOGIN_REDIRECT_URL')
        )
    return response
예제 #24
0
def do_disconnect(strategy,
                  user,
                  association_id=None,
                  redirect_name='next',
                  *args,
                  **kwargs):
    partial = partial_pipeline_data(strategy, user, *args, **kwargs)
    if partial:
        xargs, xkwargs = partial
        response = strategy.disconnect(association_id=association_id,
                                       *xargs,
                                       **xkwargs)
    else:
        response = strategy.disconnect(user=user,
                                       association_id=association_id,
                                       *args,
                                       **kwargs)

    if isinstance(response, dict):
        response = strategy.redirect(
            strategy.request_data().get(redirect_name, '')
            or strategy.setting('DISCONNECT_REDIRECT_URL')
            or strategy.setting('LOGIN_REDIRECT_URL'))
    return response
예제 #25
0
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)
예제 #26
0
 def test_kwargs_included_in_result(self):
     backend = self._backend()
     kwargitem = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(backend, None, *(),
                                        **dict([kwargitem]))
     xkwargs.should.have.key(kwargitem[0]).being.equal(kwargitem[1])
예제 #27
0
 def test_update_user(self):
     user = object()
     backend = self._backend(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(backend, user)
     xkwargs.should.have.key('user').being.equal(user)
예제 #28
0
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)
예제 #29
0
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)
    return strategy.redirect(url)
예제 #30
0
    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
        })
예제 #31
0
    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})
예제 #32
0
 def test_update_user(self):
     user = object()
     strategy = self._strategy(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(strategy, user)
     xkwargs.should.have.key('user').being.equal(user)
예제 #33
0
 def test_kwargs_included_in_result(self):
     kwargitem = ('foo', 'bar')
     _, _, _, xkwargs = partial_pipeline_data(self.MockStrategy(), None,
                                              **dict([kwargitem]))
     xkwargs.should.have.key(kwargitem[0]).being.equal(kwargitem[1])
예제 #34
0
 def test_update_user(self):
     user = object()
     backend = self._backend(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(backend, user)
     xkwargs.should.have.key('user').being.equal(user)
예제 #35
0
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)
예제 #36
0
 def test_kwargs_included_in_result(self):
     strategy = self._strategy()
     kwargitem = ('foo', 'bar')
     _, xkwargs = partial_pipeline_data(strategy, None,
                                        *(), **dict([kwargitem]))
     xkwargs.should.have.key(kwargitem[0]).being.equal(kwargitem[1])
 def test_update_user(self):
     user = object()
     strategy = self._strategy(session_kwargs={'user': None})
     _, xkwargs = partial_pipeline_data(strategy, user)
     xkwargs.should.have.key('user').being.equal(user)