Commit b44dee16 authored by Jon Dufresne's avatar Jon Dufresne Committed by Tim Graham
Browse files

Fixed #20916 -- Added Client.force_login() to bypass authentication.

parent 39ec59d6
Loading
Loading
Loading
Loading
+35 −26
Original line number Diff line number Diff line
@@ -592,10 +592,23 @@ class Client(RequestFactory):
        are incorrect, or the user is inactive, or if the sessions framework is
        not available.
        """
        from django.contrib.auth import authenticate, login
        from django.contrib.auth import authenticate
        user = authenticate(**credentials)
        if (user and user.is_active and
                apps.is_installed('django.contrib.sessions')):
            self._login(user)
            return True
        else:
            return False

    def force_login(self, user, backend=None):
        if backend is None:
            backend = settings.AUTHENTICATION_BACKENDS[0]
        user.backend = backend
        self._login(user)

    def _login(self, user):
        from django.contrib.auth import login
        engine = import_module(settings.SESSION_ENGINE)

        # Create a fake request to store login details.
@@ -622,10 +635,6 @@ class Client(RequestFactory):
        }
        self.cookies[session_cookie].update(cookie_data)

            return True
        else:
            return False

    def logout(self):
        """
        Removes the authenticated user's cookies and session object.
+5 −0
Original line number Diff line number Diff line
@@ -484,6 +484,11 @@ Tests
* Added the :meth:`json() <django.test.Response.json>` method to test client
  responses to give access to the response body as JSON.

* Added the :meth:`~django.test.Client.force_login()` method to the test
  client. Use this method to simulate the effect of a user logging into the
  site while skipping the authentication and verification steps of
  :meth:`~django.test.Client.login()`.

URLs
^^^^

+2 −0
Original line number Diff line number Diff line
@@ -312,6 +312,8 @@ failed and erroneous tests. If all the tests pass, the return code is 0. This
feature is useful if you're using the test-runner script in a shell script and
need to test for success or failure at that level.

.. _speeding-up-tests-auth-hashers:

Speeding up the tests
---------------------

+26 −0
Original line number Diff line number Diff line
@@ -384,6 +384,32 @@ Use the ``django.test.Client`` class to make requests.
        :meth:`~django.contrib.auth.models.UserManager.create_user` helper
        method to create a new user with a correctly hashed password.

    .. method:: Client.force_login(user, backend=None)

        .. versionadded:: 1.9

        If your site uses Django's :doc:`authentication
        system</topics/auth/index>`, you can use the ``force_login()`` method
        to simulate the effect of a user logging into the site. Use this method
        instead of :meth:`login` when a test requires a user be logged in and
        the details of how a user logged in aren't important.

        Unlike ``login()``, this method skips the authentication and
        verification steps: inactive users (:attr:`is_active=False
        <django.contrib.auth.models.User.is_active>`) are permitted to login
        and the user's credentials don't need to be provided.

        The user will have its ``backend`` attribute set to the value of the
        ``backend`` argument (which should be a dotted Python path string), or
        to ``settings.AUTHENTICATION_BACKENDS[0]`` if a value isn't provided.
        The :func:`~django.contrib.auth.authenticate` function called by
        :meth:`login` normally annotates the user like this.

        This method is faster than ``login()`` since the expensive
        password hashing algorithms are bypassed. Also, you can speed up
        ``login()`` by :ref:`using a weaker hasher while testing
        <speeding-up-tests-auth-hashers>`.

    .. method:: Client.logout()

        If your site uses Django's :doc:`authentication system</topics/auth/index>`,
+5 −0
Original line number Diff line number Diff line
from django.contrib.auth.backends import ModelBackend


class TestClientBackend(ModelBackend):
    pass
Loading