diff options
Diffstat (limited to 'passlib/ext/django')
-rw-r--r-- | passlib/ext/django/__init__.py | 2 | ||||
-rw-r--r-- | passlib/ext/django/models.py | 84 | ||||
-rw-r--r-- | passlib/ext/django/utils.py | 55 |
3 files changed, 56 insertions, 85 deletions
diff --git a/passlib/ext/django/__init__.py b/passlib/ext/django/__init__.py index 1545e9c..b4fcb2c 100644 --- a/passlib/ext/django/__init__.py +++ b/passlib/ext/django/__init__.py @@ -6,5 +6,5 @@ and not officially documented in Passlib just yet (though it should work). -see ``models`` submodule for details on how this app works. +see the Passlib documentation for details on how to use this app """ diff --git a/passlib/ext/django/models.py b/passlib/ext/django/models.py index 02b54cc..aaf13ee 100644 --- a/passlib/ext/django/models.py +++ b/passlib/ext/django/models.py @@ -6,58 +6,7 @@ and not officially documented in Passlib just yet (though it should work). -When this is imported on Django load, -it automatically monkeypatches -:class:`django.contrib.auth.models.User` -to use a Passlib CryptContext instance in place of normal Django -password authentication. This provides hash migration, -ability to set stronger policies for superuser & staff passwords, -and stronger password hashing schemes. - -You can set the following options in django ``settings.py``: - -``PASSLIB_CONTEXT`` - This may be one of a number of values: - - * The string ``"passlib-default"``, which will cause Passlib - to replace Django's hash routines with a builtin policy - that supports all existing django hashes; but as users - log in, upgrades them all to :class:`~passlib.hash.pbkdf2_sha256`. - It also supports stronger hashing for the superuser account. - - This is the default behavior if ``PASSLIB_CONTEXT`` is not set. - - The exact policy can be found at - :data:`passlib.ext.django.models.passlib_default_ctx`. - - * ``None``, in which case this app will do nothing when django is loaded. - - * A :class:`~passlib.context.CryptContext` - instance which will be used in place of the normal Django password - hash routines. - - It is *strongly* recommended to use a context which will support - the existing Django hashes. - - * A multiline config string suitable for passing to - :meth:`passlib.context.CryptPolicy.from_string`. - This will be parsed and used much like a :class:`!CryptContext` instance. - -``PASSLIB_GET_CATEGORY`` - - By default, Passlib will invoke the specified context with a category - string that's dependant on the User instance. - superusers will be assigned to the ``superuser`` category, - staff to the ``staff`` category, and all other accounts - assigned to ``None``. - - This allows overriding that logic by specifying an alternate - function of the format ``get_category(user) -> category|None``. - - .. seealso:: - - See :ref:`user-categories` for more details about - the category system in Passlib. +see the Passlib documentation for details on how to use this app """ #=================================================================== #imports @@ -67,33 +16,8 @@ from django.conf import settings #pkg from passlib.context import CryptContext, CryptPolicy from passlib.utils import is_crypt_context, bytes -from passlib.ext.django.utils import get_category, set_django_password_context - -#=================================================================== -#constants -#=================================================================== - -#: default context used by app -passlib_default_ctx = """ -[passlib] -schemes = - pbkdf2_sha256, - django_salted_sha1, django_salted_md5, - django_des_crypt, hex_md5, - django_disabled - -default = pbkdf2_sha256 - -deprecated = - django_salted_sha1, django_salted_md5, - django_des_crypt, hex_md5 - -all__vary_rounds = 5%% - -pbkdf2_sha256__default_rounds = 4000 -staff__pbkdf2_sha256__default_rounds = 8000 -superuser__pbkdf2_sha256__default_rounds = 10000 -""" +from passlib.ext.django.utils import DEFAULT_CTX, get_category, \ + set_django_password_context #=================================================================== #main @@ -107,7 +31,7 @@ def patch(): if not ctx: return if ctx == "passlib-default": - ctx = passlib_default_ctx + ctx = DEFAULT_CTX if isinstance(ctx, (unicode, bytes)): ctx = CryptPolicy.from_string(ctx) if isinstance(ctx, CryptPolicy): diff --git a/passlib/ext/django/utils.py b/passlib/ext/django/utils.py index 9285f16..41d4196 100644 --- a/passlib/ext/django/utils.py +++ b/passlib/ext/django/utils.py @@ -10,7 +10,6 @@ #imports #=================================================================== #site -from django.contrib.auth.models import User #pkg from passlib.utils import is_crypt_context, bytes #local @@ -20,6 +19,45 @@ __all__ = [ ] #=================================================================== +#lazy import +#=================================================================== +#NOTE: doing this lazily so sphinx can crawl module without +# having django import problems. + +User = None #imported from django.contrib.auth.models + +def _lazy_import(): + global User + if User is None: + from django.contrib.auth.models import User + +#=================================================================== +#constants +#=================================================================== + +#: default context used by app +DEFAULT_CTX = """ +[passlib] +schemes = + pbkdf2_sha256, + django_salted_sha1, django_salted_md5, + django_des_crypt, hex_md5, + django_disabled + +default = pbkdf2_sha256 + +deprecated = + django_salted_sha1, django_salted_md5, + django_des_crypt, hex_md5 + +all__vary_rounds = 5%% + +pbkdf2_sha256__default_rounds = 4000 +staff__pbkdf2_sha256__default_rounds = 8000 +superuser__pbkdf2_sha256__default_rounds = 10000 +""" + +#=================================================================== #monkeypatch framework #=================================================================== @@ -31,7 +69,15 @@ __all__ = [ _django_patch_state = None def get_category(user): - "default get_category() implementation used by set_django_password_context" + """default get_category() implementation used by set_django_password_context + + this is the function used if ``settings.PASSLIB_GET_CONTEXT`` is not + specified. + + it maps superusers to the ``"superuser"`` category, + staff to the ``"staff"`` category, + and all others to the default category. + """ if user.is_superuser: return "superuser" if user.is_staff: @@ -43,7 +89,7 @@ def um(func): return func.im_func def set_django_password_context(context=None, get_category=get_category): - """monkeypatches django.contrib.auth to use specified password context + """monkeypatches :mod:`!django.contrib.auth` to use specified password context. :arg context: Passlib context to use for Django password hashing. @@ -64,8 +110,9 @@ def set_django_password_context(context=None, get_category=get_category): By default, uses a function which returns ``"superuser"`` for superusers, and ``"staff"`` for staff. """ - global _django_patch_state + global _django_patch_state, User state = _django_patch_state + _lazy_import() # issue warning if something else monkeypatched User # while our patch was applied. |