summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorPreston Holmes <preston@ptone.com>2012-12-28 11:00:11 -0800
committerPreston Holmes <preston@ptone.com>2012-12-28 11:06:12 -0800
commit11ded967c443087487f3872aafd86842608b4c64 (patch)
treea25a1388a0109d7723a738f3926c791628eab211 /docs
parentdb278c3bf9177043c42a9ed8b529a5c117938460 (diff)
downloaddjango-11ded967c443087487f3872aafd86842608b4c64.tar.gz
Fixed #19498 -- refactored auth documentation
The auth doc was a single page which had grown unwieldy. This refactor split and grouped the content into sub-topics. Additional corrections and cleanups were made along the way.
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/deployment/wsgi/apache-auth.txt2
-rw-r--r--docs/index.txt2
-rw-r--r--docs/internals/git.txt2
-rw-r--r--docs/misc/api-stability.txt2
-rw-r--r--docs/ref/authbackends.txt33
-rw-r--r--docs/ref/contrib/auth.txt428
-rw-r--r--docs/ref/contrib/index.txt2
-rw-r--r--docs/ref/django-admin.txt4
-rw-r--r--docs/ref/index.txt1
-rw-r--r--docs/ref/middleware.txt4
-rw-r--r--docs/ref/request-response.txt2
-rw-r--r--docs/ref/settings.txt6
-rw-r--r--docs/ref/signals.txt2
-rw-r--r--docs/releases/1.2-beta-1.txt4
-rw-r--r--docs/releases/1.2.txt4
-rw-r--r--docs/releases/1.3-beta-1.txt2
-rw-r--r--docs/releases/1.3.txt2
-rw-r--r--docs/topics/auth.txt2696
-rw-r--r--docs/topics/auth/customizing.txt1074
-rw-r--r--docs/topics/auth/default.txt1077
-rw-r--r--docs/topics/auth/index.txt81
-rw-r--r--docs/topics/auth/passwords.txt212
-rw-r--r--docs/topics/db/models.txt58
-rw-r--r--docs/topics/index.txt2
-rw-r--r--docs/topics/testing/overview.txt4
25 files changed, 2920 insertions, 2786 deletions
diff --git a/docs/howto/deployment/wsgi/apache-auth.txt b/docs/howto/deployment/wsgi/apache-auth.txt
index 5f700f1cb3..220645947d 100644
--- a/docs/howto/deployment/wsgi/apache-auth.txt
+++ b/docs/howto/deployment/wsgi/apache-auth.txt
@@ -4,7 +4,7 @@ Authenticating against Django's user database from Apache
Since keeping multiple authentication databases in sync is a common problem when
dealing with Apache, you can configure Apache to authenticate against Django's
-:doc:`authentication system </topics/auth>` directly. This requires Apache
+:doc:`authentication system </topics/auth/index>` directly. This requires Apache
version >= 2.2 and mod_wsgi >= 2.0. For example, you could:
* Serve static/media files directly from Apache only to authenticated users.
diff --git a/docs/index.txt b/docs/index.txt
index e8e7eadb23..971c2ff479 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -246,7 +246,7 @@ Common Web application tools
Django offers multiple tools commonly needed in the development of Web
applications:
-* :doc:`Authentication <topics/auth>`
+* :doc:`Authentication <topics/auth/index>`
* :doc:`Caching <topics/cache>`
* :doc:`Logging <topics/logging>`
* :doc:`Sending emails <topics/email>`
diff --git a/docs/internals/git.txt b/docs/internals/git.txt
index 948f9a1f7e..2b1a279d89 100644
--- a/docs/internals/git.txt
+++ b/docs/internals/git.txt
@@ -134,7 +134,7 @@ part of Django itself, and so are no longer separately maintained:
of Django since the 0.95 release.
* ``multi-auth``: A refactoring of :doc:`Django's bundled
- authentication framework </topics/auth>` which added support for
+ authentication framework </topics/auth/index>` which added support for
:ref:`authentication backends <authentication-backends>`. This has
been part of Django since the 0.95 release.
diff --git a/docs/misc/api-stability.txt b/docs/misc/api-stability.txt
index a13cb5de69..70e6006575 100644
--- a/docs/misc/api-stability.txt
+++ b/docs/misc/api-stability.txt
@@ -38,7 +38,7 @@ In general, everything covered in the documentation -- with the exception of
anything in the :doc:`internals area </internals/index>` is considered stable as
of 1.0. This includes these APIs:
-- :doc:`Authorization </topics/auth>`
+- :doc:`Authorization </topics/auth/index>`
- :doc:`Caching </topics/cache>`.
diff --git a/docs/ref/authbackends.txt b/docs/ref/authbackends.txt
deleted file mode 100644
index 55a536e819..0000000000
--- a/docs/ref/authbackends.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-=======================
-Authentication backends
-=======================
-
-.. module:: django.contrib.auth.backends
- :synopsis: Django's built-in authentication backend classes.
-
-This document details the authentication backends that come with Django. For
-information on how to use them and how to write your own authentication
-backends, see the :ref:`Other authentication sources section
-<authentication-backends>` of the :doc:`User authentication guide
-</topics/auth>`.
-
-
-Available authentication backends
-=================================
-
-The following backends are available in :mod:`django.contrib.auth.backends`:
-
-.. class:: ModelBackend
-
- This is the default authentication backend used by Django. It
- authenticates using usernames and passwords stored in the
- :class:`~django.contrib.auth.models.User` model.
-
-
-.. class:: RemoteUserBackend
-
- Use this backend to take advantage of external-to-Django-handled
- authentication. It authenticates using usernames passed in
- :attr:`request.META['REMOTE_USER'] <django.http.HttpRequest.META>`. See
- the :doc:`Authenticating against REMOTE_USER </howto/auth-remote-user>`
- documentation.
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index 619b38e5ac..41f218b0a4 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -1,4 +1,430 @@
``django.contrib.auth``
=======================
-See :doc:`/topics/auth`.
+This document provides API reference material for the components of Django's
+authentication system. For more details on the usage of these components or
+how to customize authentication and authorization see the :doc:`authentication
+topic guide </topics/auth/index>`.
+
+.. currentmodule:: django.contrib.auth
+
+User
+====
+
+Fields
+------
+
+.. class:: models.User
+
+ :class:`~django.contrib.auth.models.User` objects have the following
+ fields:
+
+ .. attribute:: username
+
+ Required. 30 characters or fewer. Usernames may contain alphanumeric,
+ ``_``, ``@``, ``+``, ``.`` and ``-`` characters.
+
+ .. attribute:: first_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: last_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: email
+
+ Optional. Email address.
+
+ .. attribute:: password
+
+ Required. A hash of, and metadata about, the password. (Django doesn't
+ store the raw password.) Raw passwords can be arbitrarily long and can
+ contain any character. See the :doc:`password documentation
+ </topics/auth/passwords>`.
+
+ .. attribute:: groups
+
+ Many-to-many relationship to :class:`~django.contrib.auth.models.Group`
+
+ .. attribute:: user_permissions
+
+ Many-to-many relationship to :class:`~django.contrib.auth.models.Permission`
+
+ .. attribute:: is_staff
+
+ Boolean. Designates whether this user can access the admin site.
+
+ .. attribute:: is_active
+
+ Boolean. Designates whether this user account should be considered
+ active. We recommend that you set this flag to ``False`` instead of
+ deleting accounts; that way, if your applications have any foreign keys
+ to users, the foreign keys won't break.
+
+ This doesn't necessarily control whether or not the user can log in.
+ Authentication backends aren't required to check for the ``is_active``
+ flag, and the default backends do not. If you want to reject a login
+ based on ``is_active`` being ``False``, it's up to you to check that in
+ your own login view or a custom authentication backend. However, the
+ :class:`~django.contrib.auth.forms.AuthenticationForm` used by the
+ :func:`~django.contrib.auth.views.login` view (which is the default)
+ *does* perform this check, as do the permission-checking methods such
+ as :meth:`~django.contrib.auth.models.User.has_perm` and the
+ authentication in the Django admin. All of those functions/methods will
+ return ``False`` for inactive users.
+
+ .. attribute:: is_superuser
+
+ Boolean. Designates that this user has all permissions without
+ explicitly assigning them.
+
+ .. attribute:: last_login
+
+ A datetime of the user's last login. Is set to the current date/time by
+ default.
+
+ .. attribute:: date_joined
+
+ A datetime designating when the account was created. Is set to the
+ current date/time by default when the account is created.
+
+Methods
+-------
+
+.. class:: models.User
+
+ .. method:: get_username()
+
+ Returns the username for the user. Since the User model can be swapped
+ out, you should use this method instead of referencing the username
+ attribute directly.
+
+ .. method:: is_anonymous()
+
+ Always returns ``False``. This is a way of differentiating
+ :class:`~django.contrib.auth.models.User` and
+ :class:`~django.contrib.auth.models.AnonymousUser` objects.
+ Generally, you should prefer using
+ :meth:`~django.contrib.auth.models.User.is_authenticated()` to this
+ method.
+
+ .. method:: is_authenticated()
+
+ Always returns ``True``. This is a way to tell if the user has been
+ authenticated. This does not imply any permissions, and doesn't check
+ if the user is active - it only indicates that the user has provided a
+ valid username and password.
+
+ .. method:: get_full_name()
+
+ Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
+ the :attr:`~django.contrib.auth.models.User.last_name`, with a space in
+ between.
+
+ .. method:: set_password(raw_password)
+
+ Sets the user's password to the given raw string, taking care of the
+ password hashing. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ .. method:: check_password(raw_password)
+
+ Returns ``True`` if the given raw string is the correct password for
+ the user. (This takes care of the password hashing in making the
+ comparison.)
+
+ .. method:: set_unusable_password()
+
+ Marks the user as having no password set. This isn't the same as
+ having a blank string for a password.
+ :meth:`~django.contrib.auth.models.User.check_password()` for this user
+ will never return ``True``. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ You may need this if authentication for your application takes place
+ against an existing external source such as an LDAP directory.
+
+ .. method:: has_usable_password()
+
+ Returns ``False`` if
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
+ been called for this user.
+
+ .. method:: get_group_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, through his/her
+ groups.
+
+ If ``obj`` is passed in, only returns the group permissions for
+ this specific object.
+
+ .. method:: get_all_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, both through
+ group and user permissions.
+
+ If ``obj`` is passed in, only returns the permissions for this
+ specific object.
+
+ .. method:: has_perm(perm, obj=None)
+
+ Returns ``True`` if the user has the specified permission, where perm
+ is in the format ``"<app label>.<permission codename>"``. (see
+ documentation on :ref:`permissions <topic-authorization>`). If the user is
+ inactive, this method will always return ``False``.
+
+ If ``obj`` is passed in, this method won't check for a permission for
+ the model, but for this specific object.
+
+ .. method:: has_perms(perm_list, obj=None)
+
+ Returns ``True`` if the user has each of the specified permissions,
+ where each perm is in the format
+ ``"<app label>.<permission codename>"``. If the user is inactive,
+ this method will always return ``False``.
+
+ If ``obj`` is passed in, this method won't check for permissions for
+ the model, but for the specific object.
+
+ .. method:: has_module_perms(package_name)
+
+ Returns ``True`` if the user has any permissions in the given package
+ (the Django app label). If the user is inactive, this method will
+ always return ``False``.
+
+ .. method:: email_user(subject, message, from_email=None)
+
+ Sends an email to the user. If ``from_email`` is ``None``, Django uses
+ the :setting:`DEFAULT_FROM_EMAIL`.
+
+ .. method:: get_profile()
+
+ .. deprecated:: 1.5
+ With the introduction of :ref:`custom User models <auth-custom-user>`,
+ the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
+ model is no longer supported. See the
+ :doc:`Django 1.5 release notes</releases/1.5>` for more information.
+
+ Returns a site-specific profile for this user. Raises
+ ``django.contrib.auth.models.SiteProfileNotAvailable`` if the
+ current site doesn't allow profiles, or
+ :exc:`django.core.exceptions.ObjectDoesNotExist` if the user does not
+ have a profile.
+
+Manager methods
+---------------
+
+.. class:: models.UserManager
+
+ The :class:`~django.contrib.auth.models.User` model has a custom manager
+ that has the following helper methods:
+
+ .. method:: create_user(username, email=None, password=None)
+
+ .. versionchanged:: 1.4
+ The ``email`` parameter was made optional. The username
+ parameter is now checked for emptiness and raises a
+ :exc:`~exceptions.ValueError` in case of a negative result.
+
+ Creates, saves and returns a :class:`~django.contrib.auth.models.User`.
+
+ The :attr:`~django.contrib.auth.models.User.username` and
+ :attr:`~django.contrib.auth.models.User.password` are set as given. The
+ domain portion of :attr:`~django.contrib.auth.models.User.email` is
+ automatically converted to lowercase, and the returned
+ :class:`~django.contrib.auth.models.User` object will have
+ :attr:`~django.contrib.auth.models.User.is_active` set to ``True``.
+
+ If no password is provided,
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` will
+ be called.
+
+ See :ref:`Creating users <topics-auth-creating-users>` for example usage.
+
+ .. method:: make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
+
+ Returns a random password with the given length and given string of
+ allowed characters. (Note that the default value of ``allowed_chars``
+ doesn't contain letters that can cause user confusion, including:
+
+ * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
+ letter L, uppercase letter i, and the number one)
+ * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
+ and zero)
+
+
+Anonymous users
+===============
+
+.. class:: models.AnonymousUser
+
+ :class:`django.contrib.auth.models.AnonymousUser` is a class that
+ implements the :class:`django.contrib.auth.models.User` interface, with
+ these differences:
+
+ * :ref:`id <automatic-primary-key-fields>` is always ``None``.
+ * :attr:`~django.contrib.auth.models.User.is_staff` and
+ :attr:`~django.contrib.auth.models.User.is_superuser` are always
+ ``False``.
+ * :attr:`~django.contrib.auth.models.User.is_active` is always ``False``.
+ * :attr:`~django.contrib.auth.models.User.groups` and
+ :attr:`~django.contrib.auth.models.User.user_permissions` are always
+ empty.
+ * :meth:`~django.contrib.auth.models.User.is_anonymous()` returns ``True``
+ instead of ``False``.
+ * :meth:`~django.contrib.auth.models.User.is_authenticated()` returns
+ ``False`` instead of ``True``.
+ * :meth:`~django.contrib.auth.models.User.set_password()`,
+ :meth:`~django.contrib.auth.models.User.check_password()`,
+ :meth:`~django.db.models.Model.save` and
+ :meth:`~django.db.models.Model.delete()` raise
+ :exc:`~exceptions.NotImplementedError`.
+
+In practice, you probably won't need to use
+:class:`~django.contrib.auth.models.AnonymousUser` objects on your own, but
+they're used by Web requests, as explained in the next section.
+
+Permission
+==========
+
+.. class:: models.Permission
+
+Fields
+------
+
+:class:`~django.contrib.auth.models.Permission` objects have the following
+fields:
+
+.. attribute:: name
+
+ Required. 50 characters or fewer. Example: ``'Can vote'``.
+
+.. attribute:: content_type
+
+ Required. A reference to the ``django_content_type`` database table, which
+ contains a record for each installed Django model.
+
+.. attribute:: codename
+
+ Required. 100 characters or fewer. Example: ``'can_vote'``.
+
+Methods
+-------
+
+:class:`~django.contrib.auth.models.Permission` objects have the standard
+data-access methods like any other :doc:`Django model </ref/models/instances>`.
+
+Group
+=====
+
+.. class:: models.Group
+
+Fields
+------
+
+:class:`~django.contrib.auth.models.Group` objects have the following fields:
+
+.. attribute:: name
+
+ Required. 80 characters or fewer. Any characters are permitted. Example:
+ ``'Awesome Users'``.
+
+.. attribute:: permissions
+
+ Many-to-many field to :class:`~django.contrib.auth.models.Permission`::
+
+ group.permissions = [permission_list]
+ group.permissions.add(permission, permission, ...)
+ group.permissions.remove(permission, permission, ...)
+ group.permissions.clear()
+
+.. _topics-auth-signals:
+
+Login and logout signals
+========================
+
+.. module:: django.contrib.auth.signals
+
+The auth framework uses two :doc:`signals </topics/signals>` that can be used
+for notification when a user logs in or out.
+
+.. function:: django.contrib.auth.signals.user_logged_in
+
+ Sent when a user logs in successfully.
+
+ Arguments sent with this signal:
+
+ ``sender``
+ The class of the user that just logged in.
+
+ ``request``
+ The current :class:`~django.http.HttpRequest` instance.
+
+ ``user``
+ The user instance that just logged in.
+
+.. function:: django.contrib.auth.signals.user_logged_out
+
+ Sent when the logout method is called.
+
+ ``sender``
+ As above: the class of the user that just logged out or ``None``
+ if the user was not authenticated.
+
+ ``request``
+ The current :class:`~django.http.HttpRequest` instance.
+
+ ``user``
+ The user instance that just logged out or ``None`` if the
+ user was not authenticated.
+
+.. function:: django.contrib.auth.signals.user_login_failed
+
+.. versionadded:: 1.5
+
+ Sent when the user failed to login successfully
+
+ ``sender``
+ The name of the module used for authentication.
+
+ ``credentials``
+ A dictionary of keyword arguments containing the user credentials that were
+ passed to :func:`~django.contrib.auth.authenticate()` or your own custom
+ authentication backend. Credentials matching a set of 'sensitive' patterns,
+ (including password) will not be sent in the clear as part of the signal.
+
+.. _authentication-backends-reference:
+
+Authentication backends
+=======================
+
+.. module:: django.contrib.auth.backends
+ :synopsis: Django's built-in authentication backend classes.
+
+This section details the authentication backends that come with Django. For
+information on how to use them and how to write your own authentication
+backends, see the :ref:`Other authentication sources section
+<authentication-backends>` of the :doc:`User authentication guide
+</topics/auth/index>`.
+
+
+Available authentication backends
+---------------------------------
+
+The following backends are available in :mod:`django.contrib.auth.backends`:
+
+.. class:: ModelBackend
+
+ This is the default authentication backend used by Django. It
+ authenticates using usernames and passwords stored in the
+ :class:`~django.contrib.auth.models.User` model.
+
+
+.. class:: RemoteUserBackend
+
+ Use this backend to take advantage of external-to-Django-handled
+ authentication. It authenticates using usernames passed in
+ :attr:`request.META['REMOTE_USER'] <django.http.HttpRequest.META>`. See
+ the :doc:`Authenticating against REMOTE_USER </howto/auth-remote-user>`
+ documentation.
diff --git a/docs/ref/contrib/index.txt b/docs/ref/contrib/index.txt
index efe4393f64..3bf5288ee4 100644
--- a/docs/ref/contrib/index.txt
+++ b/docs/ref/contrib/index.txt
@@ -56,7 +56,7 @@ auth
Django's authentication framework.
-See :doc:`/topics/auth`.
+See :doc:`/topics/auth/index`.
comments
========
diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index 6ab3b1d133..205f349e8b 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -1145,7 +1145,7 @@ changepassword
.. django-admin:: changepassword
This command is only available if Django's :doc:`authentication system
-</topics/auth>` (``django.contrib.auth``) is installed.
+</topics/auth/index>` (``django.contrib.auth``) is installed.
Allows changing a user's password. It prompts you to enter twice the password of
the user given as parameter. If they both match, the new password will be
@@ -1167,7 +1167,7 @@ createsuperuser
.. django-admin:: createsuperuser
This command is only available if Django's :doc:`authentication system
-</topics/auth>` (``django.contrib.auth``) is installed.
+</topics/auth/index>` (``django.contrib.auth``) is installed.
Creates a superuser account (a user who has all permissions). This is
useful if you need to create an initial superuser account but did not
diff --git a/docs/ref/index.txt b/docs/ref/index.txt
index e1959d44a6..fc874a97eb 100644
--- a/docs/ref/index.txt
+++ b/docs/ref/index.txt
@@ -5,7 +5,6 @@ API Reference
.. toctree::
:maxdepth: 1
- authbackends
class-based-views/index
clickjacking
contrib/index
diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt
index b542aee6e2..41cff346ff 100644
--- a/docs/ref/middleware.txt
+++ b/docs/ref/middleware.txt
@@ -179,8 +179,8 @@ Authentication middleware
.. class:: AuthenticationMiddleware
Adds the ``user`` attribute, representing the currently-logged-in user, to
-every incoming ``HttpRequest`` object. See :doc:`Authentication in Web requests
-</topics/auth>`.
+every incoming ``HttpRequest`` object. See :ref:`Authentication in Web requests
+<auth-web-requests>`.
CSRF protection middleware
--------------------------
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index c3ba99168d..2775c974d0 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -181,7 +181,7 @@ All attributes should be considered read-only, unless stated otherwise below.
``user`` is only available if your Django installation has the
``AuthenticationMiddleware`` activated. For more, see
- :doc:`/topics/auth`.
+ :doc:`/topics/auth/index`.
.. attribute:: HttpRequest.session
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 7cb33a038d..5815062266 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -107,8 +107,8 @@ AUTHENTICATION_BACKENDS
Default: ``('django.contrib.auth.backends.ModelBackend',)``
A tuple of authentication backend classes (as strings) to use when attempting to
-authenticate a user. See the :doc:`authentication backends documentation
-</ref/authbackends>` for details.
+authenticate a user. See the :ref:`authentication backends documentation
+<authentication-backends>` for details.
.. setting:: AUTH_USER_MODEL
@@ -2256,7 +2256,7 @@ AUTH_PROFILE_MODULE
Default: Not defined
The site-specific user profile model used by this site. See
-:ref:`auth-profiles`.
+:ref:`User profiles <auth-profiles>`.
.. setting:: IGNORABLE_404_ENDS
diff --git a/docs/ref/signals.txt b/docs/ref/signals.txt
index 2eefb0ca77..0671d80b7c 100644
--- a/docs/ref/signals.txt
+++ b/docs/ref/signals.txt
@@ -12,7 +12,7 @@ A list of all the signals that Django sends.
The :doc:`comment framework </ref/contrib/comments/index>` sends a :doc:`set
of comment-related signals </ref/contrib/comments/signals>`.
- The :doc:`authentication framework </topics/auth>` sends :ref:`signals when
+ The :doc:`authentication framework </topics/auth/index>` sends :ref:`signals when
a user is logged in / out <topics-auth-signals>`.
Model signals
diff --git a/docs/releases/1.2-beta-1.txt b/docs/releases/1.2-beta-1.txt
index 99cd274957..3549767379 100644
--- a/docs/releases/1.2-beta-1.txt
+++ b/docs/releases/1.2-beta-1.txt
@@ -91,7 +91,7 @@ added in Django 1.2 alpha but not documented with the alpha release.
The default authentication backends shipped with Django do not
currently make use of this, but third-party authentication backends
-are free to do so. See the :doc:`authentication docs </topics/auth>`
+are free to do so. See the :doc:`authentication docs </topics/auth/index>`
for more information.
@@ -104,7 +104,7 @@ class will check the backend for permissions, just as the normal
``User`` does. This is intended to help centralize permission
handling; apps can always delegate the question of whether something
is allowed or not to the authorization/authentication system. See the
-:doc:`authentication docs </topics/auth>` for more details.
+:doc:`authentication docs </topics/auth/index>` for more details.
``select_related()`` improvements
diff --git a/docs/releases/1.2.txt b/docs/releases/1.2.txt
index 26a9405595..68cec91587 100644
--- a/docs/releases/1.2.txt
+++ b/docs/releases/1.2.txt
@@ -165,7 +165,7 @@ A foundation for specifying permissions at the per-object level has been added.
Although there is no implementation of this in core, a custom authentication
backend can provide this implementation and it will be used by
:class:`django.contrib.auth.models.User`. See the :doc:`authentication docs
-</topics/auth>` for more information.
+</topics/auth/index>` for more information.
Permissions for anonymous users
-------------------------------
@@ -175,7 +175,7 @@ If you provide a custom auth backend with ``supports_anonymous_user`` set to
User already did. This is useful for centralizing permission handling - apps
can always delegate the question of whether something is allowed or not to
the authorization/authentication backend. See the :doc:`authentication
-docs </topics/auth>` for more details.
+docs </topics/auth/index>` for more details.
Relaxed requirements for usernames
----------------------------------
diff --git a/docs/releases/1.3-beta-1.txt b/docs/releases/1.3-beta-1.txt
index 02c038f459..2729c7f2ba 100644
--- a/docs/releases/1.3-beta-1.txt
+++ b/docs/releases/1.3-beta-1.txt
@@ -61,7 +61,7 @@ Permissions for inactive users
If you provide a custom auth backend with ``supports_inactive_user`` set to
``True``, an inactive user model will check the backend for permissions.
This is useful for further centralizing the permission handling. See the
-:doc:`authentication docs </topics/auth>` for more details.
+:doc:`authentication docs </topics/auth/index>` for more details.
Backwards-incompatible changes in 1.3 alpha 2
=============================================
diff --git a/docs/releases/1.3.txt b/docs/releases/1.3.txt
index c507f1bed6..d6ef11d113 100644
--- a/docs/releases/1.3.txt
+++ b/docs/releases/1.3.txt
@@ -254,7 +254,7 @@ Permissions for inactive users
If you provide a custom auth backend with ``supports_inactive_user``
set to ``True``, an inactive ``User`` instance will check the backend
for permissions. This is useful for further centralizing the
-permission handling. See the :doc:`authentication docs </topics/auth>`
+permission handling. See the :doc:`authentication docs </topics/auth/index>`
for more details.
GeoDjango
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
deleted file mode 100644
index e7a0ff114e..0000000000
--- a/docs/topics/auth.txt
+++ /dev/null
@@ -1,2696 +0,0 @@
-=============================
-User authentication in Django
-=============================
-
-.. module:: django.contrib.auth
- :synopsis: Django's authentication framework.
-
-Django comes with a user authentication system. It handles user accounts,
-groups, permissions and cookie-based user sessions. This document explains how
-things work.
-
-Overview
-========
-
-The auth system consists of:
-
-* Users
-* Permissions: Binary (yes/no) flags designating whether a user may perform
- a certain task.
-* Groups: A generic way of applying labels and permissions to more than one
- user.
-
-Installation
-============
-
-Authentication support is bundled as a Django application in
-``django.contrib.auth``. To install it, do the following:
-
-1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
- your :setting:`INSTALLED_APPS` setting.
- (The :class:`~django.contrib.auth.models.Permission` model in
- :mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.)
-2. Run the command ``manage.py syncdb``.
-
-Note that the default :file:`settings.py` file created by
-:djadmin:`django-admin.py startproject <startproject>` includes
-``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
-:setting:`INSTALLED_APPS` for convenience. If your :setting:`INSTALLED_APPS`
-already contains these apps, feel free to run :djadmin:`manage.py syncdb
-<syncdb>` again; you can run that command as many times as you'd like, and each
-time it'll only install what's needed.
-
-The :djadmin:`syncdb` command creates the necessary database tables, creates
-permission objects for all installed apps that need 'em, and prompts you to
-create a superuser account the first time you run it.
-
-Once you've taken those steps, that's it.
-
-Users
-=====
-
-.. class:: models.User
-
-API reference
--------------
-
-Fields
-~~~~~~
-
-.. class:: models.User
-
- :class:`~django.contrib.auth.models.User` objects have the following
- fields:
-
- .. attribute:: models.User.username
-
- Required. 30 characters or fewer. Usernames may contain alphanumeric,
- ``_``, ``@``, ``+``, ``.`` and ``-`` characters.
-
- .. attribute:: models.User.first_name
-
- Optional. 30 characters or fewer.
-
- .. attribute:: models.User.last_name
-
- Optional. 30 characters or fewer.
-
- .. attribute:: models.User.email
-
- Optional. Email address.
-
- .. attribute:: models.User.password
-
- Required. A hash of, and metadata about, the password. (Django doesn't
- store the raw password.) Raw passwords can be arbitrarily long and can
- contain any character. See the "Passwords" section below.
-
- .. attribute:: models.User.is_staff
-
- Boolean. Designates whether this user can access the admin site.
-
- .. attribute:: models.User.is_active
-
- Boolean. Designates whether this user account should be considered
- active. We recommend that you set this flag to ``False`` instead of
- deleting accounts; that way, if your applications have any foreign keys
- to users, the foreign keys won't break.
-
- This doesn't necessarily control whether or not the user can log in.
- Authentication backends aren't required to check for the ``is_active``
- flag, and the default backends do not. If you want to reject a login
- based on ``is_active`` being ``False``, it's up to you to check that in
- your own login view or a custom authentication backend. However, the
- :class:`~django.contrib.auth.forms.AuthenticationForm` used by the
- :func:`~django.contrib.auth.views.login` view (which is the default)
- *does* perform this check, as do the permission-checking methods such
- as :meth:`~models.User.has_perm` and the authentication in the Django
- admin. All of those functions/methods will return ``False`` for
- inactive users.
-
- .. attribute:: models.User.is_superuser
-
- Boolean. Designates that this user has all permissions without
- explicitly assigning them.
-
- .. attribute:: models.User.last_login
-
- A datetime of the user's last login. Is set to the current date/time by
- default.
-
- .. attribute:: models.User.date_joined
-
- A datetime designating when the account was created. Is set to the
- current date/time by default when the account is created.
-
-Methods
-~~~~~~~
-
-.. class:: models.User
-
- :class:`~django.contrib.auth.models.User` objects have two many-to-many
- fields: ``groups`` and ``user_permissions``.
- :class:`~django.contrib.auth.models.User` objects can access their related
- objects in the same way as any other :doc:`Django model
- </topics/db/models>`:
-
- .. code-block:: python
-
- myuser.groups = [group_list]
- myuser.groups.add(group, group, ...)
- myuser.groups.remove(group, group, ...)
- myuser.groups.clear()
- myuser.user_permissions = [permission_list]
- myuser.user_permissions.add(permission, permission, ...)
- myuser.user_permissions.remove(permission, permission, ...)
- myuser.user_permissions.clear()
-
- In addition to those automatic API methods,
- :class:`~django.contrib.auth.models.User` objects have the following custom
- methods:
-
- .. method:: models.User.get_username()
-
- Returns the username for the user. Since the User model can be swapped
- out, you should use this method instead of referencing the username
- attribute directly.
-
- .. method:: models.User.is_anonymous()
-
- Always returns ``False``. This is a way of differentiating
- :class:`~django.contrib.auth.models.User` and
- :class:`~django.contrib.auth.models.AnonymousUser` objects.
- Generally, you should prefer using
- :meth:`~django.contrib.auth.models.User.is_authenticated()` to this
- method.
-
- .. method:: models.User.is_authenticated()
-
- Always returns ``True``. This is a way to tell if the user has been
- authenticated. This does not imply any permissions, and doesn't check
- if the user is active - it only indicates that the user has provided a
- valid username and password.
-
- .. method:: models.User.get_full_name()
-
- Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
- the :attr:`~django.contrib.auth.models.User.last_name`, with a space in
- between.
-
- .. method:: models.User.set_password(raw_password)
-
- Sets the user's password to the given raw string, taking care of the
- password hashing. Doesn't save the
- :class:`~django.contrib.auth.models.User` object.
-
- .. method:: models.User.check_password(raw_password)
-
- Returns ``True`` if the given raw string is the correct password for
- the user. (This takes care of the password hashing in making the
- comparison.)
-
- .. method:: models.User.set_unusable_password()
-
- Marks the user as having no password set. This isn't the same as
- having a blank string for a password.
- :meth:`~django.contrib.auth.models.User.check_password()` for this user
- will never return ``True``. Doesn't save the
- :class:`~django.contrib.auth.models.User` object.
-
- You may need this if authentication for your application takes place
- against an existing external source such as an LDAP directory.
-
- .. method:: models.User.has_usable_password()
-
- Returns ``False`` if
- :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
- been called for this user.
-
- .. method:: models.User.get_group_permissions(obj=None)
-
- Returns a set of permission strings that the user has, through his/her
- groups.
-
- If ``obj`` is passed in, only returns the group permissions for
- this specific object.
-
- .. method:: models.User.get_all_permissions(obj=None)
-
- Returns a set of permission strings that the user has, both through
- group and user permissions.
-
- If ``obj`` is passed in, only returns the permissions for this
- specific object.
-
- .. method:: models.User.has_perm(perm, obj=None)
-
- Returns ``True`` if the user has the specified permission, where perm is
- in the format ``"<app label>.<permission codename>"``. (see
- `permissions`_ section below). If the user is inactive, this method will
- always return ``False``.
-
- If ``obj`` is passed in, this method won't check for a permission for
- the model, but for this specific object.
-
- .. method:: models.User.has_perms(perm_list, obj=None)
-
- Returns ``True`` if the user has each of the specified permissions,
- where each perm is in the format
- ``"<app label>.<permission codename>"``. If the user is inactive,
- this method will always return ``False``.
-
- If ``obj`` is passed in, this method won't check for permissions for
- the model, but for the specific object.
-
- .. method:: models.User.has_module_perms(package_name)
-
- Returns ``True`` if the user has any permissions in the given package
- (the Django app label). If the user is inactive, this method will
- always return ``False``.
-
- .. method:: models.User.email_user(subject, message, from_email=None)
-
- Sends an email to the user. If
- :attr:`~django.contrib.auth.models.User.from_email` is ``None``, Django
- uses the :setting:`DEFAULT_FROM_EMAIL`.
-
- .. method:: models.User.get_profile()
-
- .. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
-
- Returns a site-specific profile for this user. Raises
- :exc:`django.contrib.auth.models.SiteProfileNotAvailable` if the
- current site doesn't allow profiles, or
- :exc:`django.core.exceptions.ObjectDoesNotExist` if the user does not
- have a profile. For information on how to define a site-specific user
- profile, see the section on `storing additional user information`_ below.
-
-.. _storing additional user information: #storing-additional-information-about-users
-
-Manager functions
-~~~~~~~~~~~~~~~~~
-
-.. class:: models.UserManager
-
- The :class:`~django.contrib.auth.models.User` model has a custom manager
- that has the following helper functions:
-
- .. method:: models.UserManager.create_user(username, email=None, password=None)
-
- .. versionchanged:: 1.4
- The ``email`` parameter was made optional. The username
- parameter is now checked for emptiness and raises a
- :exc:`~exceptions.ValueError` in case of a negative result.
-
- Creates, saves and returns a :class:`~django.contrib.auth.models.User`.
-
- The :attr:`~django.contrib.auth.models.User.username` and
- :attr:`~django.contrib.auth.models.User.password` are set as given. The
- domain portion of :attr:`~django.contrib.auth.models.User.email` is
- automatically converted to lowercase, and the returned
- :class:`~django.contrib.auth.models.User` object will have
- :attr:`~models.User.is_active` set to ``True``.
-
- If no password is provided,
- :meth:`~django.contrib.auth.models.User.set_unusable_password()` will
- be called.
-
- See `Creating users`_ for example usage.
-
- .. method:: models.UserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
-
- Returns a random password with the given length and given string of
- allowed characters. (Note that the default value of ``allowed_chars``
- doesn't contain letters that can cause user confusion, including:
-
- * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
- letter L, uppercase letter i, and the number one)
- * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
- and zero)
-
-Basic usage
------------
-
-.. _topics-auth-creating-users:
-
-Creating users
-~~~~~~~~~~~~~~
-
-The most basic way to create users is to use the
-:meth:`~django.contrib.auth.models.UserManager.create_user` helper function
-that comes with Django::
-
- >>> from django.contrib.auth.models import User
- >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
-
- # At this point, user is a User object that has already been saved
- # to the database. You can continue to change its attributes
- # if you want to change other fields.
- >>> user.is_staff = True
- >>> user.save()
-
-You can also create users using the Django admin site. Assuming you've enabled
-the admin site and hooked it to the URL ``/admin/``, the "Add user" page is at
-``/admin/auth/user/add/``. You should also see a link to "Users" in the "Auth"
-section of the main admin index page. The "Add user" admin page is different
-than standard admin pages in that it requires you to choose a username and
-password before allowing you to edit the rest of the user's fields.
-
-Also note: if you want your own user account to be able to create users using
-the Django admin site, you'll need to give yourself permission to add users
-*and* change users (i.e., the "Add user" and "Change user" permissions). If
-your account has permission to add users but not to change them, you won't be
-able to add users. Why? Because if you have permission to add users, you have
-the power to create superusers, which can then, in turn, change other users. So
-Django requires add *and* change permissions as a slight security measure.
-
-Changing passwords
-~~~~~~~~~~~~~~~~~~
-
-:djadmin:`manage.py changepassword *username* <changepassword>` offers a method
-of changing a User's password from the command line. It prompts you to
-change the password of a given user which you must enter twice. If
-they both match, the new password will be changed immediately. If you
-do not supply a user, the command will attempt to change the password
-whose username matches the current user.
-
-You can also change a password programmatically, using
-:meth:`~django.contrib.auth.models.User.set_password()`:
-
-.. code-block:: python
-
- >>> from django.contrib.auth.models import User
- >>> u = User.objects.get(username__exact='john')
- >>> u.set_password('new password')
- >>> u.save()
-
-Don't set the :attr:`~django.contrib.auth.models.User.password` attribute
-directly unless you know what you're doing. This is explained in the next
-section.
-
-.. _auth_password_storage:
-
-How Django stores passwords
----------------------------
-
-.. versionadded:: 1.4
- Django 1.4 introduces a new flexible password storage system and uses
- PBKDF2 by default. Previous versions of Django used SHA1, and other
- algorithms couldn't be chosen.
-
-The :attr:`~django.contrib.auth.models.User.password` attribute of a
-:class:`~django.contrib.auth.models.User` object is a string in this format::
-
- algorithm$hash
-
-That's a storage algorithm, and hash, separated by the dollar-sign
-character. The algorithm is one of a number of one way hashing or password
-storage algorithms Django can use; see below. The hash is the result of the one-
-way function.
-
-By default, Django uses the PBKDF2_ algorithm with a SHA256 hash, a
-password stretching mechanism recommended by NIST_. This should be
-sufficient for most users: it's quite secure, requiring massive
-amounts of computing time to break.
-
-However, depending on your requirements, you may choose a different
-algorithm, or even use a custom algorithm to match your specific
-security situation. Again, most users shouldn't need to do this -- if
-you're not sure, you probably don't. If you do, please read on:
-
-Django chooses the an algorithm by consulting the :setting:`PASSWORD_HASHERS`
-setting. This is a list of hashing algorithm classes that this Django
-installation supports. The first entry in this list (that is,
-``settings.PASSWORD_HASHERS[0]``) will be used to store passwords, and all the
-other entries are valid hashers that can be used to check existing passwords.
-This means that if you want to use a different algorithm, you'll need to modify
-:setting:`PASSWORD_HASHERS` to list your preferred algorithm first in the list.
-
-The default for :setting:`PASSWORD_HASHERS` is::
-
- PASSWORD_HASHERS = (
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
-
-This means that Django will use PBKDF2_ to store all passwords, but will support
-checking passwords stored with PBKDF2SHA1, bcrypt_, SHA1_, etc. The next few
-sections describe a couple of common ways advanced users may want to modify this
-setting.
-
-.. _bcrypt_usage:
-
-Using bcrypt with Django
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Bcrypt_ is a popular password storage algorithm that's specifically designed
-for long-term password storage. It's not the default used by Django since it
-requires the use of third-party libraries, but since many people may want to
-use it Django supports bcrypt with minimal effort.
-
-To use Bcrypt as your default storage algorithm, do the following:
-
-1. Install the `py-bcrypt`_ library (probably by running ``sudo pip install
- py-bcrypt``, or downloading the library and installing it with ``python
- setup.py install``).
-
-2. Modify :setting:`PASSWORD_HASHERS` to list ``BCryptPasswordHasher``
- first. That is, in your settings file, you'd put::
-
- PASSWORD_HASHERS = (
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
-
- (You need to keep the other entries in this list, or else Django won't
- be able to upgrade passwords; see below).
-
-That's it -- now your Django install will use Bcrypt as the default storage
-algorithm.
-
-.. admonition:: Other bcrypt implementations
-
- There are several other implementations that allow bcrypt to be
- used with Django. Django's bcrypt support is NOT directly
- compatible with these. To upgrade, you will need to modify the
- hashes in your database to be in the form `bcrypt$(raw bcrypt
- output)`. For example:
- `bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy`.
-
-Increasing the work factor
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The PBKDF2 and bcrypt algorithms use a number of iterations or rounds of
-hashing. This deliberately slows down attackers, making attacks against hashed
-passwords harder. However, as computing power increases, the number of
-iterations needs to be increased. We've chosen a reasonable default (and will
-increase it with each release of Django), but you may wish to tune it up or
-down, depending on your security needs and available processing power. To do so,
-you'll subclass the appropriate algorithm and override the ``iterations``
-parameters. For example, to increase the number of iterations used by the
-default PBKDF2 algorithm:
-
-1. Create a subclass of ``django.contrib.auth.hashers.PBKDF2PasswordHasher``::
-
- from django.contrib.auth.hashers import PBKDF2PasswordHasher
-
- class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
- """
- A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
- """
- iterations = PBKDF2PasswordHasher.iterations * 100
-
- Save this somewhere in your project. For example, you might put this in
- a file like ``myproject/hashers.py``.
-
-2. Add your new hasher as the first entry in :setting:`PASSWORD_HASHERS`::
-
- PASSWORD_HASHERS = (
- 'myproject.hashers.MyPBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
- 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
- 'django.contrib.auth.hashers.BCryptPasswordHasher',
- 'django.contrib.auth.hashers.SHA1PasswordHasher',
- 'django.contrib.auth.hashers.MD5PasswordHasher',
- 'django.contrib.auth.hashers.CryptPasswordHasher',
- )
-
-
-That's it -- now your Django install will use more iterations when it
-stores passwords using PBKDF2.
-
-Password upgrading
-~~~~~~~~~~~~~~~~~~
-
-When users log in, if their passwords are stored with anything other than
-the preferred algorithm, Django will automatically upgrade the algorithm
-to the preferred one. This means that old installs of Django will get
-automatically more secure as users log in, and it also means that you
-can switch to new (and better) storage algorithms as they get invented.
-
-However, Django can only upgrade passwords that use algorithms mentioned in
-:setting:`PASSWORD_HASHERS`, so as you upgrade to new systems you should make
-sure never to *remove* entries from this list. If you do, users using un-
-mentioned algorithms won't be able to upgrade.
-
-.. _sha1: http://en.wikipedia.org/wiki/SHA1
-.. _pbkdf2: http://en.wikipedia.org/wiki/PBKDF2
-.. _nist: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
-.. _bcrypt: http://en.wikipedia.org/wiki/Bcrypt
-.. _py-bcrypt: http://pypi.python.org/pypi/py-bcrypt/
-
-Anonymous users
----------------
-
-.. class:: models.AnonymousUser
-
- :class:`django.contrib.auth.models.AnonymousUser` is a class that
- implements the :class:`django.contrib.auth.models.User` interface, with
- these differences:
-
- * :attr:`~django.contrib.auth.models.User.id` is always ``None``.
- * :attr:`~django.contrib.auth.models.User.is_staff` and
- :attr:`~django.contrib.auth.models.User.is_superuser` are always
- ``False``.
- * :attr:`~django.contrib.auth.models.User.is_active` is always ``False``.
- * :attr:`~django.contrib.auth.models.User.groups` and
- :attr:`~django.contrib.auth.models.User.user_permissions` are always
- empty.
- * :meth:`~django.contrib.auth.models.User.is_anonymous()` returns ``True``
- instead of ``False``.
- * :meth:`~django.contrib.auth.models.User.is_authenticated()` returns
- ``False`` instead of ``True``.
- * :meth:`~django.contrib.auth.models.User.set_password()`,
- :meth:`~django.contrib.auth.models.User.check_password()`,
- :meth:`~django.contrib.auth.models.User.save()`,
- :meth:`~django.contrib.auth.models.User.delete()`,
- :meth:`~django.contrib.auth.models.User.set_groups()` and
- :meth:`~django.contrib.auth.models.User.set_permissions()` raise
- :exc:`~exceptions.NotImplementedError`.
-
-In practice, you probably won't need to use
-:class:`~django.contrib.auth.models.AnonymousUser` objects on your own, but
-they're used by Web requests, as explained in the next section.
-
-.. _topics-auth-creating-superusers:
-
-Creating superusers
--------------------
-
-:djadmin:`manage.py syncdb <syncdb>` prompts you to create a superuser the
-first time you run it after adding ``'django.contrib.auth'`` to your
-:setting:`INSTALLED_APPS`. If you need to create a superuser at a later date,
-you can use a command line utility::
-
- manage.py createsuperuser --username=joe --email=joe@example.com
-
-You will be prompted for a password. After you enter one, the user will be
-created immediately. If you leave off the :djadminopt:`--username` or the
-:djadminopt:`--email` options, it will prompt you for those values.
-
-If you're using an older release of Django, the old way of creating a superuser
-on the command line still works::
-
- python /path/to/django/contrib/auth/create_superuser.py
-
-...where :file:`/path/to` is the path to the Django codebase on your
-filesystem. The ``manage.py`` command is preferred because it figures out the
-correct path and environment for you.
-
-.. _auth-profiles:
-
-Storing additional information about users
-------------------------------------------
-
-.. deprecated:: 1.5
- With the introduction of :ref:`custom User models <auth-custom-user>`,
- the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
- model is no longer supported. See the
- :doc:`Django 1.5 release notes</releases/1.5>` for more information.
-
-If you'd like to store additional information related to your users, Django
-provides a method to specify a site-specific related model -- termed a "user
-profile" -- for this purpose.
-
-To make use of this feature, define a model with fields for the
-additional information you'd like to store, or additional methods
-you'd like to have available, and also add a
-:class:`~django.db.models.Field.OneToOneField` named ``user`` from your model
-to the :class:`~django.contrib.auth.models.User` model. This will ensure only
-one instance of your model can be created for each
-:class:`~django.contrib.auth.models.User`. For example::
-
- from django.contrib.auth.models import User
-
- class UserProfile(models.Model):
- # This field is required.
- user = models.OneToOneField(User)
-
- # Other fields here
- accepted_eula = models.BooleanField()
- favorite_animal = models.CharField(max_length=20, default="Dragons.")
-
-
-To indicate that this model is the user profile model for a given site, fill in
-the setting :setting:`AUTH_PROFILE_MODULE` with a string consisting of the
-following items, separated by a dot:
-
-1. The name of the application (case sensitive) in which the user
- profile model is defined (in other words, the
- name which was passed to :djadmin:`manage.py startapp <startapp>` to create
- the application).
-
-2. The name of the model (not case sensitive) class.
-
-For example, if the profile model was a class named ``UserProfile`` and was
-defined inside an application named ``accounts``, the appropriate setting would
-be::
-
- AUTH_PROFILE_MODULE = 'accounts.UserProfile'
-
-When a user profile model has been defined and specified in this manner, each
-:class:`~django.contrib.auth.models.User` object will have a method --
-:class:`~django.contrib.auth.models.User.get_profile()` -- which returns the
-instance of the user profile model associated with that
-:class:`~django.contrib.auth.models.User`.
-
-The method :class:`~django.contrib.auth.models.User.get_profile()`
-does not create a profile if one does not exist. You need to register a handler
-for the User model's :attr:`django.db.models.signals.post_save` signal and, in
-the handler, if ``created`` is ``True``, create the associated user profile::
-
- # in models.py
-
- from django.contrib.auth.models import User
- from django.db.models.signals import post_save
-
- # definition of UserProfile from above
- # ...
-
- def create_user_profile(sender, instance, created, **kwargs):
- if created:
- UserProfile.objects.create(user=instance)
-
- post_save.connect(create_user_profile, sender=User)
-
-.. seealso:: :doc:`/topics/signals` for more information on Django's signal
- dispatcher.
-
-Adding UserProfile fields to the admin
---------------------------------------
-
-To add the UserProfile fields to the user page in the admin, define an
-:class:`~django.contrib.admin.InlineModelAdmin` (for this example, we'll use a
-:class:`~django.contrib.admin.StackedInline`) in your app's ``admin.py`` and
-add it to a ``UserAdmin`` class which is registered with the
-:class:`~django.contrib.auth.models.User` class::
-
- from django.contrib import admin
- from django.contrib.auth.admin import UserAdmin
- from django.contrib.auth.models import User
-
- from my_user_profile_app.models import UserProfile
-
- # Define an inline admin descriptor for UserProfile model
- # which acts a bit like a singleton
- class UserProfileInline(admin.StackedInline):
- model = UserProfile
- can_delete = False
- verbose_name_plural = 'profile'
-
- # Define a new User admin
- class UserAdmin(UserAdmin):
- inlines = (UserProfileInline, )
-
- # Re-register UserAdmin
- admin.site.unregister(User)
- admin.site.register(User, UserAdmin)
-
-Authentication in Web requests
-==============================
-
-Until now, this document has dealt with the low-level APIs for manipulating
-authentication-related objects. On a higher level, Django can hook this
-authentication framework into its system of
-:class:`request objects <django.http.HttpRequest>`.
-
-First, install the
-:class:`~django.contrib.sessions.middleware.SessionMiddleware` and
-:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
-middlewares by adding them to your :setting:`MIDDLEWARE_CLASSES` setting. See
-the :doc:`session documentation </topics/http/sessions>` for more information.
-
-Once you have those middlewares installed, you'll be able to access
-:attr:`request.user <django.http.HttpRequest.user>` in views.
-:attr:`request.user <django.http.HttpRequest.user>` will give you a
-:class:`~django.contrib.auth.models.User` object representing the currently
-logged-in user. If a user isn't currently logged in,
-:attr:`request.user <django.http.HttpRequest.user>` will be set to an instance
-of :class:`~django.contrib.auth.models.AnonymousUser` (see the previous
-section). You can tell them apart with
-:meth:`~django.contrib.auth.models.User.is_authenticated()`, like so::
-
- if request.user.is_authenticated():
- # Do something for authenticated users.
- else:
- # Do something for anonymous users.
-
-.. _how-to-log-a-user-in:
-
-How to log a user in
---------------------
-
-Django provides two functions in :mod:`django.contrib.auth`:
-:func:`~django.contrib.auth.authenticate()` and
-:func:`~django.contrib.auth.login()`.
-
-.. function:: authenticate()
-
- To authenticate a given username and password, use
- :func:`~django.contrib.auth.authenticate()`. It takes two keyword
- arguments, ``username`` and ``password``, and it returns a
- :class:`~django.contrib.auth.models.User` object if the password is valid
- for the given username. If the password is invalid,
- :func:`~django.contrib.auth.authenticate()` returns ``None``. Example::
-
- from django.contrib.auth import authenticate
- user = authenticate(username='john', password='secret')
- if user is not None:
- if user.is_active:
- print("You provided a correct username and password!")
- else:
- print("Your account has been disabled!")
- else:
- print("Your username and password were incorrect.")
-
-.. function:: login()
-
- To log a user in, in a view, use :func:`~django.contrib.auth.login()`. It
- takes an :class:`~django.http.HttpRequest` object and a
- :class:`~django.contrib.auth.models.User` object.
- :func:`~django.contrib.auth.login()` saves the user's ID in the session,
- using Django's session framework, so, as mentioned above, you'll need to
- make sure to have the session middleware installed.
-
- Note that data set during the anonymous session is retained when the user
- logs in.
-
- This example shows how you might use both
- :func:`~django.contrib.auth.authenticate()` and
- :func:`~django.contrib.auth.login()`::
-
- from django.contrib.auth import authenticate, login
-
- def my_view(request):
- username = request.POST['username']
- password = request.POST['password']
- user = authenticate(username=username, password=password)
- if user is not None:
- if user.is_active:
- login(request, user)
- # Redirect to a success page.
- else:
- # Return a 'disabled account' error message
- else:
- # Return an 'invalid login' error message.
-
-.. admonition:: Calling ``authenticate()`` first
-
- When you're manually logging a user in, you *must* call
- :func:`~django.contrib.auth.authenticate()` before you call
- :func:`~django.contrib.auth.login()`.
- :func:`~django.contrib.auth.authenticate()`
- sets an attribute on the :class:`~django.contrib.auth.models.User` noting
- which authentication backend successfully authenticated that user (see the
- `backends documentation`_ for details), and this information is needed
- later during the login process.
-
-.. _backends documentation: #other-authentication-sources
-
-Manually managing a user's password
------------------------------------
-
-.. currentmodule:: django.contrib.auth.hashers
-
-.. versionadded:: 1.4
- The :mod:`django.contrib.auth.hashers` module provides a set of functions
- to create and validate hashed password. You can use them independently
- from the ``User`` model.
-
-.. function:: check_password(password, encoded)
-
- .. versionadded:: 1.4
-
- If you'd like to manually authenticate a user by comparing a plain-text
- password to the hashed password in the database, use the convenience
- function :func:`django.contrib.auth.hashers.check_password`. It takes two
- arguments: the plain-text password to check, and the full value of a
- user's ``password`` field in the database to check against, and returns
- ``True`` if they match, ``False`` otherwise.
-
-.. function:: make_password(password[, salt, hashers])
-
- .. versionadded:: 1.4
-
- Creates a hashed password in the format used by this application. It takes
- one mandatory argument: the password in plain-text. Optionally, you can
- provide a salt and a hashing algorithm to use, if you don't want to use the
- defaults (first entry of ``PASSWORD_HASHERS`` setting).
- Currently supported algorithms are: ``'pbkdf2_sha256'``, ``'pbkdf2_sha1'``,
- ``'bcrypt'`` (see :ref:`bcrypt_usage`), ``'sha1'``, ``'md5'``,
- ``'unsalted_md5'`` (only for backward compatibility) and ``'crypt'``
- if you have the ``crypt`` library installed. If the password argument is
- ``None``, an unusable password is returned (a one that will be never
- accepted by :func:`django.contrib.auth.hashers.check_password`).
-
-.. function:: is_password_usable(encoded_password)
-
- .. versionadded:: 1.4
-
- Checks if the given string is a hashed password that has a chance
- of being verified against :func:`django.contrib.auth.hashers.check_password`.
-
-
-How to log a user out
----------------------
-
-.. currentmodule:: django.contrib.auth
-
-.. function:: logout()
-
- To log out a user who has been logged in via
- :func:`django.contrib.auth.login()`, use
- :func:`django.contrib.auth.logout()` within your view. It takes an
- :class:`~django.http.HttpRequest` object and has no return value.
- Example::
-
- from django.contrib.auth import logout
-
- def logout_view(request):
- logout(request)
- # Redirect to a success page.
-
- Note that :func:`~django.contrib.auth.logout()` doesn't throw any errors if
- the user wasn't logged in.
-
- When you call :func:`~django.contrib.auth.logout()`, the session data for
- the current request is completely cleaned out. All existing data is
- removed. This is to prevent another person from using the same Web browser
- to log in and have access to the previous user's session data. If you want
- to put anything into the session that will be available to the user
- immediately after logging out, do that *after* calling
- :func:`django.contrib.auth.logout()`.
-
-.. _topics-auth-signals:
-
-Login and logout signals
-------------------------
-
-The auth framework uses two :doc:`signals </topics/signals>` that can be used
-for notification when a user logs in or out.
-
-.. data:: django.contrib.auth.signals.user_logged_in
- :module:
-
-Sent when a user logs in successfully.
-
-Arguments sent with this signal:
-
-``sender``
- The class of the user that just logged in.
-
-``request``
- The current :class:`~django.http.HttpRequest` instance.
-
-``user``
- The user instance that just logged in.
-
-.. data:: django.contrib.auth.signals.user_logged_out
- :module:
-
-Sent when the logout method is called.
-
-``sender``
- As above: the class of the user that just logged out or ``None``
- if the user was not authenticated.
-
-``request``
- The current :class:`~django.http.HttpRequest` instance.
-
-``user``
- The user instance that just logged out or ``None`` if the
- user was not authenticated.
-
-.. data:: django.contrib.auth.signals.user_login_failed
- :module:
-.. versionadded:: 1.5
-
-Sent when the user failed to login successfully
-
-``sender``
- The name of the module used for authentication.
-
-``credentials``
- A dictonary of keyword arguments containing the user credentials that were
- passed to :func:`~django.contrib.auth.authenticate()` or your own custom
- authentication backend. Credentials matching a set of 'sensitive' patterns,
- (including password) will not be sent in the clear as part of the signal.
-
-Limiting access to logged-in users
-----------------------------------
-
-The raw way
-~~~~~~~~~~~
-
-The simple, raw way to limit access to pages is to check
-:meth:`request.user.is_authenticated()
-<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
-login page::
-
- from django.http import HttpResponseRedirect
-
- def my_view(request):
- if not request.user.is_authenticated():
- return HttpResponseRedirect('/login/?next=%s' % request.path)
- # ...
-
-...or display an error message::
-
- def my_view(request):
- if not request.user.is_authenticated():
- return render_to_response('myapp/login_error.html')
- # ...
-
-The login_required decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. function:: decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME, login_url=None])
-
- As a shortcut, you can use the convenient
- :func:`~django.contrib.auth.decorators.login_required` decorator::
-
- from django.contrib.auth.decorators import login_required
-
- @login_required
- def my_view(request):
- ...
-
- :func:`~django.contrib.auth.decorators.login_required` does the following:
-
- * If the user isn't logged in, redirect to
- :setting:`settings.LOGIN_URL <LOGIN_URL>`, passing the current absolute
- path in the query string. Example: ``/accounts/login/?next=/polls/3/``.
-
- * If the user is logged in, execute the view normally. The view code is
- free to assume the user is logged in.
-
- By default, the path that the user should be redirected to upon
- successful authentication is stored in a query string parameter called
- ``"next"``. If you would prefer to use a different name for this parameter,
- :func:`~django.contrib.auth.decorators.login_required` takes an
- optional ``redirect_field_name`` parameter::
-
- from django.contrib.auth.decorators import login_required
-
- @login_required(redirect_field_name='my_redirect_field')
- def my_view(request):
- ...
-
- Note that if you provide a value to ``redirect_field_name``, you will most
- likely need to customize your login template as well, since the template
- context variable which stores the redirect path will use the value of
- ``redirect_field_name`` as its key rather than ``"next"`` (the default).
-
- :func:`~django.contrib.auth.decorators.login_required` also takes an
- optional ``login_url`` parameter. Example::
-
- from django.contrib.auth.decorators import login_required
-
- @login_required(login_url='/accounts/login/')
- def my_view(request):
- ...
-
- Note that if you don't specify the ``login_url`` parameter, you'll need to map
- the appropriate Django view to :setting:`settings.LOGIN_URL <LOGIN_URL>`. For
- example, using the defaults, add the following line to your URLconf::
-
- (r'^accounts/login/$', 'django.contrib.auth.views.login'),
-
- .. versionchanged:: 1.5
-
- As of version 1.5 :setting:`settings.LOGIN_URL <LOGIN_URL>` now also accepts
- view function names and :ref:`named URL patterns <naming-url-patterns>`.
- This allows you to freely remap your login view within your URLconf
- without having to update the setting.
-
-.. function:: views.login(request, [template_name, redirect_field_name, authentication_form])
-
- **URL name:** ``login``
-
- See :doc:`the URL documentation </topics/http/urls>` for details on using
- named URL patterns.
-
- Here's what ``django.contrib.auth.views.login`` does:
-
- * If called via ``GET``, it displays a login form that POSTs to the
- same URL. More on this in a bit.
-
- * If called via ``POST``, it tries to log the user in. If login is
- successful, the view redirects to the URL specified in ``next``. If
- ``next`` isn't provided, it redirects to
- :setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>` (which
- defaults to ``/accounts/profile/``). If login isn't successful, it
- redisplays the login form.
-
- It's your responsibility to provide the login form in a template called
- ``registration/login.html`` by default. This template gets passed four
- template context variables:
-
- * ``form``: A :class:`~django.forms.Form` object representing the login
- form. See the :doc:`forms documentation </topics/forms/index>` for
- more on ``Form`` objects.
-
- * ``next``: The URL to redirect to after successful login. This may
- contain a query string, too.
-
- * ``site``: The current :class:`~django.contrib.sites.models.Site`,
- according to the :setting:`SITE_ID` setting. If you don't have the
- site framework installed, this will be set to an instance of
- :class:`~django.contrib.sites.models.RequestSite`, which derives the
- site name and domain from the current
- :class:`~django.http.HttpRequest`.
-
- * ``site_name``: An alias for ``site.name``. If you don't have the site
- framework installed, this will be set to the value of
- :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
- For more on sites, see :doc:`/ref/contrib/sites`.
-
- If you'd prefer not to call the template :file:`registration/login.html`,
- you can pass the ``template_name`` parameter via the extra arguments to
- the view in your URLconf. For example, this URLconf line would use
- :file:`myapp/login.html` instead::
-
- (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
-
- You can also specify the name of the ``GET`` field which contains the URL
- to redirect to after login by passing ``redirect_field_name`` to the view.
- By default, the field is called ``next``.
-
- Here's a sample :file:`registration/login.html` template you can use as a
- starting point. It assumes you have a :file:`base.html` template that
- defines a ``content`` block:
-
- .. code-block:: html+django
-
- {% extends "base.html" %}
-
- {% block content %}
-
- {% if form.errors %}
- <p>Your username and password didn't match. Please try again.</p>
- {% endif %}
-
- <form method="post" action="{% url 'django.contrib.auth.views.login' %}">
- {% csrf_token %}
- <table>
- <tr>
- <td>{{ form.username.label_tag }}</td>
- <td>{{ form.username }}</td>
- </tr>
- <tr>
- <td>{{ form.password.label_tag }}</td>
- <td>{{ form.password }}</td>
- </tr>
- </table>
-
- <input type="submit" value="login" />
- <input type="hidden" name="next" value="{{ next }}" />
- </form>
-
- {% endblock %}
-
- If you are using alternate authentication (see
- :ref:`authentication-backends`) you can pass a custom authentication form
- to the login view via the ``authentication_form`` parameter. This form must
- accept a ``request`` keyword argument in its ``__init__`` method, and
- provide a ``get_user`` method which returns the authenticated user object
- (this method is only ever called after successful form validation).
-
- .. _forms documentation: ../forms/
- .. _site framework docs: ../sites/
-
- .. versionadded:: 1.4
-
- The :func:`~views.login` view and the :ref:`other-built-in-views` now all
- return a :class:`~django.template.response.TemplateResponse` instance,
- which allows you to easily customize the response data before rendering.
- For more details, see the
- :doc:`TemplateResponse documentation </ref/template-response>`.
-
-.. _other-built-in-views:
-
-Other built-in views
---------------------
-
-.. module:: django.contrib.auth.views
-
-In addition to the :func:`~views.login` view, the authentication system
-includes a few other useful built-in views located in
-:mod:`django.contrib.auth.views`:
-
-.. function:: logout(request, [next_page, template_name, redirect_field_name])
-
- Logs a user out.
-
- **URL name:** ``logout``
-
- See :doc:`the URL documentation </topics/http/urls>` for details on using
- named URL patterns.
-
- **Optional arguments:**
-
- * ``next_page``: The URL to redirect to after logout.
-
- * ``template_name``: The full name of a template to display after
- logging the user out. Defaults to
- :file:`registration/logged_out.html` if no argument is supplied.
-
- * ``redirect_field_name``: The name of a ``GET`` field containing the
- URL to redirect to after log out. Overrides ``next_page`` if the given
- ``GET`` parameter is passed.
-
- **Template context:**
-
- * ``title``: The string "Logged out", localized.
-
- * ``site``: The current :class:`~django.contrib.sites.models.Site`,
- according to the :setting:`SITE_ID` setting. If you don't have the
- site framework installed, this will be set to an instance of
- :class:`~django.contrib.sites.models.RequestSite`, which derives the
- site name and domain from the current
- :class:`~django.http.HttpRequest`.
-
- * ``site_name``: An alias for ``site.name``. If you don't have the site
- framework installed, this will be set to the value of
- :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
- For more on sites, see :doc:`/ref/contrib/sites`.
-
-.. function:: logout_then_login(request[, login_url])
-
- Logs a user out, then redirects to the login page.
-
- **URL name:** No default URL provided
-
- **Optional arguments:**
-
- * ``login_url``: The URL of the login page to redirect to.
- Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
-
-.. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
-
- Allows a user to change their password.
-
- **URL name:** ``password_change``
-
- **Optional arguments:**
-
- * ``template_name``: The full name of a template to use for
- displaying the password change form. Defaults to
- :file:`registration/password_change_form.html` if not supplied.
-
- * ``post_change_redirect``: The URL to redirect to after a successful
- password change.
-
- * ``password_change_form``: A custom "change password" form which must
- accept a ``user`` keyword argument. The form is responsible for
- actually changing the user's password. Defaults to
- :class:`~django.contrib.auth.forms.PasswordChangeForm`.
-
- **Template context:**
-
- * ``form``: The password change form (see ``password_change_form`` above).
-
-.. function:: password_change_done(request[, template_name])
-
- The page shown after a user has changed their password.
-
- **URL name:** ``password_change_done``
-
- **Optional arguments:**
-
- * ``template_name``: The full name of a template to use.
- Defaults to :file:`registration/password_change_done.html` if not
- supplied.
-
-.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
-
- Allows a user to reset their password by generating a one-time use link
- that can be used to reset the password, and sending that link to the
- user's registered email address.
-
- .. versionchanged:: 1.4
- Users flagged with an unusable password (see
- :meth:`~django.contrib.auth.models.User.set_unusable_password()`
- will not be able to request a password reset to prevent misuse
- when using an external authentication source like LDAP.
-
- **URL name:** ``password_reset``
-
- **Optional arguments:**
-
- * ``template_name``: The full name of a template to use for
- displaying the password reset form. Defaults to
- :file:`registration/password_reset_form.html` if not supplied.
-
- * ``email_template_name``: The full name of a template to use for
- generating the email with the reset password link. Defaults to
- :file:`registration/password_reset_email.html` if not supplied.
-
- * ``subject_template_name``: The full name of a template to use for
- the subject of the email with the reset password link. Defaults
- to :file:`registration/password_reset_subject.txt` if not supplied.
-
- .. versionadded:: 1.4
-
- * ``password_reset_form``: Form that will be used to get the email of
- the user to reset the password for. Defaults to
- :class:`~django.contrib.auth.forms.PasswordResetForm`.
-
- * ``token_generator``: Instance of the class to check the one time link.
- This will default to ``default_token_generator``, it's an instance of
- ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
-
- * ``post_reset_redirect``: The URL to redirect to after a successful
- password reset request.
-
- * ``from_email``: A valid email address. By default Django uses
- the :setting:`DEFAULT_FROM_EMAIL`.
-
- **Template context:**
-
- * ``form``: The form (see ``password_reset_form`` above) for resetting
- the user's password.
-
- **Email template context:**
-
- * ``email``: An alias for ``user.email``
-
- * ``user``: The current :class:`~django.contrib.auth.models.User`,
- according to the ``email`` form field. Only active users are able to
- reset their passwords (``User.is_active is True``).
-
- * ``site_name``: An alias for ``site.name``. If you don't have the site
- framework installed, this will be set to the value of
- :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
- For more on sites, see :doc:`/ref/contrib/sites`.
-
- * ``domain``: An alias for ``site.domain``. If you don't have the site
- framework installed, this will be set to the value of
- ``request.get_host()``.
-
- * ``protocol``: http or https
-
- * ``uid``: The user's id encoded in base 36.
-
- * ``token``: Token to check that the reset link is valid.
-
- Sample ``registration/password_reset_email.html`` (email body template):
-
- .. code-block:: html+django
-
- Someone asked for password reset for email {{ email }}. Follow the link below:
- {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}
-
- The same template context is used for subject template. Subject must be
- single line plain text string.
-
-
-.. function:: password_reset_done(request[, template_name])
-
- The page shown after a user has been emailed a link to reset their
- password. This view is called by default if the :func:`password_reset` view
- doesn't have an explicit ``post_reset_redirect`` URL set.
-
- **URL name:** ``password_reset_done``
-
- **Optional arguments:**
-
- * ``template_name``: The full name of a template to use.
- Defaults to :file:`registration/password_reset_done.html` if not
- supplied.
-
-.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])
-
- Presents a form for entering a new password.
-
- **URL name:** ``password_reset_confirm``
-
- **Optional arguments:**
-
- * ``uidb36``: The user's id encoded in base 36. Defaults to ``None``.
-
- * ``token``: Token to check that the password is valid. Defaults to
- ``None``.
-
- * ``template_name``: The full name of a template to display the confirm
- password view. Default value is :file:`registration/password_reset_confirm.html`.
-
- * ``token_generator``: Instance of the class to check the password. This
- will default to ``default_token_generator``, it's an instance of
- ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
-
- * ``set_password_form``: Form that will be used to set the password.
- Defaults to :class:`~django.contrib.auth.forms.SetPasswordForm`
-
- * ``post_reset_redirect``: URL to redirect after the password reset
- done. Defaults to ``None``.
-
- **Template context:**
-
- * ``form``: The form (see ``set_password_form`` above) for setting the
- new user's password.
-
- * ``validlink``: Boolean, True if the link (combination of uidb36 and
- token) is valid or unused yet.
-
-.. function:: password_reset_complete(request[,template_name])
-
- Presents a view which informs the user that the password has been
- successfully changed.
-
- **URL name:** ``password_reset_complete``
-
- **Optional arguments:**
-
- * ``template_name``: The full name of a template to display the view.
- Defaults to :file:`registration/password_reset_complete.html`.
-
-Helper functions
-----------------
-
-.. currentmodule:: django.contrib.auth.views
-
-.. function:: redirect_to_login(next[, login_url, redirect_field_name])
-
- Redirects to the login page, and then back to another URL after a
- successful login.
-
- **Required arguments:**
-
- * ``next``: The URL to redirect to after a successful login.
-
- **Optional arguments:**
-
- * ``login_url``: The URL of the login page to redirect to.
- Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
-
- * ``redirect_field_name``: The name of a ``GET`` field containing the
- URL to redirect to after log out. Overrides ``next`` if the given
- ``GET`` parameter is passed.
-
-
-.. _built-in-auth-forms:
-
-Built-in forms
---------------
-
-.. module:: django.contrib.auth.forms
-
-If you don't want to use the built-in views, but want the convenience of not
-having to write forms for this functionality, the authentication system
-provides several built-in forms located in :mod:`django.contrib.auth.forms`:
-
-.. class:: AdminPasswordChangeForm
-
- A form used in the admin interface to change a user's password.
-
-.. class:: AuthenticationForm
-
- A form for logging a user in.
-
-.. class:: PasswordChangeForm
-
- A form for allowing a user to change their password.
-
-.. class:: PasswordResetForm
-
- A form for generating and emailing a one-time use link to reset a
- user's password.
-
-.. class:: SetPasswordForm
-
- A form that lets a user change his/her password without entering the old
- password.
-
-.. class:: UserChangeForm
-
- A form used in the admin interface to change a user's information and
- permissions.
-
-.. class:: UserCreationForm
-
- A form for creating a new user.
-
-Limiting access to logged-in users that pass a test
----------------------------------------------------
-
-.. currentmodule:: django.contrib.auth.decorators
-
-To limit access based on certain permissions or some other test, you'd do
-essentially the same thing as described in the previous section.
-
-The simple way is to run your test on :attr:`request.user
-<django.http.HttpRequest.user>` in the view directly. For example, this view
-checks to make sure the user is logged in and has the permission
-``polls.can_vote``::
-
- def my_view(request):
- if not request.user.has_perm('polls.can_vote'):
- return HttpResponse("You can't vote in this poll.")
- # ...
-
-.. function:: user_passes_test(func, [login_url=None])
-
- As a shortcut, you can use the convenient ``user_passes_test`` decorator::
-
- from django.contrib.auth.decorators import user_passes_test
-
- @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
- def my_view(request):
- ...
-
- We're using this particular test as a relatively simple example. However,
- if you just want to test whether a permission is available to a user, you
- can use the :func:`~django.contrib.auth.decorators.permission_required()`
- decorator, described later in this document.
-
- :func:`~django.contrib.auth.decorators.user_passes_test` takes a required
- argument: a callable that takes a
- :class:`~django.contrib.auth.models.User` object and returns ``True`` if
- the user is allowed to view the page. Note that
- :func:`~django.contrib.auth.decorators.user_passes_test` does not
- automatically check that the :class:`~django.contrib.auth.models.User` is
- not anonymous.
-
- :func:`~django.contrib.auth.decorators.user_passes_test()` takes an
- optional ``login_url`` argument, which lets you specify the URL for your
- login page (:setting:`settings.LOGIN_URL <LOGIN_URL>` by default).
-
- For example::
-
- from django.contrib.auth.decorators import user_passes_test
-
- @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')
- def my_view(request):
- ...
-
-The permission_required decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. function:: permission_required([login_url=None, raise_exception=False])
-
- It's a relatively common task to check whether a user has a particular
- permission. For that reason, Django provides a shortcut for that case: the
- :func:`~django.contrib.auth.decorators.permission_required()` decorator.
- Using this decorator, the earlier example can be written as::
-
- from django.contrib.auth.decorators import permission_required
-
- @permission_required('polls.can_vote')
- def my_view(request):
- ...
-
- As for the :meth:`User.has_perm` method, permission names take the form
- ``"<app label>.<permission codename>"`` (i.e. ``polls.can_vote`` for a
- permission on a model in the ``polls`` application).
-
- Note that :func:`~django.contrib.auth.decorators.permission_required()`
- also takes an optional ``login_url`` parameter. Example::
-
- from django.contrib.auth.decorators import permission_required
-
- @permission_required('polls.can_vote', login_url='/loginpage/')
- def my_view(request):
- ...
-
- As in the :func:`~decorators.login_required` decorator, ``login_url``
- defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>`.
-
- .. versionchanged:: 1.4
-
- Added ``raise_exception`` parameter. If given, the decorator will raise
- :exc:`~django.core.exceptions.PermissionDenied`, prompting
- :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` instead of
- redirecting to the login page.
-
-.. currentmodule:: django.contrib.auth
-
-Applying permissions to generic views
--------------------------------------
-
-To apply a permission to a :doc:`class-based generic view
-</ref/class-based-views/index>`, decorate the :meth:`View.dispatch
-<django.views.generic.base.View.dispatch>` method on the class. See
-:ref:`decorating-class-based-views` for details.
-
-.. _permissions:
-
-Permissions
-===========
-
-Django comes with a simple permissions system. It provides a way to assign
-permissions to specific users and groups of users.
-
-It's used by the Django admin site, but you're welcome to use it in your own
-code.
-
-The Django admin site uses permissions as follows:
-
-* Access to view the "add" form and add an object is limited to users with
- the "add" permission for that type of object.
-* Access to view the change list, view the "change" form and change an
- object is limited to users with the "change" permission for that type of
- object.
-* Access to delete an object is limited to users with the "delete"
- permission for that type of object.
-
-Permissions can be set not only per type of object, but also per specific
-object instance. By using the
-:meth:`~django.contrib.admin.ModelAdmin.has_add_permission`,
-:meth:`~django.contrib.admin.ModelAdmin.has_change_permission` and
-:meth:`~django.contrib.admin.ModelAdmin.has_delete_permission` methods provided
-by the :class:`~django.contrib.admin.ModelAdmin` class, it is possible to
-customize permissions for different object instances of the same type.
-
-Default permissions
--------------------
-
-When ``django.contrib.auth`` is listed in your :setting:`INSTALLED_APPS`
-setting, it will ensure that three default permissions -- add, change and
-delete -- are created for each Django model defined in one of your installed
-applications.
-
-These permissions will be created when you run :djadmin:`manage.py syncdb
-<syncdb>`; the first time you run ``syncdb`` after adding
-``django.contrib.auth`` to :setting:`INSTALLED_APPS`, the default permissions
-will be created for all previously-installed models, as well as for any new
-models being installed at that time. Afterward, it will create default
-permissions for new models each time you run :djadmin:`manage.py syncdb
-<syncdb>`.
-
-Assuming you have an application with an
-:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
-to test for basic permissions you should use:
-
-* add: ``user.has_perm('foo.add_bar')``
-* change: ``user.has_perm('foo.change_bar')``
-* delete: ``user.has_perm('foo.delete_bar')``
-
-.. _custom-permissions:
-
-Custom permissions
-------------------
-
-To create custom permissions for a given model object, use the ``permissions``
-:ref:`model Meta attribute <meta-options>`.
-
-This example Task model creates three custom permissions, i.e., actions users
-can or cannot do with Task instances, specific to your application::
-
- class Task(models.Model):
- ...
- class Meta:
- permissions = (
- ("view_task", "Can see available tasks"),
- ("change_task_status", "Can change the status of tasks"),
- ("close_task", "Can remove a task by setting its status as closed"),
- )
-
-The only thing this does is create those extra permissions when you run
-:djadmin:`manage.py syncdb <syncdb>`. Your code is in charge of checking the
-value of these permissions when an user is trying to access the functionality
-provided by the application (viewing tasks, changing the status of tasks,
-closing tasks.) Continuing the above example, the following checks if a user may
-view tasks::
-
- user.has_perm('app.view_task')
-
-API reference
--------------
-
-.. currentmodule:: django.contrib.auth.models
-
-.. class:: models.Permission
-
-Fields
-~~~~~~
-
-:class:`~django.contrib.auth.models.Permission` objects have the following
-fields:
-
-.. attribute:: Permission.name
-
- Required. 50 characters or fewer. Example: ``'Can vote'``.
-
-.. attribute:: Permission.content_type
-
- Required. A reference to the ``django_content_type`` database table, which
- contains a record for each installed Django model.
-
-.. attribute:: Permission.codename
-
- Required. 100 characters or fewer. Example: ``'can_vote'``.
-
-Methods
-~~~~~~~
-
-:class:`~django.contrib.auth.models.Permission` objects have the standard
-data-access methods like any other :doc:`Django model </ref/models/instances>`.
-
-.. currentmodule:: django.contrib.auth
-
-Programmatically creating permissions
--------------------------------------
-
-While custom permissions can be defined within a model's ``Meta`` class, you
-can also create permissions directly. For example, you can create the
-``can_publish`` permission for a ``BlogPost`` model in ``myapp``::
-
- from django.contrib.auth.models import Group, Permission
- from django.contrib.contenttypes.models import ContentType
-
- content_type = ContentType.objects.get(app_label='myapp', model='BlogPost')
- permission = Permission.objects.create(codename='can_publish',
- name='Can Publish Posts',
- content_type=content_type)
-
-The permission can then be assigned to a
-:class:`~django.contrib.auth.models.User` via its ``user_permissions``
-attribute or to a :class:`~django.contrib.auth.models.Group` via its
-``permissions`` attribute.
-
-Authentication data in templates
-================================
-
-The currently logged-in user and his/her permissions are made available in the
-:doc:`template context </ref/templates/api>` when you use
-:class:`~django.template.context.RequestContext`.
-
-.. admonition:: Technicality
-
- Technically, these variables are only made available in the template context
- if you use :class:`~django.template.context.RequestContext` *and* your
- :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
- ``"django.contrib.auth.context_processors.auth"``, which is default. For
- more, see the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
-
-Users
------
-
-When rendering a template :class:`~django.template.context.RequestContext`, the
-currently logged-in user, either a :class:`~django.contrib.auth.models.User`
-instance or an :class:`~django.contrib.auth.models.AnonymousUser` instance, is
-stored in the template variable ``{{ user }}``:
-
-.. code-block:: html+django
-
- {% if user.is_authenticated %}
- <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
- {% else %}
- <p>Welcome, new user. Please log in.</p>
- {% endif %}
-
-This template context variable is not available if a ``RequestContext`` is not
-being used.
-
-Permissions
------------
-
-The currently logged-in user's permissions are stored in the template variable
-``{{ perms }}``. This is an instance of
-:class:`django.contrib.auth.context_processors.PermWrapper`, which is a
-template-friendly proxy of permissions.
-
-In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
-:meth:`User.has_module_perms <django.contrib.auth.models.User.has_module_perms>`.
-This example would display ``True`` if the logged-in user had any permissions
-in the ``foo`` app::
-
- {{ perms.foo }}
-
-Two-level-attribute lookup is a proxy to
-:meth:`User.has_perm <django.contrib.auth.models.User.has_perm>`. This example
-would display ``True`` if the logged-in user had the permission
-``foo.can_vote``::
-
- {{ perms.foo.can_vote }}
-
-Thus, you can check permissions in template ``{% if %}`` statements:
-
-.. code-block:: html+django
-
- {% if perms.foo %}
- <p>You have permission to do something in the foo app.</p>
- {% if perms.foo.can_vote %}
- <p>You can vote!</p>
- {% endif %}
- {% if perms.foo.can_drive %}
- <p>You can drive!</p>
- {% endif %}
- {% else %}
- <p>You don't have permission to do anything in the foo app.</p>
- {% endif %}
-
-.. versionadded:: 1.5
- Permission lookup by "if in".
-
-It is possible to also look permissions up by ``{% if in %}`` statements.
-For example:
-
-.. code-block:: html+django
-
- {% if 'foo' in perms %}
- {% if 'foo.can_vote' in perms %}
- <p>In lookup works, too.</p>
- {% endif %}
- {% endif %}
-
-Groups
-======
-
-Groups are a generic way of categorizing users so you can apply permissions, or
-some other label, to those users. A user can belong to any number of groups.
-
-A user in a group automatically has the permissions granted to that group. For
-example, if the group ``Site editors`` has the permission
-``can_edit_home_page``, any user in that group will have that permission.
-
-Beyond permissions, groups are a convenient way to categorize users to give
-them some label, or extended functionality. For example, you could create a
-group ``'Special users'``, and you could write code that could, say, give them
-access to a members-only portion of your site, or send them members-only email
-messages.
-
-API reference
--------------
-
-.. class:: models.Group
-
-Fields
-~~~~~~
-
-:class:`~django.contrib.auth.models.Group` objects have the following fields:
-
-.. attribute:: Group.name
-
- Required. 80 characters or fewer. Any characters are permitted. Example:
- ``'Awesome Users'``.
-
-.. attribute:: Group.permissions
-
- Many-to-many field to :class:`~django.contrib.auth.models.Permissions`::
-
- group.permissions = [permission_list]
- group.permissions.add(permission, permission, ...)
- group.permissions.remove(permission, permission, ...)
- group.permissions.clear()
-
-.. _auth-custom-user:
-
-Customizing the User model
-==========================
-
-.. versionadded:: 1.5
-
-Some kinds of projects may have authentication requirements for which Django's
-built-in :class:`~django.contrib.auth.models.User` model is not always
-appropriate. For instance, on some sites it makes more sense to use an email
-address as your identification token instead of a username.
-
-Django allows you to override the default User model by providing a value for
-the :setting:`AUTH_USER_MODEL` setting that references a custom model::
-
- AUTH_USER_MODEL = 'myapp.MyUser'
-
-This dotted pair describes the name of the Django app, and the name of the Django
-model that you wish to use as your User model.
-
-.. admonition:: Warning
-
- Changing :setting:`AUTH_USER_MODEL` has a big effect on your database
- structure. It changes the tables that are available, and it will affect the
- construction of foreign keys and many-to-many relationships. If you intend
- to set :setting:`AUTH_USER_MODEL`, you should set it before running
- ``manage.py syncdb`` for the first time.
-
- If you have an existing project and you want to migrate to using a custom
- User model, you may need to look into using a migration tool like South_
- to ease the transition.
-
-.. _South: http://south.aeracode.org
-
-Referencing the User model
---------------------------
-
-If you reference :class:`~django.contrib.auth.models.User` directly (for
-example, by referring to it in a foreign key), your code will not work in
-projects where the :setting:`AUTH_USER_MODEL` setting has been changed to a
-different User model.
-
-Instead of referring to :class:`~django.contrib.auth.models.User` directly,
-you should reference the user model using
-:func:`django.contrib.auth.get_user_model()`. This method will return the
-currently active User model -- the custom User model if one is specified, or
-:class:`~django.contrib.auth.User` otherwise.
-
-When you define a foreign key or many-to-many relations to the User model,
-you should specify the custom model using the :setting:`AUTH_USER_MODEL`
-setting. For example::
-
- from django.conf import settings
- from django.db import models
-
- class Article(models.Model)
- author = models.ForeignKey(settings.AUTH_USER_MODEL)
-
-Specifying a custom User model
-------------------------------
-
-.. admonition:: Model design considerations
-
- Think carefully before handling information not directly related to
- authentication in your custom User Model.
-
- It may be better to store app-specific user information in a model
- that has a relation with the User model. That allows each app to specify
- its own user data requirements without risking conflicts with other
- apps. On the other hand, queries to retrieve this related information
- will involve a database join, which may have an effect on performance.
-
-Django expects your custom User model to meet some minimum requirements.
-
-1. Your model must have a single unique field that can be used for
- identification purposes. This can be a username, an email address,
- or any other unique attribute.
-
-2. Your model must provide a way to address the user in a "short" and
- "long" form. The most common interpretation of this would be to use
- the user's given name as the "short" identifier, and the user's full
- name as the "long" identifier. However, there are no constraints on
- what these two methods return - if you want, they can return exactly
- the same value.
-
-The easiest way to construct a compliant custom User model is to inherit from
-:class:`~django.contrib.auth.models.AbstractBaseUser`.
-:class:`~django.contrib.auth.models.AbstractBaseUser` provides the core
-implementation of a `User` model, including hashed passwords and tokenized
-password resets. You must then provide some key implementation details:
-
-.. class:: models.CustomUser
-
- .. attribute:: User.USERNAME_FIELD
-
- A string describing the name of the field on the User model that is
- used as the unique identifier. This will usually be a username of
- some kind, but it can also be an email address, or any other unique
- identifier. In the following example, the field `identifier` is used
- as the identifying field::
-
- class MyUser(AbstractBaseUser):
- identifier = models.CharField(max_length=40, unique=True, db_index=True)
- ...
- USERNAME_FIELD = 'identifier'
-
- .. attribute:: User.REQUIRED_FIELDS
-
- A list of the field names that *must* be provided when creating
- a user. For example, here is the partial definition for a User model
- that defines two required fields - a date of birth and height::
-
- class MyUser(AbstractBaseUser):
- ...
- date_of_birth = models.DateField()
- height = models.FloatField()
- ...
- REQUIRED_FIELDS = ['date_of_birth', 'height']
-
- .. note::
-
- ``REQUIRED_FIELDS`` must contain all required fields on your User
- model, but should *not* contain the ``USERNAME_FIELD``.
-
- .. attribute:: User.is_active
-
- A boolean attribute that indicates whether the user is considered
- "active". This attribute is provided as an attribute on
- ``AbstractBaseUser`` defaulting to ``True``. How you choose to
- implement it will depend on the details of your chosen auth backends.
- See the documentation of the :attr:`attribute on the builtin user model
- <django.contrib.auth.models.User.is_active>` for details.
-
- .. method:: User.get_full_name():
-
- A longer formal identifier for the user. A common interpretation
- would be the full name name of the user, but it can be any string that
- identifies the user.
-
- .. method:: User.get_short_name():
-
- A short, informal identifier for the user. A common interpretation
- would be the first name of the user, but it can be any string that
- identifies the user in an informal way. It may also return the same
- value as :meth:`django.contrib.auth.User.get_full_name()`.
-
-The following methods are available on any subclass of
-:class:`~django.contrib.auth.models.AbstractBaseUser`:
-
-.. class:: models.AbstractBaseUser
-
- .. method:: models.AbstractBaseUser.get_username()
-
- Returns the value of the field nominated by ``USERNAME_FIELD``.
-
- .. method:: models.AbstractBaseUser.is_anonymous()
-
- Always returns ``False``. This is a way of differentiating
- from :class:`~django.contrib.auth.models.AnonymousUser` objects.
- Generally, you should prefer using
- :meth:`~django.contrib.auth.models.AbstractBaseUser.is_authenticated()` to this
- method.
-
- .. method:: models.AbstractBaseUser.is_authenticated()
-
- Always returns ``True``. This is a way to tell if the user has been
- authenticated. This does not imply any permissions, and doesn't check
- if the user is active - it only indicates that the user has provided a
- valid username and password.
-
- .. method:: models.AbstractBaseUser.set_password(raw_password)
-
- Sets the user's password to the given raw string, taking care of the
- password hashing. Doesn't save the
- :class:`~django.contrib.auth.models.AbstractBaseUser` object.
-
- .. method:: models.AbstractBaseUser.check_password(raw_password)
-
- Returns ``True`` if the given raw string is the correct password for
- the user. (This takes care of the password hashing in making the
- comparison.)
-
- .. method:: models.AbstractBaseUser.set_unusable_password()
-
- Marks the user as having no password set. This isn't the same as
- having a blank string for a password.
- :meth:`~django.contrib.auth.models.AbstractBaseUser.check_password()` for this user
- will never return ``True``. Doesn't save the
- :class:`~django.contrib.auth.models.AbstractBaseUser` object.
-
- You may need this if authentication for your application takes place
- against an existing external source such as an LDAP directory.
-
- .. method:: models.AbstractBaseUser.has_usable_password()
-
- Returns ``False`` if
- :meth:`~django.contrib.auth.models.AbstractBaseUser.set_unusable_password()` has
- been called for this user.
-
-
-You should also define a custom manager for your User model. If your User
-model defines `username` and `email` fields the same as Django's default User,
-you can just install Django's
-:class:`~django.contrib.auth.models.UserManager`; however, if your User model
-defines different fields, you will need to define a custom manager that
-extends :class:`~django.contrib.auth.models.BaseUserManager` providing two
-additional methods:
-
-.. class:: models.CustomUserManager
-
- .. method:: models.CustomUserManager.create_user(*username_field*, password=None, **other_fields)
-
- The prototype of `create_user()` should accept the username field,
- plus all required fields as arguments. For example, if your user model
- uses `email` as the username field, and has `date_of_birth` as a required
- fields, then create_user should be defined as::
-
- def create_user(self, email, date_of_birth, password=None):
- # create user here
-
- .. method:: models.CustomUserManager.create_superuser(*username_field*, password, **other_fields)
-
- The prototype of `create_superuser()` should accept the username field,
- plus all required fields as arguments. For example, if your user model
- uses `email` as the username field, and has `date_of_birth` as a required
- fields, then create_superuser should be defined as::
-
- def create_superuser(self, email, date_of_birth, password):
- # create superuser here
-
- Unlike `create_user()`, `create_superuser()` *must* require the caller
- to provider a password.
-
-:class:`~django.contrib.auth.models.BaseUserManager` provides the following
-utility methods:
-
-.. class:: models.BaseUserManager
-
- .. method:: models.BaseUserManager.normalize_email(email)
-
- A classmethod that normalizes email addresses by lowercasing
- the domain portion of the email address.
-
- .. method:: models.BaseUserManager.get_by_natural_key(username)
-
- Retrieves a user instance using the contents of the field
- nominated by ``USERNAME_FIELD``.
-
- .. method:: models.BaseUserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
-
- Returns a random password with the given length and given string of
- allowed characters. (Note that the default value of ``allowed_chars``
- doesn't contain letters that can cause user confusion, including:
-
- * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
- letter L, uppercase letter i, and the number one)
- * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
- and zero)
-
-Extending Django's default User
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you're entirely happy with Django's :class:`~django.contrib.auth.models.User`
-model and you just want to add some additional profile information, you can
-simply subclass :class:`~django.contrib.auth.models.AbstractUser` and add your
-custom profile fields.
-
-Custom users and the built-in auth forms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As you may expect, built-in Django's :ref:`forms <built-in-auth-forms>`
-and :ref:`views <other-built-in-views>` make certain assumptions about
-the user model that they are working with.
-
-If your user model doesn't follow the same assumptions, it may be necessary to define
-a replacement form, and pass that form in as part of the configuration of the
-auth views.
-
-* :class:`~django.contrib.auth.forms.UserCreationForm`
-
- Depends on the :class:`~django.contrib.auth.models.User` model.
- Must be re-written for any custom user model.
-
-* :class:`~django.contrib.auth.forms.UserChangeForm`
-
- Depends on the :class:`~django.contrib.auth.models.User` model.
- Must be re-written for any custom user model.
-
-* :class:`~django.contrib.auth.forms.AuthenticationForm`
-
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`,
- and will adapt to use the field defined in `USERNAME_FIELD`.
-
-* :class:`~django.contrib.auth.forms.PasswordResetForm`
-
- Assumes that the user model has an integer primary key, has a field named
- `email` that can be used to identify the user, and a boolean field
- named `is_active` to prevent password resets for inactive users.
-
-* :class:`~django.contrib.auth.forms.SetPasswordForm`
-
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
-
-* :class:`~django.contrib.auth.forms.PasswordChangeForm`
-
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
-
-* :class:`~django.contrib.auth.forms.AdminPasswordChangeForm`
-
- Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
-
-
-Custom users and django.contrib.admin
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you want your custom User model to also work with Admin, your User model must
-define some additional attributes and methods. These methods allow the admin to
-control access of the User to admin content:
-
-.. attribute:: User.is_staff
-
- Returns True if the user is allowed to have access to the admin site.
-
-.. attribute:: User.is_active
-
- Returns True if the user account is currently active.
-
-.. method:: User.has_perm(perm, obj=None):
-
- Returns True if the user has the named permission. If `obj` is
- provided, the permission needs to be checked against a specific object
- instance.
-
-.. method:: User.has_module_perms(app_label):
-
- Returns True if the user has permission to access models in
- the given app.
-
-You will also need to register your custom User model with the admin. If
-your custom User model extends :class:`~django.contrib.auth.models.AbstractUser`,
-you can use Django's existing :class:`~django.contrib.auth.admin.UserAdmin`
-class. However, if your User model extends
-:class:`~django.contrib.auth.models.AbstractBaseUser`, you'll need to define
-a custom ModelAdmin class. It may be possible to subclass the default
-:class:`~django.contrib.auth.admin.UserAdmin`; however, you'll need to
-override any of the definitions that refer to fields on
-:class:`~django.contrib.auth.models.AbstractUser` that aren't on your
-custom User class.
-
-Custom users and permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To make it easy to include Django's permission framework into your own User
-class, Django provides :class:`~django.contrib.auth.model.PermissionsMixin`.
-This is an abstract model you can include in the class heirarchy for your User
-model, giving you all the methods and database fields necessary to support
-Django's permission model.
-
-:class:`~django.contrib.auth.model.PermissionsMixin` provides the following
-methods and attributes:
-
-.. class:: models.PermissionsMixin
-
- .. attribute:: models.PermissionsMixin.is_superuser
-
- Boolean. Designates that this user has all permissions without
- explicitly assigning them.
-
- .. method:: models.PermissionsMixin.get_group_permissions(obj=None)
-
- Returns a set of permission strings that the user has, through his/her
- groups.
-
- If ``obj`` is passed in, only returns the group permissions for
- this specific object.
-
- .. method:: models.PermissionsMixin.get_all_permissions(obj=None)
-
- Returns a set of permission strings that the user has, both through
- group and user permissions.
-
- If ``obj`` is passed in, only returns the permissions for this
- specific object.
-
- .. method:: models.PermissionsMixin.has_perm(perm, obj=None)
-
- Returns ``True`` if the user has the specified permission, where perm is
- in the format ``"<app label>.<permission codename>"`` (see
- `permissions`_). If the user is inactive, this method will
- always return ``False``.
-
- If ``obj`` is passed in, this method won't check for a permission for
- the model, but for this specific object.
-
- .. method:: models.PermissionsMixin.has_perms(perm_list, obj=None)
-
- Returns ``True`` if the user has each of the specified permissions,
- where each perm is in the format
- ``"<app label>.<permission codename>"``. If the user is inactive,
- this method will always return ``False``.
-
- If ``obj`` is passed in, this method won't check for permissions for
- the model, but for the specific object.
-
- .. method:: models.PermissionsMixin.has_module_perms(package_name)
-
- Returns ``True`` if the user has any permissions in the given package
- (the Django app label). If the user is inactive, this method will
- always return ``False``.
-
-.. admonition:: ModelBackend
-
- If you don't include the
- :class:`~django.contrib.auth.model.PermissionsMixin`, you must ensure you
- don't invoke the permissions methods on ``ModelBackend``. ``ModelBackend``
- assumes that certain fields are available on your user model. If your User
- model doesn't provide those fields, you will receive database errors when
- you check permissions.
-
-Custom users and Proxy models
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-One limitation of custom User models is that installing a custom User model
-will break any proxy model extending :class:`~django.contrib.auth.models.User`.
-Proxy models must be based on a concrete base class; by defining a custom User
-model, you remove the ability of Django to reliably identify the base class.
-
-If your project uses proxy models, you must either modify the proxy to extend
-the User model that is currently in use in your project, or merge your proxy's
-behavior into your User subclass.
-
-Custom users and signals
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Another limitation of custom User models is that you can't use
-:func:`django.contrib.auth.get_user_model()` as the sender or target of a signal
-handler. Instead, you must register the handler with the actual User model.
-
-Custom users and testing/fixtures
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you are writing an application that interacts with the User model, you must
-take some precautions to ensure that your test suite will run regardless of
-the User model that is being used by a project. Any test that instantiates an
-instance of User will fail if the User model has been swapped out. This
-includes any attempt to create an instance of User with a fixture.
-
-To ensure that your test suite will pass in any project configuration,
-``django.contrib.auth.tests.utils`` defines a ``@skipIfCustomUser`` decorator.
-This decorator will cause a test case to be skipped if any User model other
-than the default Django user is in use. This decorator can be applied to a
-single test, or to an entire test class.
-
-Depending on your application, tests may also be needed to be added to ensure
-that the application works with *any* user model, not just the default User
-model. To assist with this, Django provides two substitute user models that
-can be used in test suites:
-
-* :class:`django.contrib.auth.tests.custom_user.CustomUser`, a custom user
- model that uses an ``email`` field as the username, and has a basic
- admin-compliant permissions setup
-
-* :class:`django.contrib.auth.tests.custom_user.ExtensionUser`, a custom
- user model that extends :class:`~django.contrib.auth.models.AbstractUser`,
- adding a ``date_of_birth`` field.
-
-You can then use the ``@override_settings`` decorator to make that test run
-with the custom User model. For example, here is a skeleton for a test that
-would test three possible User models -- the default, plus the two User
-models provided by ``auth`` app::
-
- from django.contrib.auth.tests.utils import skipIfCustomUser
- from django.test import TestCase
- from django.test.utils import override_settings
-
-
- class ApplicationTestCase(TestCase):
- @skipIfCustomUser
- def test_normal_user(self):
- "Run tests for the normal user model"
- self.assertSomething()
-
- @override_settings(AUTH_USER_MODEL='auth.CustomUser')
- def test_custom_user(self):
- "Run tests for a custom user model with email-based authentication"
- self.assertSomething()
-
- @override_settings(AUTH_USER_MODEL='auth.ExtensionUser')
- def test_extension_user(self):
- "Run tests for a simple extension of the built-in User."
- self.assertSomething()
-
-
-A full example
---------------
-
-Here is an example of an admin-compliant custom user app. This user model uses
-an email address as the username, and has a required date of birth; it
-provides no permission checking, beyond a simple `admin` flag on the user
-account. This model would be compatible with all the built-in auth forms and
-views, except for the User creation forms.
-
-This code would all live in a ``models.py`` file for a custom
-authentication app::
-
- from django.db import models
- from django.contrib.auth.models import (
- BaseUserManager, AbstractBaseUser
- )
-
-
- class MyUserManager(BaseUserManager):
- def create_user(self, email, date_of_birth, password=None):
- """
- Creates and saves a User with the given email, date of
- birth and password.
- """
- if not email:
- raise ValueError('Users must have an email address')
-
- user = self.model(
- email=MyUserManager.normalize_email(email),
- date_of_birth=date_of_birth,
- )
-
- user.set_password(password)
- user.save(using=self._db)
- return user
-
- def create_superuser(self, email, date_of_birth, password):
- """
- Creates and saves a superuser with the given email, date of
- birth and password.
- """
- user = self.create_user(email,
- password=password,
- date_of_birth=date_of_birth
- )
- user.is_admin = True
- user.save(using=self._db)
- return user
-
-
- class MyUser(AbstractBaseUser):
- email = models.EmailField(
- verbose_name='email address',
- max_length=255,
- unique=True,
- db_index=True,
- )
- date_of_birth = models.DateField()
- is_active = models.BooleanField(default=True)
- is_admin = models.BooleanField(default=False)
-
- objects = MyUserManager()
-
- USERNAME_FIELD = 'email'
- REQUIRED_FIELDS = ['date_of_birth']
-
- def get_full_name(self):
- # The user is identified by their email address
- return self.email
-
- def get_short_name(self):
- # The user is identified by their email address
- return self.email
-
- def __unicode__(self):
- return self.email
-
- def has_perm(self, perm, obj=None):
- "Does the user have a specific permission?"
- # Simplest possible answer: Yes, always
- return True
-
- def has_module_perms(self, app_label):
- "Does the user have permissions to view the app `app_label`?"
- # Simplest possible answer: Yes, always
- return True
-
- @property
- def is_staff(self):
- "Is the user a member of staff?"
- # Simplest possible answer: All admins are staff
- return self.is_admin
-
-Then, to register this custom User model with Django's admin, the following
-code would be required in the app's ``admin.py`` file::
-
- from django import forms
- from django.contrib import admin
- from django.contrib.auth.models import Group
- from django.contrib.auth.admin import UserAdmin
- from django.contrib.auth.forms import ReadOnlyPasswordHashField
-
- from customauth.models import MyUser
-
-
- class UserCreationForm(forms.ModelForm):
- """A form for creating new users. Includes all the required
- fields, plus a repeated password."""
- password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
- password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
-
- class Meta:
- model = MyUser
- fields = ('email', 'date_of_birth')
-
- def clean_password2(self):
- # Check that the two password entries match
- password1 = self.cleaned_data.get("password1")
- password2 = self.cleaned_data.get("password2")
- if password1 and password2 and password1 != password2:
- raise forms.ValidationError("Passwords don't match")
- return password2
-
- def save(self, commit=True):
- # Save the provided password in hashed format
- user = super(UserCreationForm, self).save(commit=False)
- user.set_password(self.cleaned_data["password1"])
- if commit:
- user.save()
- return user
-
-
- class UserChangeForm(forms.ModelForm):
- """A form for updating users. Includes all the fields on
- the user, but replaces the password field with admin's
- password hash display field.
- """
- password = ReadOnlyPasswordHashField()
-
- class Meta:
- model = MyUser
-
- def clean_password(self):
- # Regardless of what the user provides, return the initial value.
- # This is done here, rather than on the field, because the
- # field does not have access to the initial value
- return self.initial["password"]
-
-
- class MyUserAdmin(UserAdmin):
- # The forms to add and change user instances
- form = UserChangeForm
- add_form = UserCreationForm
-
- # The fields to be used in displaying the User model.
- # These override the definitions on the base UserAdmin
- # that reference specific fields on auth.User.
- list_display = ('email', 'date_of_birth', 'is_admin')
- list_filter = ('is_admin',)
- fieldsets = (
- (None, {'fields': ('email', 'password')}),
- ('Personal info', {'fields': ('date_of_birth',)}),
- ('Permissions', {'fields': ('is_admin',)}),
- ('Important dates', {'fields': ('last_login',)}),
- )
- add_fieldsets = (
- (None, {
- 'classes': ('wide',),
- 'fields': ('email', 'date_of_birth', 'password1', 'password2')}
- ),
- )
- search_fields = ('email',)
- ordering = ('email',)
- filter_horizontal = ()
-
- # Now register the new UserAdmin...
- admin.site.register(MyUser, MyUserAdmin)
- # ... and, since we're not using Django's builtin permissions,
- # unregister the Group model from admin.
- admin.site.unregister(Group)
-
-.. _authentication-backends:
-
-Other authentication sources
-============================
-
-The authentication that comes with Django is good enough for most common cases,
-but you may have the need to hook into another authentication source -- that
-is, another source of usernames and passwords or authentication methods.
-
-For example, your company may already have an LDAP setup that stores a username
-and password for every employee. It'd be a hassle for both the network
-administrator and the users themselves if users had separate accounts in LDAP
-and the Django-based applications.
-
-So, to handle situations like this, the Django authentication system lets you
-plug in other authentication sources. You can override Django's default
-database-based scheme, or you can use the default system in tandem with other
-systems.
-
-See the :doc:`authentication backend reference </ref/authbackends>`
-for information on the authentication backends included with Django.
-
-Specifying authentication backends
-----------------------------------
-
-Behind the scenes, Django maintains a list of "authentication backends" that it
-checks for authentication. When somebody calls
-:func:`django.contrib.auth.authenticate()` -- as described in :ref:`How to log
-a user in <how-to-log-a-user-in>` above -- Django tries authenticating across
-all of its authentication backends. If the first authentication method fails,
-Django tries the second one, and so on, until all backends have been attempted.
-
-The list of authentication backends to use is specified in the
-:setting:`AUTHENTICATION_BACKENDS` setting. This should be a tuple of Python
-path names that point to Python classes that know how to authenticate. These
-classes can be anywhere on your Python path.
-
-By default, :setting:`AUTHENTICATION_BACKENDS` is set to::
-
- ('django.contrib.auth.backends.ModelBackend',)
-
-That's the basic authentication backend that checks the Django users database
-and queries the builtin permissions. It does not provide protection against
-brute force attacks via any rate limiting mechanism. You may either implement
-your own rate limiting mechanism in a custom auth backend, or use the
-mechanisms provided by most Web servers.
-
-The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same
-username and password is valid in multiple backends, Django will stop
-processing at the first positive match.
-
-.. note::
-
- Once a user has authenticated, Django stores which backend was used to
- authenticate the user in the user's session, and re-uses the same backend
- for the duration of that session whenever access to the currently
- authenticated user is needed. This effectively means that authentication
- sources are cached on a per-session basis, so if you change
- :setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
- you need to force users to re-authenticate using different methods. A simple
- way to do that is simply to execute ``Session.objects.all().delete()``.
-
-.. versionadded:: 1.6
-
-If a backend raises a :class:`~django.core.exceptions.PermissionDenied`
-exception, authentication will immediately fail. Django won't check the
-backends that follow.
-
-Writing an authentication backend
----------------------------------
-
-An authentication backend is a class that implements two required methods:
-``get_user(user_id)`` and ``authenticate(**credentials)``, as well as a set of
-optional permission related :ref:`authorization methods <authorization_methods>`.
-
-The ``get_user`` method takes a ``user_id`` -- which could be a username,
-database ID or whatever -- and returns a ``User`` object.
-
-The ``authenticate`` method takes credentials as keyword arguments. Most of
-the time, it'll just look like this::
-
- class MyBackend(object):
- def authenticate(self, username=None, password=None):
- # Check the username/password and return a User.
-
-But it could also authenticate a token, like so::
-
- class MyBackend(object):
- def authenticate(self, token=None):
- # Check the token and return a User.
-
-Either way, ``authenticate`` should check the credentials it gets, and it
-should return a ``User`` object that matches those credentials, if the
-credentials are valid. If they're not valid, it should return ``None``.
-
-The Django admin system is tightly coupled to the Django ``User`` object
-described at the beginning of this document. For now, the best way to deal with
-this is to create a Django ``User`` object for each user that exists for your
-backend (e.g., in your LDAP directory, your external SQL database, etc.) You
-can either write a script to do this in advance, or your ``authenticate``
-method can do it the first time a user logs in.
-
-Here's an example backend that authenticates against a username and password
-variable defined in your ``settings.py`` file and creates a Django ``User``
-object the first time a user authenticates::
-
- from django.conf import settings
- from django.contrib.auth.models import User, check_password
-
- class SettingsBackend(object):
- """
- Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
-
- Use the login name, and a hash of the password. For example:
-
- ADMIN_LOGIN = 'admin'
- ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
- """
-
- def authenticate(self, username=None, password=None):
- login_valid = (settings.ADMIN_LOGIN == username)
- pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
- if login_valid and pwd_valid:
- try:
- user = User.objects.get(username=username)
- except User.DoesNotExist:
- # Create a new user. Note that we can set password
- # to anything, because it won't be checked; the password
- # from settings.py will.
- user = User(username=username, password='get from settings.py')
- user.is_staff = True
- user.is_superuser = True
- user.save()
- return user
- return None
-
- def get_user(self, user_id):
- try:
- return User.objects.get(pk=user_id)
- except User.DoesNotExist:
- return None
-
-.. _authorization_methods:
-
-Handling authorization in custom backends
------------------------------------------
-
-Custom auth backends can provide their own permissions.
-
-The user model will delegate permission lookup functions
-(:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
-:meth:`~django.contrib.auth.models.User.get_all_permissions()`,
-:meth:`~django.contrib.auth.models.User.has_perm()`, and
-:meth:`~django.contrib.auth.models.User.has_module_perms()`) to any
-authentication backend that implements these functions.
-
-The permissions given to the user will be the superset of all permissions
-returned by all backends. That is, Django grants a permission to a user that
-any one backend grants.
-
-The simple backend above could implement permissions for the magic admin
-fairly simply::
-
- class SettingsBackend(object):
-
- # ...
-
- def has_perm(self, user_obj, perm, obj=None):
- if user_obj.username == settings.ADMIN_LOGIN:
- return True
- else:
- return False
-
-This gives full permissions to the user granted access in the above example.
-Notice that in addition to the same arguments given to the associated
-:class:`django.contrib.auth.models.User` functions, the backend auth functions
-all take the user object, which may be an anonymous user, as an argument.
-
-A full authorization implementation can be found in the ``ModelBackend`` class
-in `django/contrib/auth/backends.py`_, which is the default backend and queries
-the ``auth_permission`` table most of the time. If you wish to provide
-custom behavior for only part of the backend API, you can take advantage of
-Python inheritence and subclass ``ModelBackend`` instead of implementing the
-complete API in a custom backend.
-
-.. _django/contrib/auth/backends.py: https://github.com/django/django/blob/master/django/contrib/auth/backends.py
-
-.. _anonymous_auth:
-
-Authorization for anonymous users
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An anonymous user is one that is not authenticated i.e. they have provided no
-valid authentication details. However, that does not necessarily mean they are
-not authorized to do anything. At the most basic level, most Web sites
-authorize anonymous users to browse most of the site, and many allow anonymous
-posting of comments etc.
-
-Django's permission framework does not have a place to store permissions for
-anonymous users. However, the user object passed to an authentication backend
-may be an :class:`django.contrib.auth.models.AnonymousUser` object, allowing
-the backend to specify custom authorization behavior for anonymous users. This
-is especially useful for the authors of re-usable apps, who can delegate all
-questions of authorization to the auth backend, rather than needing settings,
-for example, to control anonymous access.
-
-.. _inactive_auth:
-
-Authorization for inactive users
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An inactive user is a one that is authenticated but has its attribute
-``is_active`` set to ``False``. However this does not mean they are not
-authorized to do anything. For example they are allowed to activate their
-account.
-
-The support for anonymous users in the permission system allows for a scenario
-where anonymous users have permissions to do something while inactive
-authenticated users do not.
-
-Do not forget to test for the ``is_active`` attribute of the user in your own
-backend permission methods.
-
-
-Handling object permissions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Django's permission framework has a foundation for object permissions, though
-there is no implementation for it in the core. That means that checking for
-object permissions will always return ``False`` or an empty list (depending on
-the check performed). An authentication backend will receive the keyword
-parameters ``obj`` and ``user_obj`` for each object related authorization
-method and can return the object level permission as appropriate.
diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt
new file mode 100644
index 0000000000..5f48e82e2b
--- /dev/null
+++ b/docs/topics/auth/customizing.txt
@@ -0,0 +1,1074 @@
+====================================
+Customizing authentication in Django
+====================================
+
+The authentication that comes with Django is good enough for most common cases,
+but you may have needs not met by the out-of-the-box defaults. To customize
+authentication to your projects needs involves understanding what points of the
+provided system are extendible or replaceable. This document provides details
+about how the auth system can be customized.
+
+:ref:`Authentication backends <authentication-backends>` provide an extensible
+system for when a username and password stored with the User model need
+to be authenticated against a different service than Django's default.
+
+You can give your models :ref:`custom permissions <custom-permissions>` that can be
+checked through Django's authorization system.
+
+You can :ref:`extend <extending-user>` the default User model, or :ref:`substitute
+<auth-custom-user>` a completely customized model.
+
+.. _authentication-backends:
+
+Other authentication sources
+============================
+
+There may be times you have the need to hook into another authentication source
+-- that is, another source of usernames and passwords or authentication
+methods.
+
+For example, your company may already have an LDAP setup that stores a username
+and password for every employee. It'd be a hassle for both the network
+administrator and the users themselves if users had separate accounts in LDAP
+and the Django-based applications.
+
+So, to handle situations like this, the Django authentication system lets you
+plug in other authentication sources. You can override Django's default
+database-based scheme, or you can use the default system in tandem with other
+systems.
+
+See the `authentication backend reference
+<authentication-backends-reference>` for information on the authentication
+backends included with Django.
+
+Specifying authentication backends
+----------------------------------
+
+Behind the scenes, Django maintains a list of "authentication backends" that it
+checks for authentication. When somebody calls
+:func:`django.contrib.auth.authenticate()` -- as described in :ref:`How to log
+a user in <how-to-log-a-user-in>` above -- Django tries authenticating across
+all of its authentication backends. If the first authentication method fails,
+Django tries the second one, and so on, until all backends have been attempted.
+
+The list of authentication backends to use is specified in the
+:setting:`AUTHENTICATION_BACKENDS` setting. This should be a tuple of Python
+path names that point to Python classes that know how to authenticate. These
+classes can be anywhere on your Python path.
+
+By default, :setting:`AUTHENTICATION_BACKENDS` is set to::
+
+ ('django.contrib.auth.backends.ModelBackend',)
+
+That's the basic authentication backend that checks the Django users database
+and queries the built-in permissions. It does not provide protection against
+brute force attacks via any rate limiting mechanism. You may either implement
+your own rate limiting mechanism in a custom auth backend, or use the
+mechanisms provided by most Web servers.
+
+The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same
+username and password is valid in multiple backends, Django will stop
+processing at the first positive match.
+
+.. note::
+
+ Once a user has authenticated, Django stores which backend was used to
+ authenticate the user in the user's session, and re-uses the same backend
+ for the duration of that session whenever access to the currently
+ authenticated user is needed. This effectively means that authentication
+ sources are cached on a per-session basis, so if you change
+ :setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
+ you need to force users to re-authenticate using different methods. A simple
+ way to do that is simply to execute ``Session.objects.all().delete()``.
+
+.. versionadded:: 1.6
+
+If a backend raises a :class:`~django.core.exceptions.PermissionDenied`
+exception, authentication will immediately fail. Django won't check the
+backends that follow.
+
+Writing an authentication backend
+---------------------------------
+
+An authentication backend is a class that implements two required methods:
+``get_user(user_id)`` and ``authenticate(**credentials)``, as well as a set of
+optional permission related :ref:`authorization methods <authorization_methods>`.
+
+The ``get_user`` method takes a ``user_id`` -- which could be a username,
+database ID or whatever -- and returns a ``User`` object.
+
+The ``authenticate`` method takes credentials as keyword arguments. Most of
+the time, it'll just look like this::
+
+ class MyBackend(object):
+ def authenticate(self, username=None, password=None):
+ # Check the username/password and return a User.
+
+But it could also authenticate a token, like so::
+
+ class MyBackend(object):
+ def authenticate(self, token=None):
+ # Check the token and return a User.
+
+Either way, ``authenticate`` should check the credentials it gets, and it
+should return a ``User`` object that matches those credentials, if the
+credentials are valid. If they're not valid, it should return ``None``.
+
+The Django admin system is tightly coupled to the Django ``User`` object
+described at the beginning of this document. For now, the best way to deal with
+this is to create a Django ``User`` object for each user that exists for your
+backend (e.g., in your LDAP directory, your external SQL database, etc.) You
+can either write a script to do this in advance, or your ``authenticate``
+method can do it the first time a user logs in.
+
+Here's an example backend that authenticates against a username and password
+variable defined in your ``settings.py`` file and creates a Django ``User``
+object the first time a user authenticates::
+
+ from django.conf import settings
+ from django.contrib.auth.models import User, check_password
+
+ class SettingsBackend(object):
+ """
+ Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
+
+ Use the login name, and a hash of the password. For example:
+
+ ADMIN_LOGIN = 'admin'
+ ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
+ """
+
+ def authenticate(self, username=None, password=None):
+ login_valid = (settings.ADMIN_LOGIN == username)
+ pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
+ if login_valid and pwd_valid:
+ try:
+ user = User.objects.get(username=username)
+ except User.DoesNotExist:
+ # Create a new user. Note that we can set password
+ # to anything, because it won't be checked; the password
+ # from settings.py will.
+ user = User(username=username, password='get from settings.py')
+ user.is_staff = True
+ user.is_superuser = True
+ user.save()
+ return user
+ return None
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
+
+.. _authorization_methods:
+
+Handling authorization in custom backends
+-----------------------------------------
+
+Custom auth backends can provide their own permissions.
+
+The user model will delegate permission lookup functions
+(:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
+:meth:`~django.contrib.auth.models.User.get_all_permissions()`,
+:meth:`~django.contrib.auth.models.User.has_perm()`, and
+:meth:`~django.contrib.auth.models.User.has_module_perms()`) to any
+authentication backend that implements these functions.
+
+The permissions given to the user will be the superset of all permissions
+returned by all backends. That is, Django grants a permission to a user that
+any one backend grants.
+
+The simple backend above could implement permissions for the magic admin
+fairly simply::
+
+ class SettingsBackend(object):
+
+ # ...
+
+ def has_perm(self, user_obj, perm, obj=None):
+ if user_obj.username == settings.ADMIN_LOGIN:
+ return True
+ else:
+ return False
+
+This gives full permissions to the user granted access in the above example.
+Notice that in addition to the same arguments given to the associated
+:class:`django.contrib.auth.models.User` functions, the backend auth functions
+all take the user object, which may be an anonymous user, as an argument.
+
+A full authorization implementation can be found in the ``ModelBackend`` class
+in `django/contrib/auth/backends.py`_, which is the default backend and queries
+the ``auth_permission`` table most of the time. If you wish to provide
+custom behavior for only part of the backend API, you can take advantage of
+Python inheritance and subclass ``ModelBackend`` instead of implementing the
+complete API in a custom backend.
+
+.. _django/contrib/auth/backends.py: https://github.com/django/django/blob/master/django/contrib/auth/backends.py
+
+.. _anonymous_auth:
+
+Authorization for anonymous users
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An anonymous user is one that is not authenticated i.e. they have provided no
+valid authentication details. However, that does not necessarily mean they are
+not authorized to do anything. At the most basic level, most Web sites
+authorize anonymous users to browse most of the site, and many allow anonymous
+posting of comments etc.
+
+Django's permission framework does not have a place to store permissions for
+anonymous users. However, the user object passed to an authentication backend
+may be an :class:`django.contrib.auth.models.AnonymousUser` object, allowing
+the backend to specify custom authorization behavior for anonymous users. This
+is especially useful for the authors of re-usable apps, who can delegate all
+questions of authorization to the auth backend, rather than needing settings,
+for example, to control anonymous access.
+
+.. _inactive_auth:
+
+Authorization for inactive users
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An inactive user is a one that is authenticated but has its attribute
+``is_active`` set to ``False``. However this does not mean they are not
+authorized to do anything. For example they are allowed to activate their
+account.
+
+The support for anonymous users in the permission system allows for a scenario
+where anonymous users have permissions to do something while inactive
+authenticated users do not.
+
+Do not forget to test for the ``is_active`` attribute of the user in your own
+backend permission methods.
+
+
+Handling object permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django's permission framework has a foundation for object permissions, though
+there is no implementation for it in the core. That means that checking for
+object permissions will always return ``False`` or an empty list (depending on
+the check performed). An authentication backend will receive the keyword
+parameters ``obj`` and ``user_obj`` for each object related authorization
+method and can return the object level permission as appropriate.
+
+.. _custom-permissions:
+
+Custom permissions
+==================
+
+To create custom permissions for a given model object, use the ``permissions``
+:ref:`model Meta attribute <meta-options>`.
+
+This example Task model creates three custom permissions, i.e., actions users
+can or cannot do with Task instances, specific to your application::
+
+ class Task(models.Model):
+ ...
+ class Meta:
+ permissions = (
+ ("view_task", "Can see available tasks"),
+ ("change_task_status", "Can change the status of tasks"),
+ ("close_task", "Can remove a task by setting its status as closed"),
+ )
+
+The only thing this does is create those extra permissions when you run
+:djadmin:`manage.py syncdb <syncdb>`. Your code is in charge of checking the
+value of these permissions when an user is trying to access the functionality
+provided by the application (viewing tasks, changing the status of tasks,
+closing tasks.) Continuing the above example, the following checks if a user may
+view tasks::
+
+ user.has_perm('app.view_task')
+
+.. _extending-user:
+
+Extending the existing User model
+=================================
+
+There are two ways to extend the default
+:class:`~django.contrib.auth.models.User` model without substituting your own
+model. If the changes you need are purely behavioral, and don't require any
+change to what is stored in the database, you can create a :ref:`proxy model
+<proxy-models>` based on :class:`~django.contrib.auth.models.User`. This
+allows for any of the features offered by proxy models including default
+ordering, custom managers, or custom model methods.
+
+If you wish to store information related to ``User``, you can use a :ref:`one-to-one
+relationship <ref-onetoone>` to a model containing the fields for
+additional information. This one-to-one model is often called a profile model,
+as it might store non-auth related information about a site user. For example
+you might create an Employee model::
+
+ from django.contrib.auth.models import User
+
+ class Employee(models.Model):
+ user = models.OneToOneField(User)
+ department = models.CharField(max_length=100)
+
+Assuming an existing Employee Fred Smith who has both a User and Employee
+model, you can access the related information using Django's standard related
+model conventions::
+
+ >>> u = User.objects.get(username='fsmith')
+ >>> freds_department = u.employee.department
+
+To add a profile model's fields to the user page in the admin, define an
+:class:`~django.contrib.admin.InlineModelAdmin` (for this example, we'll use a
+:class:`~django.contrib.admin.StackedInline`) in your app's ``admin.py`` and
+add it to a ``UserAdmin`` class which is registered with the
+:class:`~django.contrib.auth.models.User` class::
+
+ from django.contrib import admin
+ from django.contrib.auth.admin import UserAdmin
+ from django.contrib.auth.models import User
+
+ from my_user_profile_app.models import Employee
+
+ # Define an inline admin descriptor for Employee model
+ # which acts a bit like a singleton
+ class EmployeeInline(admin.StackedInline):
+ model = Employee
+ can_delete = False
+ verbose_name_plural = 'employee'
+
+ # Define a new User admin
+ class UserAdmin(UserAdmin):
+ inlines = (EmployeeInline, )
+
+ # Re-register UserAdmin
+ admin.site.unregister(User)
+ admin.site.register(User, UserAdmin)
+
+These profile models are not special in any way - they are just Django models that
+happen to have a one-to-one link with a User model. As such, they do not get
+auto created when a user is created, but
+a :attr:`django.db.models.signals.post_save` could be used to create or update
+related models as appropriate.
+
+Note that using related models results in additional queries or joins to
+retrieve the related data, and depending on your needs substituting the User
+model and adding the related fields may be your better option. However
+existing links to the default User model within your project's apps may justify
+the extra database load.
+
+.. _auth-profiles:
+
+.. deprecated:: 1.5
+ With the introduction of :ref:`custom User models <auth-custom-user>`,
+ the use of :setting:`AUTH_PROFILE_MODULE` to define a single profile
+ model is no longer supported. See the
+ :doc:`Django 1.5 release notes</releases/1.5>` for more information.
+
+Prior to 1.5, a single profile model could be specified site-wide with the
+setting :setting:`AUTH_PROFILE_MODULE` with a string consisting of the
+following items, separated by a dot:
+
+1. The name of the application (case sensitive) in which the user
+ profile model is defined (in other words, the
+ name which was passed to :djadmin:`manage.py startapp <startapp>` to create
+ the application).
+
+2. The name of the model (not case sensitive) class.
+
+For example, if the profile model was a class named ``UserProfile`` and was
+defined inside an application named ``accounts``, the appropriate setting would
+be::
+
+ AUTH_PROFILE_MODULE = 'accounts.UserProfile'
+
+When a user profile model has been defined and specified in this manner, each
+:class:`~django.contrib.auth.models.User` object will have a method --
+:class:`~django.contrib.auth.models.User.get_profile()` -- which returns the
+instance of the user profile model associated with that
+:class:`~django.contrib.auth.models.User`.
+
+The method :class:`~django.contrib.auth.models.User.get_profile()`
+does not create a profile if one does not exist.
+
+.. _auth-custom-user:
+
+Substituting a custom User model
+================================
+
+.. versionadded:: 1.5
+
+Some kinds of projects may have authentication requirements for which Django's
+built-in :class:`~django.contrib.auth.models.User` model is not always
+appropriate. For instance, on some sites it makes more sense to use an email
+address as your identification token instead of a username.
+
+Django allows you to override the default User model by providing a value for
+the :setting:`AUTH_USER_MODEL` setting that references a custom model::
+
+ AUTH_USER_MODEL = 'myapp.MyUser'
+
+This dotted pair describes the name of the Django app, and the name of the Django
+model that you wish to use as your User model.
+
+.. admonition:: Warning
+
+ Changing :setting:`AUTH_USER_MODEL` has a big effect on your database
+ structure. It changes the tables that are available, and it will affect the
+ construction of foreign keys and many-to-many relationships. If you intend
+ to set :setting:`AUTH_USER_MODEL`, you should set it before running
+ ``manage.py syncdb`` for the first time.
+
+ If you have an existing project and you want to migrate to using a custom
+ User model, you may need to look into using a migration tool like South_
+ to ease the transition.
+
+.. _South: http://south.aeracode.org
+
+Referencing the User model
+--------------------------
+
+.. currentmodule:: django.contrib.auth
+
+If you reference :class:`~django.contrib.auth.models.User` directly (for
+example, by referring to it in a foreign key), your code will not work in
+projects where the :setting:`AUTH_USER_MODEL` setting has been changed to a
+different User model.
+
+.. function:: get_user_model()
+
+ Instead of referring to :class:`~django.contrib.auth.models.User` directly,
+ you should reference the user model using
+ ``django.contrib.auth.get_user_model()``. This method will return the
+ currently active User model -- the custom User model if one is specified, or
+ :class:`~django.contrib.auth.models.User` otherwise.
+
+ When you define a foreign key or many-to-many relations to the User model,
+ you should specify the custom model using the :setting:`AUTH_USER_MODEL`
+ setting. For example::
+
+
+ from django.conf import settings
+ from django.db import models
+
+ class Article(models.Model)
+ author = models.ForeignKey(settings.AUTH_USER_MODEL)
+
+Specifying a custom User model
+------------------------------
+
+.. admonition:: Model design considerations
+
+ Think carefully before handling information not directly related to
+ authentication in your custom User Model.
+
+ It may be better to store app-specific user information in a model
+ that has a relation with the User model. That allows each app to specify
+ its own user data requirements without risking conflicts with other
+ apps. On the other hand, queries to retrieve this related information
+ will involve a database join, which may have an effect on performance.
+
+Django expects your custom User model to meet some minimum requirements.
+
+1. Your model must have a single unique field that can be used for
+ identification purposes. This can be a username, an email address,
+ or any other unique attribute.
+
+2. Your model must provide a way to address the user in a "short" and
+ "long" form. The most common interpretation of this would be to use
+ the user's given name as the "short" identifier, and the user's full
+ name as the "long" identifier. However, there are no constraints on
+ what these two methods return - if you want, they can return exactly
+ the same value.
+
+The easiest way to construct a compliant custom User model is to inherit from
+:class:`~django.contrib.auth.models.AbstractBaseUser`.
+:class:`~django.contrib.auth.models.AbstractBaseUser` provides the core
+implementation of a `User` model, including hashed passwords and tokenized
+password resets. You must then provide some key implementation details:
+
+.. currentmodule:: django.contrib.auth
+
+.. class:: models.CustomUser
+
+ .. attribute:: USERNAME_FIELD
+
+ A string describing the name of the field on the User model that is
+ used as the unique identifier. This will usually be a username of
+ some kind, but it can also be an email address, or any other unique
+ identifier. In the following example, the field `identifier` is used
+ as the identifying field::
+
+ class MyUser(AbstractBaseUser):
+ identifier = models.CharField(max_length=40, unique=True, db_index=True)
+ ...
+ USERNAME_FIELD = 'identifier'
+
+ .. attribute:: REQUIRED_FIELDS
+
+ A list of the field names that *must* be provided when creating
+ a user. For example, here is the partial definition for a User model
+ that defines two required fields - a date of birth and height::
+
+ class MyUser(AbstractBaseUser):
+ ...
+ date_of_birth = models.DateField()
+ height = models.FloatField()
+ ...
+ REQUIRED_FIELDS = ['date_of_birth', 'height']
+
+ .. note::
+
+ ``REQUIRED_FIELDS`` must contain all required fields on your User
+ model, but should *not* contain the ``USERNAME_FIELD``.
+
+ .. attribute:: is_active
+
+ A boolean attribute that indicates whether the user is considered
+ "active". This attribute is provided as an attribute on
+ ``AbstractBaseUser`` defaulting to ``True``. How you choose to
+ implement it will depend on the details of your chosen auth backends.
+ See the documentation of the :attr:`attribute on the builtin user model
+ <django.contrib.auth.models.User.is_active>` for details.
+
+ .. method:: get_full_name()
+
+ A longer formal identifier for the user. A common interpretation
+ would be the full name name of the user, but it can be any string that
+ identifies the user.
+
+ .. method:: get_short_name()
+
+ A short, informal identifier for the user. A common interpretation
+ would be the first name of the user, but it can be any string that
+ identifies the user in an informal way. It may also return the same
+ value as :meth:`django.contrib.auth.models.User.get_full_name()`.
+
+The following methods are available on any subclass of
+:class:`~django.contrib.auth.models.AbstractBaseUser`:
+
+.. class:: models.AbstractBaseUser
+
+ .. method:: get_username()
+
+ Returns the value of the field nominated by ``USERNAME_FIELD``.
+
+ .. method:: models.AbstractBaseUser.is_anonymous()
+
+ Always returns ``False``. This is a way of differentiating
+ from :class:`~django.contrib.auth.models.AnonymousUser` objects.
+ Generally, you should prefer using
+ :meth:`~django.contrib.auth.models.AbstractBaseUser.is_authenticated()` to this
+ method.
+
+ .. method:: models.AbstractBaseUser.is_authenticated()
+
+ Always returns ``True``. This is a way to tell if the user has been
+ authenticated. This does not imply any permissions, and doesn't check
+ if the user is active - it only indicates that the user has provided a
+ valid username and password.
+
+ .. method:: models.AbstractBaseUser.set_password(raw_password)
+
+ Sets the user's password to the given raw string, taking care of the
+ password hashing. Doesn't save the
+ :class:`~django.contrib.auth.models.AbstractBaseUser` object.
+
+ .. method:: models.AbstractBaseUser.check_password(raw_password)
+
+ Returns ``True`` if the given raw string is the correct password for
+ the user. (This takes care of the password hashing in making the
+ comparison.)
+
+ .. method:: models.AbstractBaseUser.set_unusable_password()
+
+ Marks the user as having no password set. This isn't the same as
+ having a blank string for a password.
+ :meth:`~django.contrib.auth.models.AbstractBaseUser.check_password()` for this user
+ will never return ``True``. Doesn't save the
+ :class:`~django.contrib.auth.models.AbstractBaseUser` object.
+
+ You may need this if authentication for your application takes place
+ against an existing external source such as an LDAP directory.
+
+ .. method:: models.AbstractBaseUser.has_usable_password()
+
+ Returns ``False`` if
+ :meth:`~django.contrib.auth.models.AbstractBaseUser.set_unusable_password()` has
+ been called for this user.
+
+You should also define a custom manager for your User model. If your User
+model defines `username` and `email` fields the same as Django's default User,
+you can just install Django's
+:class:`~django.contrib.auth.models.UserManager`; however, if your User model
+defines different fields, you will need to define a custom manager that
+extends :class:`~django.contrib.auth.models.BaseUserManager` providing two
+additional methods:
+
+.. class:: models.CustomUserManager
+
+ .. method:: models.CustomUserManager.create_user(*username_field*, password=None, \**other_fields)
+
+ The prototype of `create_user()` should accept the username field,
+ plus all required fields as arguments. For example, if your user model
+ uses `email` as the username field, and has `date_of_birth` as a required
+ fields, then create_user should be defined as::
+
+ def create_user(self, email, date_of_birth, password=None):
+ # create user here
+
+ .. method:: models.CustomUserManager.create_superuser(*username_field*, password, \**other_fields)
+
+ The prototype of `create_superuser()` should accept the username field,
+ plus all required fields as arguments. For example, if your user model
+ uses `email` as the username field, and has `date_of_birth` as a required
+ fields, then create_superuser should be defined as::
+
+ def create_superuser(self, email, date_of_birth, password):
+ # create superuser here
+
+ Unlike `create_user()`, `create_superuser()` *must* require the caller
+ to provider a password.
+
+:class:`~django.contrib.auth.models.BaseUserManager` provides the following
+utility methods:
+
+.. class:: models.BaseUserManager
+
+ .. method:: models.BaseUserManager.normalize_email(email)
+
+ A classmethod that normalizes email addresses by lowercasing
+ the domain portion of the email address.
+
+ .. method:: models.BaseUserManager.get_by_natural_key(username)
+
+ Retrieves a user instance using the contents of the field
+ nominated by ``USERNAME_FIELD``.
+
+ .. method:: models.BaseUserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
+
+ Returns a random password with the given length and given string of
+ allowed characters. (Note that the default value of ``allowed_chars``
+ doesn't contain letters that can cause user confusion, including:
+
+ * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
+ letter L, uppercase letter i, and the number one)
+ * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
+ and zero)
+
+Extending Django's default User
+-------------------------------
+
+If you're entirely happy with Django's :class:`~django.contrib.auth.models.User`
+model and you just want to add some additional profile information, you can
+simply subclass ``django.contrib.auth.models.AbstractUser`` and add your
+custom profile fields. This class provides the full implementation of the
+default :class:`~django.contrib.auth.models.User` as an :ref:`abstract model
+<abstract-base-classes>`.
+
+Custom users and the built-in auth forms
+----------------------------------------
+
+As you may expect, built-in Django's :ref:`forms <built-in-auth-forms>` and
+:ref:`views <built-in-auth-views>` make certain assumptions about the user
+model that they are working with.
+
+If your user model doesn't follow the same assumptions, it may be necessary to define
+a replacement form, and pass that form in as part of the configuration of the
+auth views.
+
+* :class:`~django.contrib.auth.forms.UserCreationForm`
+
+ Depends on the :class:`~django.contrib.auth.models.User` model.
+ Must be re-written for any custom user model.
+
+* :class:`~django.contrib.auth.forms.UserChangeForm`
+
+ Depends on the :class:`~django.contrib.auth.models.User` model.
+ Must be re-written for any custom user model.
+
+* :class:`~django.contrib.auth.forms.AuthenticationForm`
+
+ Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`,
+ and will adapt to use the field defined in `USERNAME_FIELD`.
+
+* :class:`~django.contrib.auth.forms.PasswordResetForm`
+
+ Assumes that the user model has an integer primary key, has a field named
+ `email` that can be used to identify the user, and a boolean field
+ named `is_active` to prevent password resets for inactive users.
+
+* :class:`~django.contrib.auth.forms.SetPasswordForm`
+
+ Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
+
+* :class:`~django.contrib.auth.forms.PasswordChangeForm`
+
+ Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
+
+* :class:`~django.contrib.auth.forms.AdminPasswordChangeForm`
+
+ Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`
+
+
+Custom users and django.contrib.admin
+-------------------------------------
+
+If you want your custom User model to also work with Admin, your User model must
+define some additional attributes and methods. These methods allow the admin to
+control access of the User to admin content:
+
+.. class:: models.CustomUser
+
+.. attribute:: is_staff
+
+ Returns True if the user is allowed to have access to the admin site.
+
+.. attribute:: is_active
+
+ Returns True if the user account is currently active.
+
+.. method:: has_perm(perm, obj=None):
+
+ Returns True if the user has the named permission. If `obj` is
+ provided, the permission needs to be checked against a specific object
+ instance.
+
+.. method:: has_module_perms(app_label):
+
+ Returns True if the user has permission to access models in
+ the given app.
+
+You will also need to register your custom User model with the admin. If
+your custom User model extends ``django.contrib.auth.models.AbstractUser``,
+you can use Django's existing ``django.contrib.auth.admin.UserAdmin``
+class. However, if your User model extends
+:class:`~django.contrib.auth.models.AbstractBaseUser`, you'll need to define
+a custom ModelAdmin class. It may be possible to subclass the default
+``django.contrib.auth.admin.UserAdmin``; however, you'll need to
+override any of the definitions that refer to fields on
+``django.contrib.auth.models.AbstractUser`` that aren't on your
+custom User class.
+
+Custom users and permissions
+----------------------------
+
+To make it easy to include Django's permission framework into your own User
+class, Django provides :class:`~django.contrib.auth.models.PermissionsMixin`.
+This is an abstract model you can include in the class hierarchy for your User
+model, giving you all the methods and database fields necessary to support
+Django's permission model.
+
+:class:`~django.contrib.auth.models.PermissionsMixin` provides the following
+methods and attributes:
+
+.. class:: models.PermissionsMixin
+
+ .. attribute:: models.PermissionsMixin.is_superuser
+
+ Boolean. Designates that this user has all permissions without
+ explicitly assigning them.
+
+ .. method:: models.PermissionsMixin.get_group_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, through his/her
+ groups.
+
+ If ``obj`` is passed in, only returns the group permissions for
+ this specific object.
+
+ .. method:: models.PermissionsMixin.get_all_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, both through
+ group and user permissions.
+
+ If ``obj`` is passed in, only returns the permissions for this
+ specific object.
+
+ .. method:: models.PermissionsMixin.has_perm(perm, obj=None)
+
+ Returns ``True`` if the user has the specified permission, where perm is
+ in the format ``"<app label>.<permission codename>"`` (see
+ :ref:`permissions <topic-authorization>`). If the user is inactive, this method will
+ always return ``False``.
+
+ If ``obj`` is passed in, this method won't check for a permission for
+ the model, but for this specific object.
+
+ .. method:: models.PermissionsMixin.has_perms(perm_list, obj=None)
+
+ Returns ``True`` if the user has each of the specified permissions,
+ where each perm is in the format
+ ``"<app label>.<permission codename>"``. If the user is inactive,
+ this method will always return ``False``.
+
+ If ``obj`` is passed in, this method won't check for permissions for
+ the model, but for the specific object.
+
+ .. method:: models.PermissionsMixin.has_module_perms(package_name)
+
+ Returns ``True`` if the user has any permissions in the given package
+ (the Django app label). If the user is inactive, this method will
+ always return ``False``.
+
+.. admonition:: ModelBackend
+
+ If you don't include the
+ :class:`~django.contrib.auth.models.PermissionsMixin`, you must ensure you
+ don't invoke the permissions methods on ``ModelBackend``. ``ModelBackend``
+ assumes that certain fields are available on your user model. If your User
+ model doesn't provide those fields, you will receive database errors when
+ you check permissions.
+
+Custom users and Proxy models
+-----------------------------
+
+One limitation of custom User models is that installing a custom User model
+will break any proxy model extending :class:`~django.contrib.auth.models.User`.
+Proxy models must be based on a concrete base class; by defining a custom User
+model, you remove the ability of Django to reliably identify the base class.
+
+If your project uses proxy models, you must either modify the proxy to extend
+the User model that is currently in use in your project, or merge your proxy's
+behavior into your User subclass.
+
+Custom users and signals
+------------------------
+
+Another limitation of custom User models is that you can't use
+:func:`django.contrib.auth.get_user_model()` as the sender or target of a signal
+handler. Instead, you must register the handler with the resulting User model.
+See :doc:`/topics/signals` for more information on registering an sending
+signals.
+
+Custom users and testing/fixtures
+---------------------------------
+
+If you are writing an application that interacts with the User model, you must
+take some precautions to ensure that your test suite will run regardless of
+the User model that is being used by a project. Any test that instantiates an
+instance of User will fail if the User model has been swapped out. This
+includes any attempt to create an instance of User with a fixture.
+
+To ensure that your test suite will pass in any project configuration,
+``django.contrib.auth.tests.utils`` defines a ``@skipIfCustomUser`` decorator.
+This decorator will cause a test case to be skipped if any User model other
+than the default Django user is in use. This decorator can be applied to a
+single test, or to an entire test class.
+
+Depending on your application, tests may also be needed to be added to ensure
+that the application works with *any* user model, not just the default User
+model. To assist with this, Django provides two substitute user models that
+can be used in test suites:
+
+* ``django.contrib.auth.tests.custom_user.CustomUser``, a custom user
+ model that uses an ``email`` field as the username, and has a basic
+ admin-compliant permissions setup
+
+* ``django.contrib.auth.tests.custom_user.ExtensionUser``, a custom
+ user model that extends ``django.contrib.auth.models.AbstractUser``,
+ adding a ``date_of_birth`` field.
+
+You can then use the ``@override_settings`` decorator to make that test run
+with the custom User model. For example, here is a skeleton for a test that
+would test three possible User models -- the default, plus the two User
+models provided by ``auth`` app::
+
+ from django.contrib.auth.tests.utils import skipIfCustomUser
+ from django.test import TestCase
+ from django.test.utils import override_settings
+
+
+ class ApplicationTestCase(TestCase):
+ @skipIfCustomUser
+ def test_normal_user(self):
+ "Run tests for the normal user model"
+ self.assertSomething()
+
+ @override_settings(AUTH_USER_MODEL='auth.CustomUser')
+ def test_custom_user(self):
+ "Run tests for a custom user model with email-based authentication"
+ self.assertSomething()
+
+ @override_settings(AUTH_USER_MODEL='auth.ExtensionUser')
+ def test_extension_user(self):
+ "Run tests for a simple extension of the built-in User."
+ self.assertSomething()
+
+
+A full example
+--------------
+
+Here is an example of an admin-compliant custom user app. This user model uses
+an email address as the username, and has a required date of birth; it
+provides no permission checking, beyond a simple `admin` flag on the user
+account. This model would be compatible with all the built-in auth forms and
+views, except for the User creation forms.
+
+This code would all live in a ``models.py`` file for a custom
+authentication app::
+
+ from django.db import models
+ from django.contrib.auth.models import (
+ BaseUserManager, AbstractBaseUser
+ )
+
+
+ class MyUserManager(BaseUserManager):
+ def create_user(self, email, date_of_birth, password=None):
+ """
+ Creates and saves a User with the given email, date of
+ birth and password.
+ """
+ if not email:
+ raise ValueError('Users must have an email address')
+
+ user = self.model(
+ email=MyUserManager.normalize_email(email),
+ date_of_birth=date_of_birth,
+ )
+
+ user.set_password(password)
+ user.save(using=self._db)
+ return user
+
+ def create_superuser(self, email, date_of_birth, password):
+ """
+ Creates and saves a superuser with the given email, date of
+ birth and password.
+ """
+ user = self.create_user(email,
+ password=password,
+ date_of_birth=date_of_birth
+ )
+ user.is_admin = True
+ user.save(using=self._db)
+ return user
+
+
+ class MyUser(AbstractBaseUser):
+ email = models.EmailField(
+ verbose_name='email address',
+ max_length=255,
+ unique=True,
+ db_index=True,
+ )
+ date_of_birth = models.DateField()
+ is_active = models.BooleanField(default=True)
+ is_admin = models.BooleanField(default=False)
+
+ objects = MyUserManager()
+
+ USERNAME_FIELD = 'email'
+ REQUIRED_FIELDS = ['date_of_birth']
+
+ def get_full_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def get_short_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def __unicode__(self):
+ return self.email
+
+ def has_perm(self, perm, obj=None):
+ "Does the user have a specific permission?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ def has_module_perms(self, app_label):
+ "Does the user have permissions to view the app `app_label`?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ @property
+ def is_staff(self):
+ "Is the user a member of staff?"
+ # Simplest possible answer: All admins are staff
+ return self.is_admin
+
+Then, to register this custom User model with Django's admin, the following
+code would be required in the app's ``admin.py`` file::
+
+ from django import forms
+ from django.contrib import admin
+ from django.contrib.auth.models import Group
+ from django.contrib.auth.admin import UserAdmin
+ from django.contrib.auth.forms import ReadOnlyPasswordHashField
+
+ from customauth.models import MyUser
+
+
+ class UserCreationForm(forms.ModelForm):
+ """A form for creating new users. Includes all the required
+ fields, plus a repeated password."""
+ password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
+ password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
+
+ class Meta:
+ model = MyUser
+ fields = ('email', 'date_of_birth')
+
+ def clean_password2(self):
+ # Check that the two password entries match
+ password1 = self.cleaned_data.get("password1")
+ password2 = self.cleaned_data.get("password2")
+ if password1 and password2 and password1 != password2:
+ raise forms.ValidationError("Passwords don't match")
+ return password2
+
+ def save(self, commit=True):
+ # Save the provided password in hashed format
+ user = super(UserCreationForm, self).save(commit=False)
+ user.set_password(self.cleaned_data["password1"])
+ if commit:
+ user.save()
+ return user
+
+
+ class UserChangeForm(forms.ModelForm):
+ """A form for updating users. Includes all the fields on
+ the user, but replaces the password field with admin's
+ password hash display field.
+ """
+ password = ReadOnlyPasswordHashField()
+
+ class Meta:
+ model = MyUser
+
+ def clean_password(self):
+ # Regardless of what the user provides, return the initial value.
+ # This is done here, rather than on the field, because the
+ # field does not have access to the initial value
+ return self.initial["password"]
+
+
+ class MyUserAdmin(UserAdmin):
+ # The forms to add and change user instances
+ form = UserChangeForm
+ add_form = UserCreationForm
+
+ # The fields to be used in displaying the User model.
+ # These override the definitions on the base UserAdmin
+ # that reference specific fields on auth.User.
+ list_display = ('email', 'date_of_birth', 'is_admin')
+ list_filter = ('is_admin',)
+ fieldsets = (
+ (None, {'fields': ('email', 'password')}),
+ ('Personal info', {'fields': ('date_of_birth',)}),
+ ('Permissions', {'fields': ('is_admin',)}),
+ ('Important dates', {'fields': ('last_login',)}),
+ )
+ add_fieldsets = (
+ (None, {
+ 'classes': ('wide',),
+ 'fields': ('email', 'date_of_birth', 'password1', 'password2')}
+ ),
+ )
+ search_fields = ('email',)
+ ordering = ('email',)
+ filter_horizontal = ()
+
+ # Now register the new UserAdmin...
+ admin.site.register(MyUser, MyUserAdmin)
+ # ... and, since we're not using Django's builtin permissions,
+ # unregister the Group model from admin.
+ admin.site.unregister(Group)
diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
new file mode 100644
index 0000000000..c4736135b0
--- /dev/null
+++ b/docs/topics/auth/default.txt
@@ -0,0 +1,1077 @@
+======================================
+Using the Django authentication system
+======================================
+
+.. currentmodule:: django.contrib.auth
+
+This document explains the usage of Django's authentication system in its
+default configuration. This configuration has evolved to serve the most common
+project needs, handling a reasonably wide range of tasks, and has a careful
+implementation of passwords and permissions, and can handle many projects as
+is. For projects where authentication needs differ from the default, Django
+supports extensive :doc:`extension and customization
+</topics/auth/customizing>` of authentication.
+
+Django authentication provides both authentication and authorization, together
+and is generally referred to as the authentication system, as these features
+somewhat coupled.
+
+.. _user-objects:
+
+User objects
+============
+
+:class:`~django.contrib.auth.models.User` objects are the core of the
+authentication system. They typically represent the people interacting with
+your site and are used to enable things like restricting access, registering
+user profiles, associating content with creators etc. Only one class of user
+exists in Django's authentication framework, i.e., 'superusers' or admin
+'staff' users are is just a user objects with special attributes set, not
+different classes of user objects.
+
+The primary attributes of the default user are:
+
+* username
+* password
+* email
+* first name
+* last name
+
+See the :class:`full API documentation <django.contrib.auth.models.User>` for
+full reference, the documentation that follows is more task oriented.
+
+.. _topics-auth-creating-users:
+
+Creating users
+--------------
+
+The most direct way to create users is to use the included
+:meth:`~django.contrib.auth.models.UserManager.create_user` helper function::
+
+ >>> from django.contrib.auth.models import User
+ >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
+
+ # At this point, user is a User object that has already been saved
+ # to the database. You can continue to change its attributes
+ # if you want to change other fields.
+ >>> user.last_name = 'Lennon'
+ >>> user.save()
+
+If you have the Django admin installed, you can also :ref:`create users
+interactively <auth-admin>`.
+
+.. _topics-auth-creating-superusers:
+
+Creating superusers
+-------------------
+
+:djadmin:`manage.py syncdb <syncdb>` prompts you to create a superuser the
+first time you run it with ``'django.contrib.auth'`` in your
+:setting:`INSTALLED_APPS`. If you need to create a superuser at a later date,
+you can use a command line utility::
+
+ manage.py createsuperuser --username=joe --email=joe@example.com
+
+You will be prompted for a password. After you enter one, the user will be
+created immediately. If you leave off the :djadminopt:`--username` or the
+:djadminopt:`--email` options, it will prompt you for those values.
+
+Changing passwords
+------------------
+
+Django does not store raw (clear text) passwords on the user model, but only
+a hash (see :doc:`documentation of how passwords are managed
+</topics/auth/passwords>` for full details). Because of this, do not attempt to
+manipulate the password attribute of the user directly. This is why a a helper
+function is used when creating a user.
+
+To change a user's password, you have several options:
+
+:djadmin:`manage.py changepassword *username* <changepassword>` offers a method
+of changing a User's password from the command line. It prompts you to
+change the password of a given user which you must enter twice. If
+they both match, the new password will be changed immediately. If you
+do not supply a user, the command will attempt to change the password
+whose username matches the current system user.
+
+You can also change a password programmatically, using
+:meth:`~django.contrib.auth.models.User.set_password()`:
+
+.. code-block:: python
+
+ >>> from django.contrib.auth.models import User
+ >>> u = User.objects.get(username__exact='john')
+ >>> u.set_password('new password')
+ >>> u.save()
+
+If you have the Django admin installed, you can also change user's passwords
+on the :ref:`authentication system's admin pages <auth-admin>`.
+
+Django also provides :ref:`views <built-in-auth-views>` and :ref:`forms
+<built-in-auth-forms>` that may be used to allow users to change their own
+passwords.
+
+Authenticating Users
+--------------------
+
+.. function:: authenticate(\**credentials)
+
+ To authenticate a given username and password, use
+ :func:`~django.contrib.auth.authenticate()`. It takes credentials in the
+ form of keyword arguments, for the default configuration this is
+ ``username`` and ``password``, and it returns
+ a :class:`~django.contrib.auth.models.User` object if the password is valid
+ for the given username. If the password is invalid,
+ :func:`~django.contrib.auth.authenticate()` returns ``None``. Example::
+
+ from django.contrib.auth import authenticate
+ user = authenticate(username='john', password='secret')
+ if user is not None:
+ # the password verified for the user
+ if user.is_active:
+ print("User is valid, active and authenticated")
+ else:
+ print("The password is valid, but the account has been disabled!")
+ else:
+ # the authentication system was unable to verify the username and password
+ print("The username and password were incorrect.")
+
+.. _topic-authorization:
+
+Permissions and Authorization
+=============================
+
+Django comes with a simple permissions system. It provides a way to assign
+permissions to specific users and groups of users.
+
+It's used by the Django admin site, but you're welcome to use it in your own
+code.
+
+The Django admin site uses permissions as follows:
+
+* Access to view the "add" form and add an object is limited to users with
+ the "add" permission for that type of object.
+* Access to view the change list, view the "change" form and change an
+ object is limited to users with the "change" permission for that type of
+ object.
+* Access to delete an object is limited to users with the "delete"
+ permission for that type of object.
+
+Permissions can be set not only per type of object, but also per specific
+object instance. By using the
+:meth:`~django.contrib.admin.ModelAdmin.has_add_permission`,
+:meth:`~django.contrib.admin.ModelAdmin.has_change_permission` and
+:meth:`~django.contrib.admin.ModelAdmin.has_delete_permission` methods provided
+by the :class:`~django.contrib.admin.ModelAdmin` class, it is possible to
+customize permissions for different object instances of the same type.
+
+:class:`~django.contrib.auth.models.User` objects have two many-to-many
+fields: ``groups`` and ``user_permissions``.
+:class:`~django.contrib.auth.models.User` objects can access their related
+objects in the same way as any other :doc:`Django model
+</topics/db/models>`:
+
+.. code-block:: python
+
+ myuser.groups = [group_list]
+ myuser.groups.add(group, group, ...)
+ myuser.groups.remove(group, group, ...)
+ myuser.groups.clear()
+ myuser.user_permissions = [permission_list]
+ myuser.user_permissions.add(permission, permission, ...)
+ myuser.user_permissions.remove(permission, permission, ...)
+ myuser.user_permissions.clear()
+
+Default permissions
+-------------------
+
+When ``django.contrib.auth`` is listed in your :setting:`INSTALLED_APPS`
+setting, it will ensure that three default permissions -- add, change and
+delete -- are created for each Django model defined in one of your installed
+applications.
+
+These permissions will be created when you run :djadmin:`manage.py syncdb
+<syncdb>`; the first time you run ``syncdb`` after adding
+``django.contrib.auth`` to :setting:`INSTALLED_APPS`, the default permissions
+will be created for all previously-installed models, as well as for any new
+models being installed at that time. Afterward, it will create default
+permissions for new models each time you run :djadmin:`manage.py syncdb
+<syncdb>`.
+
+Assuming you have an application with an
+:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
+to test for basic permissions you should use:
+
+* add: ``user.has_perm('foo.add_bar')``
+* change: ``user.has_perm('foo.change_bar')``
+* delete: ``user.has_perm('foo.delete_bar')``
+
+The :class:`~django.contrib.auth.models.Permission` model is rarely accessed
+directly.
+
+Groups
+------
+
+:class:`django.contrib.auth.models.Group` models are a generic way of
+categorizing users so you can apply permissions, or some other label, to those
+users. A user can belong to any number of groups.
+
+A user in a group automatically has the permissions granted to that group. For
+example, if the group ``Site editors`` has the permission
+``can_edit_home_page``, any user in that group will have that permission.
+
+Beyond permissions, groups are a convenient way to categorize users to give
+them some label, or extended functionality. For example, you could create a
+group ``'Special users'``, and you could write code that could, say, give them
+access to a members-only portion of your site, or send them members-only email
+messages.
+
+Programmatically creating permissions
+-------------------------------------
+
+While :ref:`custom permissions <custom-permissions>` can be defined within
+a model's ``Meta`` class, you can also create permissions directly. For
+example, you can create the ``can_publish`` permission for a ``BlogPost`` model
+in ``myapp``::
+
+ from django.contrib.auth.models import Group, Permission
+ from django.contrib.contenttypes.models import ContentType
+
+ content_type = ContentType.objects.get(app_label='myapp', model='BlogPost')
+ permission = Permission.objects.create(codename='can_publish',
+ name='Can Publish Posts',
+ content_type=content_type)
+
+The permission can then be assigned to a
+:class:`~django.contrib.auth.models.User` via its ``user_permissions``
+attribute or to a :class:`~django.contrib.auth.models.Group` via its
+``permissions`` attribute.
+
+.. _auth-web-requests:
+
+Authentication in Web requests
+==============================
+
+Django uses :doc:`sessions </topics/http/sessions>` and middleware to hook the
+authentication system into :class:`request objects <django.http.HttpRequest>`.
+
+These provide a :attr:`request.user <django.http.HttpRequest.user>` attribute
+on every request which represents the current user. If the current user has not
+logged in, this attribute will be set to an instance
+of :class:`~django.contrib.auth.models.AnonymousUser`, otherwise it will be an
+instance of :class:`~django.contrib.auth.models.User`.
+
+You can tell them apart with
+:meth:`~django.contrib.auth.models.User.is_authenticated()`, like so::
+
+ if request.user.is_authenticated():
+ # Do something for authenticated users.
+ else:
+ # Do something for anonymous users.
+
+.. _how-to-log-a-user-in:
+
+How to log a user in
+--------------------
+
+If you have an authenticated user you want to attach to the current session
+- this is done with a :func:`~django.contrib.auth.login` function.
+
+.. function:: login()
+
+ To log a user in, from a view, use :func:`~django.contrib.auth.login()`. It
+ takes an :class:`~django.http.HttpRequest` object and a
+ :class:`~django.contrib.auth.models.User` object.
+ :func:`~django.contrib.auth.login()` saves the user's ID in the session,
+ using Django's session framework.
+
+ Note that any data set during the anonymous session is retained in the
+ session after a user logs in.
+
+ This example shows how you might use both
+ :func:`~django.contrib.auth.authenticate()` and
+ :func:`~django.contrib.auth.login()`::
+
+ from django.contrib.auth import authenticate, login
+
+ def my_view(request):
+ username = request.POST['username']
+ password = request.POST['password']
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ if user.is_active:
+ login(request, user)
+ # Redirect to a success page.
+ else:
+ # Return a 'disabled account' error message
+ else:
+ # Return an 'invalid login' error message.
+
+.. admonition:: Calling ``authenticate()`` first
+
+ When you're manually logging a user in, you *must* call
+ :func:`~django.contrib.auth.authenticate()` before you call
+ :func:`~django.contrib.auth.login()`.
+ :func:`~django.contrib.auth.authenticate()`
+ sets an attribute on the :class:`~django.contrib.auth.models.User` noting
+ which authentication backend successfully authenticated that user (see the
+ :ref:`backends documentation <authentication-backends>` for details), and
+ this information is needed later during the login process. An error will be
+ raise if you try to login a user object retrieved from the database
+ directly.
+
+How to log a user out
+---------------------
+
+.. function:: logout()
+
+ To log out a user who has been logged in via
+ :func:`django.contrib.auth.login()`, use
+ :func:`django.contrib.auth.logout()` within your view. It takes an
+ :class:`~django.http.HttpRequest` object and has no return value.
+ Example::
+
+ from django.contrib.auth import logout
+
+ def logout_view(request):
+ logout(request)
+ # Redirect to a success page.
+
+ Note that :func:`~django.contrib.auth.logout()` doesn't throw any errors if
+ the user wasn't logged in.
+
+ When you call :func:`~django.contrib.auth.logout()`, the session data for
+ the current request is completely cleaned out. All existing data is
+ removed. This is to prevent another person from using the same Web browser
+ to log in and have access to the previous user's session data. If you want
+ to put anything into the session that will be available to the user
+ immediately after logging out, do that *after* calling
+ :func:`django.contrib.auth.logout()`.
+
+Limiting access to logged-in users
+----------------------------------
+
+The raw way
+~~~~~~~~~~~
+
+The simple, raw way to limit access to pages is to check
+:meth:`request.user.is_authenticated()
+<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
+login page::
+
+ from django.shortcuts import redirect
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return redirect('/login/?next=%s' % request.path)
+ # ...
+
+...or display an error message::
+
+ from django.shortcuts import render
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return render('myapp/login_error.html')
+ # ...
+
+.. currentmodule:: django.contrib.auth.decorators
+
+The login_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: login_required([redirect_field_name=REDIRECT_FIELD_NAME, login_url=None])
+
+ As a shortcut, you can use the convenient
+ :func:`~django.contrib.auth.decorators.login_required` decorator::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required
+ def my_view(request):
+ ...
+
+ :func:`~django.contrib.auth.decorators.login_required` does the following:
+
+ * If the user isn't logged in, redirect to
+ :setting:`settings.LOGIN_URL <LOGIN_URL>`, passing the current absolute
+ path in the query string. Example: ``/accounts/login/?next=/polls/3/``.
+
+ * If the user is logged in, execute the view normally. The view code is
+ free to assume the user is logged in.
+
+ By default, the path that the user should be redirected to upon
+ successful authentication is stored in a query string parameter called
+ ``"next"``. If you would prefer to use a different name for this parameter,
+ :func:`~django.contrib.auth.decorators.login_required` takes an
+ optional ``redirect_field_name`` parameter::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required(redirect_field_name='my_redirect_field')
+ def my_view(request):
+ ...
+
+ Note that if you provide a value to ``redirect_field_name``, you will most
+ likely need to customize your login template as well, since the template
+ context variable which stores the redirect path will use the value of
+ ``redirect_field_name`` as its key rather than ``"next"`` (the default).
+
+ :func:`~django.contrib.auth.decorators.login_required` also takes an
+ optional ``login_url`` parameter. Example::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required(login_url='/accounts/login/')
+ def my_view(request):
+ ...
+
+ Note that if you don't specify the ``login_url`` parameter, you'll need to
+ ensure that the :setting:`settings.LOGIN_URL <LOGIN_URL>` and your login
+ view are properly associated. For example, using the defaults, add the
+ following line to your URLconf::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login'),
+
+ .. versionchanged:: 1.5
+
+ The :setting:`settings.LOGIN_URL <LOGIN_URL>` also accepts
+ view function names and :ref:`named URL patterns <naming-url-patterns>`.
+ This allows you to freely remap your login view within your URLconf
+ without having to update the setting.
+
+.. note::
+
+ The login_required decorator does NOT check the is_active flag on a user.
+
+Limiting access to logged-in users that pass a test
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To limit access based on certain permissions or some other test, you'd do
+essentially the same thing as described in the previous section.
+
+The simple way is to run your test on :attr:`request.user
+<django.http.HttpRequest.user>` in the view directly. For example, this view
+checks to make sure the user has an email in the desired domain::
+
+ def my_view(request):
+ if not '@example.com' in request.user.email:
+ return HttpResponse("You can't vote in this poll.")
+ # ...
+
+.. function:: user_passes_test(func, [login_url=None])
+
+ As a shortcut, you can use the convenient ``user_passes_test`` decorator::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ def email_check(user):
+ return '@example.com' in request.user.email
+
+ @user_passes_test(email_check)
+ def my_view(request):
+ ...
+
+ :func:`~django.contrib.auth.decorators.user_passes_test` takes a required
+ argument: a callable that takes a
+ :class:`~django.contrib.auth.models.User` object and returns ``True`` if
+ the user is allowed to view the page. Note that
+ :func:`~django.contrib.auth.decorators.user_passes_test` does not
+ automatically check that the :class:`~django.contrib.auth.models.User` is
+ not anonymous.
+
+ :func:`~django.contrib.auth.decorators.user_passes_test()` takes an
+ optional ``login_url`` argument, which lets you specify the URL for your
+ login page (:setting:`settings.LOGIN_URL <LOGIN_URL>` by default).
+
+ For example::
+
+ @user_passes_test(email_check, login_url='/login/')
+ def my_view(request):
+ ...
+
+The permission_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: permission_required([login_url=None, raise_exception=False])
+
+ It's a relatively common task to check whether a user has a particular
+ permission. For that reason, Django provides a shortcut for that case: the
+ :func:`~django.contrib.auth.decorators.permission_required()` decorator.::
+
+ from django.contrib.auth.decorators import permission_required
+
+ @permission_required('polls.can_vote')
+ def my_view(request):
+ ...
+
+ As for the :meth:`~django.contrib.auth.models.User.has_perm` method,
+ permission names take the form ``"<app label>.<permission codename>"``
+ (i.e. ``polls.can_vote`` for a permission on a model in the ``polls``
+ application).
+
+ Note that :func:`~django.contrib.auth.decorators.permission_required()`
+ also takes an optional ``login_url`` parameter. Example::
+
+ from django.contrib.auth.decorators import permission_required
+
+ @permission_required('polls.can_vote', login_url='/loginpage/')
+ def my_view(request):
+ ...
+
+ As in the :func:`~django.contrib.auth.decorators.login_required` decorator,
+ ``login_url`` defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>`.
+
+ .. versionchanged:: 1.4
+
+ Added ``raise_exception`` parameter. If given, the decorator will raise
+ :exc:`~django.core.exceptions.PermissionDenied`, prompting
+ :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` instead of
+ redirecting to the login page.
+
+Applying permissions to generic views
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To apply a permission to a :doc:`class-based generic view
+</ref/class-based-views/index>`, decorate the :meth:`View.dispatch
+<django.views.generic.base.View.dispatch>` method on the class. See
+:ref:`decorating-class-based-views` for details.
+
+
+.. _built-in-auth-views:
+
+Authentication Views
+--------------------
+
+.. module:: django.contrib.auth.views
+
+Django provides several views that you can use for handling login, logout, and
+password management. These make use of the :ref:`stock auth forms
+<built-in-auth-forms>` but you can pass in your own forms as well.
+
+Django provides no default template for the authentication views - however the
+template context is documented for each view below.
+
+.. versionadded:: 1.4
+
+The built-in views all return
+a :class:`~django.template.response.TemplateResponse` instance, which allows
+you to easily customize the response data before rendering. For more details,
+see the :doc:`TemplateResponse documentation </ref/template-response>`.
+
+Most built-in authentication views provide a URL name for easier reference. See
+:doc:`the URL documentation </topics/http/urls>` for details on using named URL
+patterns.
+
+
+.. function:: login(request, [template_name, redirect_field_name, authentication_form])
+
+ **URL name:** ``login``
+
+ See :doc:`the URL documentation </topics/http/urls>` for details on using
+ named URL patterns.
+
+ Here's what ``django.contrib.auth.views.login`` does:
+
+ * If called via ``GET``, it displays a login form that POSTs to the
+ same URL. More on this in a bit.
+
+ * If called via ``POST`` with user submitted credentials, it tries to log
+ the user in. If login is successful, the view redirects to the URL
+ specified in ``next``. If ``next`` isn't provided, it redirects to
+ :setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>` (which
+ defaults to ``/accounts/profile/``). If login isn't successful, it
+ redisplays the login form.
+
+ It's your responsibility to provide the html for the login template
+ , called ``registration/login.html`` by default. This template gets passed
+ four template context variables:
+
+ * ``form``: A :class:`~django.forms.Form` object representing the
+ :class:`~django.contrib.auth.forms.AuthenticationForm`.
+
+ * ``next``: The URL to redirect to after successful login. This may
+ contain a query string, too.
+
+ * ``site``: The current :class:`~django.contrib.sites.models.Site`,
+ according to the :setting:`SITE_ID` setting. If you don't have the
+ site framework installed, this will be set to an instance of
+ :class:`~django.contrib.sites.models.RequestSite`, which derives the
+ site name and domain from the current
+ :class:`~django.http.HttpRequest`.
+
+ * ``site_name``: An alias for ``site.name``. If you don't have the site
+ framework installed, this will be set to the value of
+ :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
+ For more on sites, see :doc:`/ref/contrib/sites`.
+
+ If you'd prefer not to call the template :file:`registration/login.html`,
+ you can pass the ``template_name`` parameter via the extra arguments to
+ the view in your URLconf. For example, this URLconf line would use
+ :file:`myapp/login.html` instead::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
+
+ You can also specify the name of the ``GET`` field which contains the URL
+ to redirect to after login by passing ``redirect_field_name`` to the view.
+ By default, the field is called ``next``.
+
+ Here's a sample :file:`registration/login.html` template you can use as a
+ starting point. It assumes you have a :file:`base.html` template that
+ defines a ``content`` block:
+
+ .. code-block:: html+django
+
+ {% extends "base.html" %}
+
+ {% block content %}
+
+ {% if form.errors %}
+ <p>Your username and password didn't match. Please try again.</p>
+ {% endif %}
+
+ <form method="post" action="{% url 'django.contrib.auth.views.login' %}">
+ {% csrf_token %}
+ <table>
+ <tr>
+ <td>{{ form.username.label_tag }}</td>
+ <td>{{ form.username }}</td>
+ </tr>
+ <tr>
+ <td>{{ form.password.label_tag }}</td>
+ <td>{{ form.password }}</td>
+ </tr>
+ </table>
+
+ <input type="submit" value="login" />
+ <input type="hidden" name="next" value="{{ next }}" />
+ </form>
+
+ {% endblock %}
+
+ If you have customized authentication (see
+ :doc:`Customizing Authentication </topics/auth/customizing>`) you can pass a custom authentication form
+ to the login view via the ``authentication_form`` parameter. This form must
+ accept a ``request`` keyword argument in its ``__init__`` method, and
+ provide a ``get_user`` method which returns the authenticated user object
+ (this method is only ever called after successful form validation).
+
+ .. _forms documentation: ../forms/
+ .. _site framework docs: ../sites/
+
+
+.. function:: logout(request, [next_page, template_name, redirect_field_name])
+
+ Logs a user out.
+
+ **URL name:** ``logout``
+
+ **Optional arguments:**
+
+ * ``next_page``: The URL to redirect to after logout.
+
+ * ``template_name``: The full name of a template to display after
+ logging the user out. Defaults to
+ :file:`registration/logged_out.html` if no argument is supplied.
+
+ * ``redirect_field_name``: The name of a ``GET`` field containing the
+ URL to redirect to after log out. Overrides ``next_page`` if the given
+ ``GET`` parameter is passed.
+
+ **Template context:**
+
+ * ``title``: The string "Logged out", localized.
+
+ * ``site``: The current :class:`~django.contrib.sites.models.Site`,
+ according to the :setting:`SITE_ID` setting. If you don't have the
+ site framework installed, this will be set to an instance of
+ :class:`~django.contrib.sites.models.RequestSite`, which derives the
+ site name and domain from the current
+ :class:`~django.http.HttpRequest`.
+
+ * ``site_name``: An alias for ``site.name``. If you don't have the site
+ framework installed, this will be set to the value of
+ :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
+ For more on sites, see :doc:`/ref/contrib/sites`.
+
+.. function:: logout_then_login(request[, login_url])
+
+ Logs a user out, then redirects to the login page.
+
+ **URL name:** No default URL provided
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to.
+ Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
+
+.. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
+
+ Allows a user to change their password.
+
+ **URL name:** ``password_change``
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password change form. Defaults to
+ :file:`registration/password_change_form.html` if not supplied.
+
+ * ``post_change_redirect``: The URL to redirect to after a successful
+ password change.
+
+ * ``password_change_form``: A custom "change password" form which must
+ accept a ``user`` keyword argument. The form is responsible for
+ actually changing the user's password. Defaults to
+ :class:`~django.contrib.auth.forms.PasswordChangeForm`.
+
+ **Template context:**
+
+ * ``form``: The password change form (see ``password_change_form`` above).
+
+.. function:: password_change_done(request[, template_name])
+
+ The page shown after a user has changed their password.
+
+ **URL name:** ``password_change_done``
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use.
+ Defaults to :file:`registration/password_change_done.html` if not
+ supplied.
+
+.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
+
+ Allows a user to reset their password by generating a one-time use link
+ that can be used to reset the password, and sending that link to the
+ user's registered email address.
+
+ .. versionchanged:: 1.4
+ Users flagged with an unusable password (see
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()`
+ will not be able to request a password reset to prevent misuse
+ when using an external authentication source like LDAP.
+
+ **URL name:** ``password_reset``
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password reset form. Defaults to
+ :file:`registration/password_reset_form.html` if not supplied.
+
+ * ``email_template_name``: The full name of a template to use for
+ generating the email with the reset password link. Defaults to
+ :file:`registration/password_reset_email.html` if not supplied.
+
+ * ``subject_template_name``: The full name of a template to use for
+ the subject of the email with the reset password link. Defaults
+ to :file:`registration/password_reset_subject.txt` if not supplied.
+
+ .. versionadded:: 1.4
+
+ * ``password_reset_form``: Form that will be used to get the email of
+ the user to reset the password for. Defaults to
+ :class:`~django.contrib.auth.forms.PasswordResetForm`.
+
+ * ``token_generator``: Instance of the class to check the one time link.
+ This will default to ``default_token_generator``, it's an instance of
+ ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
+
+ * ``post_reset_redirect``: The URL to redirect to after a successful
+ password reset request.
+
+ * ``from_email``: A valid email address. By default Django uses
+ the :setting:`DEFAULT_FROM_EMAIL`.
+
+ **Template context:**
+
+ * ``form``: The form (see ``password_reset_form`` above) for resetting
+ the user's password.
+
+ **Email template context:**
+
+ * ``email``: An alias for ``user.email``
+
+ * ``user``: The current :class:`~django.contrib.auth.models.User`,
+ according to the ``email`` form field. Only active users are able to
+ reset their passwords (``User.is_active is True``).
+
+ * ``site_name``: An alias for ``site.name``. If you don't have the site
+ framework installed, this will be set to the value of
+ :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
+ For more on sites, see :doc:`/ref/contrib/sites`.
+
+ * ``domain``: An alias for ``site.domain``. If you don't have the site
+ framework installed, this will be set to the value of
+ ``request.get_host()``.
+
+ * ``protocol``: http or https
+
+ * ``uid``: The user's id encoded in base 36.
+
+ * ``token``: Token to check that the reset link is valid.
+
+ Sample ``registration/password_reset_email.html`` (email body template):
+
+ .. code-block:: html+django
+
+ Someone asked for password reset for email {{ email }}. Follow the link below:
+ {{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb36=uid token=token %}
+
+ The same template context is used for subject template. Subject must be
+ single line plain text string.
+
+
+.. function:: password_reset_done(request[, template_name])
+
+ The page shown after a user has been emailed a link to reset their
+ password. This view is called by default if the :func:`password_reset` view
+ doesn't have an explicit ``post_reset_redirect`` URL set.
+
+ **URL name:** ``password_reset_done``
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use.
+ Defaults to :file:`registration/password_reset_done.html` if not
+ supplied.
+
+.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])
+
+ Presents a form for entering a new password.
+
+ **URL name:** ``password_reset_confirm``
+
+ **Optional arguments:**
+
+ * ``uidb36``: The user's id encoded in base 36. Defaults to ``None``.
+
+ * ``token``: Token to check that the password is valid. Defaults to
+ ``None``.
+
+ * ``template_name``: The full name of a template to display the confirm
+ password view. Default value is :file:`registration/password_reset_confirm.html`.
+
+ * ``token_generator``: Instance of the class to check the password. This
+ will default to ``default_token_generator``, it's an instance of
+ ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
+
+ * ``set_password_form``: Form that will be used to set the password.
+ Defaults to :class:`~django.contrib.auth.forms.SetPasswordForm`
+
+ * ``post_reset_redirect``: URL to redirect after the password reset
+ done. Defaults to ``None``.
+
+ **Template context:**
+
+ * ``form``: The form (see ``set_password_form`` above) for setting the
+ new user's password.
+
+ * ``validlink``: Boolean, True if the link (combination of uidb36 and
+ token) is valid or unused yet.
+
+.. function:: password_reset_complete(request[,template_name])
+
+ Presents a view which informs the user that the password has been
+ successfully changed.
+
+ **URL name:** ``password_reset_complete``
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to display the view.
+ Defaults to :file:`registration/password_reset_complete.html`.
+
+Helper functions
+----------------
+
+.. currentmodule:: django.contrib.auth.views
+
+.. function:: redirect_to_login(next[, login_url, redirect_field_name])
+
+ Redirects to the login page, and then back to another URL after a
+ successful login.
+
+ **Required arguments:**
+
+ * ``next``: The URL to redirect to after a successful login.
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to.
+ Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
+
+ * ``redirect_field_name``: The name of a ``GET`` field containing the
+ URL to redirect to after log out. Overrides ``next`` if the given
+ ``GET`` parameter is passed.
+
+
+.. _built-in-auth-forms:
+
+Built-in forms
+--------------
+
+.. module:: django.contrib.auth.forms
+
+If you don't want to use the built-in views, but want the convenience of not
+having to write forms for this functionality, the authentication system
+provides several built-in forms located in :mod:`django.contrib.auth.forms`:
+
+.. class:: AdminPasswordChangeForm
+
+ A form used in the admin interface to change a user's password.
+
+.. class:: AuthenticationForm
+
+ A form for logging a user in.
+
+.. class:: PasswordChangeForm
+
+ A form for allowing a user to change their password.
+
+.. class:: PasswordResetForm
+
+ A form for generating and emailing a one-time use link to reset a
+ user's password.
+
+.. class:: SetPasswordForm
+
+ A form that lets a user change his/her password without entering the old
+ password.
+
+.. class:: UserChangeForm
+
+ A form used in the admin interface to change a user's information and
+ permissions.
+
+.. class:: UserCreationForm
+
+ A form for creating a new user.
+
+.. currentmodule:: django.contrib.auth
+
+
+Authentication data in templates
+--------------------------------
+
+The currently logged-in user and his/her permissions are made available in the
+:doc:`template context </ref/templates/api>` when you use
+:class:`~django.template.RequestContext`.
+
+.. admonition:: Technicality
+
+ Technically, these variables are only made available in the template context
+ if you use :class:`~django.template.RequestContext` *and* your
+ :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
+ ``"django.contrib.auth.context_processors.auth"``, which is default. For
+ more, see the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
+
+Users
+~~~~~
+
+When rendering a template :class:`~django.template.RequestContext`, the
+currently logged-in user, either a :class:`~django.contrib.auth.models.User`
+instance or an :class:`~django.contrib.auth.models.AnonymousUser` instance, is
+stored in the template variable ``{{ user }}``:
+
+.. code-block:: html+django
+
+ {% if user.is_authenticated %}
+ <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
+ {% else %}
+ <p>Welcome, new user. Please log in.</p>
+ {% endif %}
+
+This template context variable is not available if a ``RequestContext`` is not
+being used.
+
+Permissions
+~~~~~~~~~~~
+
+The currently logged-in user's permissions are stored in the template variable
+``{{ perms }}``. This is an instance of
+``django.contrib.auth.context_processors.PermWrapper``, which is a
+template-friendly proxy of permissions.
+
+In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
+:meth:`User.has_module_perms <django.contrib.auth.models.User.has_module_perms>`.
+This example would display ``True`` if the logged-in user had any permissions
+in the ``foo`` app::
+
+ {{ perms.foo }}
+
+Two-level-attribute lookup is a proxy to
+:meth:`User.has_perm <django.contrib.auth.models.User.has_perm>`. This example
+would display ``True`` if the logged-in user had the permission
+``foo.can_vote``::
+
+ {{ perms.foo.can_vote }}
+
+Thus, you can check permissions in template ``{% if %}`` statements:
+
+.. code-block:: html+django
+
+ {% if perms.foo %}
+ <p>You have permission to do something in the foo app.</p>
+ {% if perms.foo.can_vote %}
+ <p>You can vote!</p>
+ {% endif %}
+ {% if perms.foo.can_drive %}
+ <p>You can drive!</p>
+ {% endif %}
+ {% else %}
+ <p>You don't have permission to do anything in the foo app.</p>
+ {% endif %}
+
+.. versionadded:: 1.5
+ Permission lookup by "if in".
+
+It is possible to also look permissions up by ``{% if in %}`` statements.
+For example:
+
+.. code-block:: html+django
+
+ {% if 'foo' in perms %}
+ {% if 'foo.can_vote' in perms %}
+ <p>In lookup works, too.</p>
+ {% endif %}
+ {% endif %}
+
+.. _auth-admin:
+
+Managing users in the admin
+===========================
+
+When you have both ``django.contrib.admin`` and ``django.contrib.auth``
+installed, the admin provides a convenient way to view and manage users,
+groups, and permissions. Users can be created and deleted like any Django
+model. Groups can be created, and permissions can be assigned to users or
+groups. A log of user edits to models made within the admin is also stored and
+displayed.
+
+Creating Users
+--------------
+
+You should see a link to "Users" in the "Auth"
+section of the main admin index page. The "Add user" admin page is different
+than standard admin pages in that it requires you to choose a username and
+password before allowing you to edit the rest of the user's fields.
+
+Also note: if you want a user account to be able to create users using the
+Django admin site, you'll need to give them permission to add users *and*
+change users (i.e., the "Add user" and "Change user" permissions). If an
+account has permission to add users but not to change them, that account won't
+be able to add users. Why? Because if you have permission to add users, you
+have the power to create superusers, which can then, in turn, change other
+users. So Django requires add *and* change permissions as a slight security
+measure.
+
+Changing Passwords
+------------------
+
+User passwords are not displayed in the admin (nor stored in the database), but
+the :doc:`password storage details </topics/auth/passwords>` are displayed.
+Included in the display of this information is a link to
+a password change form that allows admins to change user passwords.
diff --git a/docs/topics/auth/index.txt b/docs/topics/auth/index.txt
new file mode 100644
index 0000000000..ddb2d2f992
--- /dev/null
+++ b/docs/topics/auth/index.txt
@@ -0,0 +1,81 @@
+=============================
+User authentication in Django
+=============================
+
+.. toctree::
+ :hidden:
+
+ default
+ passwords
+ customizing
+
+.. module:: django.contrib.auth
+ :synopsis: Django's authentication framework.
+
+Django comes with an user authentication system. It handles user accounts,
+groups, permissions and cookie-based user sessions. This section of the
+documentation explains how the default implementation works out of the box, as
+well as how to :doc:`extend and customize </topics/auth/customizing>` it to
+suit your project's needs.
+
+Overview
+========
+
+The Django authentication system handles both authentication and authorization.
+Briefly, authentication verifies a user is who they claim to be, and
+authorization determines what an authenticated user is allowed to do. Here the
+term authentication is used to refer to both tasks.
+
+The auth system consists of:
+
+* Users
+* Permissions: Binary (yes/no) flags designating whether a user may perform
+ a certain task.
+* Groups: A generic way of applying labels and permissions to more than one
+ user.
+* A configurable password hashing system
+* Forms and view tools for logging in users, or restricting content
+* A pluggable backend system
+
+Installation
+============
+
+Authentication support is bundled as a Django contrib module in
+``django.contrib.auth``. By default, the required configuration is already
+included in the :file:`settings.py` generated by :djadmin:`django-admin.py
+startproject <startproject>`, these consist of two items listed in your
+:setting:`INSTALLED_APPS` setting:
+
+1. ``'django.contrib.auth'`` contains the core of the authentication framework,
+ and its default models.
+2. ``'django.contrib.contenttypes'`` is the Django :doc:`content type system
+ </ref/contrib/contenttypes>`, which allows permissions to be associated with
+ models you create.
+
+and two items in your :setting:`MIDDLEWARE_CLASSES` setting:
+
+1. :class:`~django.contrib.sessions.middleware.SessionMiddleware` manages
+ :doc:`sessions </topics/http/sessions>` across requests.
+2. :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` associates
+ users with requests using sessions.
+
+With these settings in place, running the command ``manage.py syncdb`` creates
+the necessary database tables for auth related models, creates permissions for
+any models defined in your installed apps, and prompts you to create
+a superuser account the first time you run it.
+
+Usage
+=====
+
+:doc:`Using Django's default implementation <default>`
+
+* :ref:`Working with User objects <user-objects>`
+* :ref:`Permissions and authorization <topic-authorization>`
+* :ref:`Authentication in web requests <auth-web-requests>`
+* :ref:`Managing users in the admin <auth-admin>`
+
+:doc:`API reference for the default implementation </ref/contrib/auth>`
+
+:doc:`Customizing Users and authentication <customizing>`
+
+:doc:`Password management in Django <passwords>`
diff --git a/docs/topics/auth/passwords.txt b/docs/topics/auth/passwords.txt
new file mode 100644
index 0000000000..e6345aab2e
--- /dev/null
+++ b/docs/topics/auth/passwords.txt
@@ -0,0 +1,212 @@
+=============================
+Password management in Django
+=============================
+
+Password management is something that should generally not be reinvented
+unnecessarily, and Django endeavors to provide a secure and flexible set of
+tools for managing user passwords. This document describes how Django stores
+passwords, how the storage hashing can be configured, and some utilities to
+work with hashed passwords.
+
+.. _auth_password_storage:
+
+How Django stores passwords
+===========================
+
+.. versionadded:: 1.4
+ Django 1.4 introduces a new flexible password storage system and uses
+ PBKDF2 by default. Previous versions of Django used SHA1, and other
+ algorithms couldn't be chosen.
+
+The :attr:`~django.contrib.auth.models.User.password` attribute of a
+:class:`~django.contrib.auth.models.User` object is a string in this format::
+
+ algorithm$hash
+
+That's a storage algorithm, and hash, separated by the dollar-sign
+character. The algorithm is one of a number of one way hashing or password
+storage algorithms Django can use; see below. The hash is the result of the one-
+way function.
+
+By default, Django uses the PBKDF2_ algorithm with a SHA256 hash, a
+password stretching mechanism recommended by NIST_. This should be
+sufficient for most users: it's quite secure, requiring massive
+amounts of computing time to break.
+
+However, depending on your requirements, you may choose a different
+algorithm, or even use a custom algorithm to match your specific
+security situation. Again, most users shouldn't need to do this -- if
+you're not sure, you probably don't. If you do, please read on:
+
+Django chooses the an algorithm by consulting the :setting:`PASSWORD_HASHERS`
+setting. This is a list of hashing algorithm classes that this Django
+installation supports. The first entry in this list (that is,
+``settings.PASSWORD_HASHERS[0]``) will be used to store passwords, and all the
+other entries are valid hashers that can be used to check existing passwords.
+This means that if you want to use a different algorithm, you'll need to modify
+:setting:`PASSWORD_HASHERS` to list your preferred algorithm first in the list.
+
+The default for :setting:`PASSWORD_HASHERS` is::
+
+ PASSWORD_HASHERS = (
+ 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.BCryptPasswordHasher',
+ 'django.contrib.auth.hashers.SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.MD5PasswordHasher',
+ 'django.contrib.auth.hashers.CryptPasswordHasher',
+ )
+
+This means that Django will use PBKDF2_ to store all passwords, but will support
+checking passwords stored with PBKDF2SHA1, bcrypt_, SHA1_, etc. The next few
+sections describe a couple of common ways advanced users may want to modify this
+setting.
+
+.. _bcrypt_usage:
+
+Using bcrypt with Django
+------------------------
+
+Bcrypt_ is a popular password storage algorithm that's specifically designed
+for long-term password storage. It's not the default used by Django since it
+requires the use of third-party libraries, but since many people may want to
+use it Django supports bcrypt with minimal effort.
+
+To use Bcrypt as your default storage algorithm, do the following:
+
+1. Install the `py-bcrypt`_ library (probably by running ``sudo pip install
+ py-bcrypt``, or downloading the library and installing it with ``python
+ setup.py install``).
+
+2. Modify :setting:`PASSWORD_HASHERS` to list ``BCryptPasswordHasher``
+ first. That is, in your settings file, you'd put::
+
+ PASSWORD_HASHERS = (
+ 'django.contrib.auth.hashers.BCryptPasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.MD5PasswordHasher',
+ 'django.contrib.auth.hashers.CryptPasswordHasher',
+ )
+
+ (You need to keep the other entries in this list, or else Django won't
+ be able to upgrade passwords; see below).
+
+That's it -- now your Django install will use Bcrypt as the default storage
+algorithm.
+
+.. admonition:: Other bcrypt implementations
+
+ There are several other implementations that allow bcrypt to be
+ used with Django. Django's bcrypt support is NOT directly
+ compatible with these. To upgrade, you will need to modify the
+ hashes in your database to be in the form `bcrypt$(raw bcrypt
+ output)`. For example:
+ `bcrypt$$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy`.
+
+Increasing the work factor
+--------------------------
+
+The PBKDF2 and bcrypt algorithms use a number of iterations or rounds of
+hashing. This deliberately slows down attackers, making attacks against hashed
+passwords harder. However, as computing power increases, the number of
+iterations needs to be increased. We've chosen a reasonable default (and will
+increase it with each release of Django), but you may wish to tune it up or
+down, depending on your security needs and available processing power. To do so,
+you'll subclass the appropriate algorithm and override the ``iterations``
+parameters. For example, to increase the number of iterations used by the
+default PBKDF2 algorithm:
+
+1. Create a subclass of ``django.contrib.auth.hashers.PBKDF2PasswordHasher``::
+
+ from django.contrib.auth.hashers import PBKDF2PasswordHasher
+
+ class MyPBKDF2PasswordHasher(PBKDF2PasswordHasher):
+ """
+ A subclass of PBKDF2PasswordHasher that uses 100 times more iterations.
+ """
+ iterations = PBKDF2PasswordHasher.iterations * 100
+
+ Save this somewhere in your project. For example, you might put this in
+ a file like ``myproject/hashers.py``.
+
+2. Add your new hasher as the first entry in :setting:`PASSWORD_HASHERS`::
+
+ PASSWORD_HASHERS = (
+ 'myproject.hashers.MyPBKDF2PasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.BCryptPasswordHasher',
+ 'django.contrib.auth.hashers.SHA1PasswordHasher',
+ 'django.contrib.auth.hashers.MD5PasswordHasher',
+ 'django.contrib.auth.hashers.CryptPasswordHasher',
+ )
+
+
+That's it -- now your Django install will use more iterations when it
+stores passwords using PBKDF2.
+
+Password upgrading
+------------------
+
+When users log in, if their passwords are stored with anything other than
+the preferred algorithm, Django will automatically upgrade the algorithm
+to the preferred one. This means that old installs of Django will get
+automatically more secure as users log in, and it also means that you
+can switch to new (and better) storage algorithms as they get invented.
+
+However, Django can only upgrade passwords that use algorithms mentioned in
+:setting:`PASSWORD_HASHERS`, so as you upgrade to new systems you should make
+sure never to *remove* entries from this list. If you do, users using un-
+mentioned algorithms won't be able to upgrade.
+
+.. _sha1: http://en.wikipedia.org/wiki/SHA1
+.. _pbkdf2: http://en.wikipedia.org/wiki/PBKDF2
+.. _nist: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
+.. _bcrypt: http://en.wikipedia.org/wiki/Bcrypt
+.. _py-bcrypt: http://pypi.python.org/pypi/py-bcrypt/
+
+
+Manually managing a user's password
+===================================
+
+.. module:: django.contrib.auth.hashers
+
+.. versionadded:: 1.4
+ The :mod:`django.contrib.auth.hashers` module provides a set of functions
+ to create and validate hashed password. You can use them independently
+ from the ``User`` model.
+
+.. function:: check_password(password, encoded)
+
+ .. versionadded:: 1.4
+
+ If you'd like to manually authenticate a user by comparing a plain-text
+ password to the hashed password in the database, use the convenience
+ function :func:`django.contrib.auth.hashers.check_password`. It takes two
+ arguments: the plain-text password to check, and the full value of a
+ user's ``password`` field in the database to check against, and returns
+ ``True`` if they match, ``False`` otherwise.
+
+.. function:: make_password(password[, salt, hashers])
+
+ .. versionadded:: 1.4
+
+ Creates a hashed password in the format used by this application. It takes
+ one mandatory argument: the password in plain-text. Optionally, you can
+ provide a salt and a hashing algorithm to use, if you don't want to use the
+ defaults (first entry of ``PASSWORD_HASHERS`` setting).
+ Currently supported algorithms are: ``'pbkdf2_sha256'``, ``'pbkdf2_sha1'``,
+ ``'bcrypt'`` (see :ref:`bcrypt_usage`), ``'sha1'``, ``'md5'``,
+ ``'unsalted_md5'`` (only for backward compatibility) and ``'crypt'``
+ if you have the ``crypt`` library installed. If the password argument is
+ ``None``, an unusable password is returned (a one that will be never
+ accepted by :func:`django.contrib.auth.hashers.check_password`).
+
+.. function:: is_password_usable(encoded_password)
+
+ .. versionadded:: 1.4
+
+ Checks if the given string is a hashed password that has a chance
+ of being verified against :func:`django.contrib.auth.hashers.check_password`.
diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt
index cfa794ca92..c4db0d77a7 100644
--- a/docs/topics/db/models.txt
+++ b/docs/topics/db/models.txt
@@ -1063,52 +1063,46 @@ Proxy models are declared like normal models. You tell Django that it's a
proxy model by setting the :attr:`~django.db.models.Options.proxy` attribute of
the ``Meta`` class to ``True``.
-For example, suppose you want to add a method to the standard
-:class:`~django.contrib.auth.models.User` model that will be used in your
-templates. You can do it like this::
+For example, suppose you want to add a method to the ``Person`` model described
+above. You can do it like this::
- from django.contrib.auth.models import User
-
- class MyUser(User):
+ class MyPerson(Person):
class Meta:
proxy = True
def do_something(self):
...
-The ``MyUser`` class operates on the same database table as its parent
-:class:`~django.contrib.auth.models.User` class. In particular, any new
-instances of :class:`~django.contrib.auth.models.User` will also be accessible
-through ``MyUser``, and vice-versa::
+The ``MyPerson`` class operates on the same database table as its parent
+``Person`` class. In particular, any new instances of ``Person`` will also be
+accessible through ``MyPerson``, and vice-versa::
- >>> u = User.objects.create(username="foobar")
- >>> MyUser.objects.get(username="foobar")
- <MyUser: foobar>
+ >>> p = Person.objects.create(first_name="foobar")
+ >>> MyPerson.objects.get(first_name="foobar")
+ <MyPerson: foobar>
-You could also use a proxy model to define a different default ordering on a
-model. The standard :class:`~django.contrib.auth.models.User` model has no
-ordering defined on it (intentionally; sorting is expensive and we don't want
-to do it all the time when we fetch users). You might want to regularly order
-by the ``username`` attribute when you use the proxy. This is easy::
+You could also use a proxy model to define a different default ordering on
+a model. You might not always want to order the ``Person`` model, but regularly
+order by the ``last_name`` attribute when you use the proxy. This is easy::
- class OrderedUser(User):
+ class OrderedPerson(Person):
class Meta:
- ordering = ["username"]
+ ordering = ["last_name"]
proxy = True
-Now normal :class:`~django.contrib.auth.models.User` queries will be unordered
-and ``OrderedUser`` queries will be ordered by ``username``.
+Now normal ``Person`` queries will be unordered
+and ``OrderedPerson`` queries will be ordered by ``last_name``.
QuerySets still return the model that was requested
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-There is no way to have Django return, say, a ``MyUser`` object whenever you
-query for :class:`~django.contrib.auth.models.User` objects. A queryset for
-``User`` objects will return those types of objects. The whole point of proxy
-objects is that code relying on the original ``User`` will use those and your
-own code can use the extensions you included (that no other code is relying on
-anyway). It is not a way to replace the ``User`` (or any other) model
-everywhere with something of your own creation.
+There is no way to have Django return, say, a ``MyPerson`` object whenever you
+query for ``Person`` objects. A queryset for ``Person`` objects will return
+those types of objects. The whole point of proxy objects is that code relying
+on the original ``Person`` will use those and your own code can use the
+extensions you included (that no other code is relying on anyway). It is not
+a way to replace the ``Person`` (or any other) model everywhere with something
+of your own creation.
Base class restrictions
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1131,12 +1125,12 @@ it will become the default, although any managers defined on the parent
classes will still be available.
Continuing our example from above, you could change the default manager used
-when you query the ``User`` model like this::
+when you query the ``Person`` model like this::
class NewManager(models.Manager):
...
- class MyUser(User):
+ class MyPerson(Person):
objects = NewManager()
class Meta:
@@ -1154,7 +1148,7 @@ containing the new managers and inherit that after the primary base class::
class Meta:
abstract = True
- class MyUser(User, ExtraManagers):
+ class MyPerson(Person, ExtraManagers):
class Meta:
proxy = True
diff --git a/docs/topics/index.txt b/docs/topics/index.txt
index 82c5859b2c..a69318f05c 100644
--- a/docs/topics/index.txt
+++ b/docs/topics/index.txt
@@ -14,7 +14,7 @@ Introductions to all the key parts of Django you'll need to know:
class-based-views/index
files
testing/index
- auth
+ auth/index
cache
conditional-view-processing
signing
diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
index c1c2a32f55..0627bd40d7 100644
--- a/docs/topics/testing/overview.txt
+++ b/docs/topics/testing/overview.txt
@@ -651,7 +651,7 @@ Use the ``django.test.client.Client`` class to make requests.
.. method:: Client.login(**credentials)
- If your site uses Django's :doc:`authentication system</topics/auth>`
+ If your site uses Django's :doc:`authentication system</topics/auth/index>`
and you deal with logging in users, you can use the test client's
``login()`` method to simulate the effect of a user logging into the
site.
@@ -695,7 +695,7 @@ Use the ``django.test.client.Client`` class to make requests.
.. method:: Client.logout()
- If your site uses Django's :doc:`authentication system</topics/auth>`,
+ If your site uses Django's :doc:`authentication system</topics/auth/index>`,
the ``logout()`` method can be used to simulate the effect of a user
logging out of your site.