diff options
author | Eli Collins <elic@assurancetechnologies.com> | 2016-07-29 13:08:11 -0400 |
---|---|---|
committer | Eli Collins <elic@assurancetechnologies.com> | 2016-07-29 13:08:11 -0400 |
commit | e8bb0ffb84a6e5bc3ebb2af21c90ccc64d97b2cb (patch) | |
tree | f505946e6b3aadfe6f9a6f08de93ecb4600a5ea4 | |
parent | b1e09fe9533d5de145111beee76ee0a82534b536 (diff) | |
download | passlib-e8bb0ffb84a6e5bc3ebb2af21c90ccc64d97b2cb.tar.gz |
docs: large reorganization of documentation
* reordering into 'narrative' and 'reference' sections,
to take advantage of 'fulltoc' extension making
all pages visible in sidebar.
* styling updates, requires latest cloud_sptheme
* wording improvements to various bits of content
-rw-r--r-- | CHANGES | 246 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | docs/conf.py | 25 | ||||
-rw-r--r-- | docs/contents.rst | 31 | ||||
-rw-r--r-- | docs/index.rst | 109 | ||||
-rw-r--r-- | docs/lib/passlib.context-tutorial.rst | 11 | ||||
-rw-r--r-- | docs/lib/passlib.context.rst | 9 | ||||
-rw-r--r-- | docs/lib/passlib.exc.rst | 6 | ||||
-rw-r--r-- | docs/lib/passlib.hash.bcrypt.rst | 9 | ||||
-rw-r--r-- | docs/lib/passlib.hash.rst | 186 | ||||
-rw-r--r-- | docs/lib/passlib.pwd.rst | 2 | ||||
-rw-r--r-- | docs/lib/passlib.totp-tutorial.rst | 36 | ||||
-rw-r--r-- | docs/lib/passlib.totp.rst | 40 | ||||
-rw-r--r-- | docs/modular_crypt_format.rst | 30 | ||||
-rw-r--r-- | docs/new_app_quickstart.rst | 21 | ||||
-rw-r--r-- | docs/password_hash_api.rst | 2 |
16 files changed, 425 insertions, 340 deletions
@@ -6,25 +6,33 @@ Release History =============== -Future Changes -============== +.. rst-class:: without-title -The following is not a comprehensive list of upcoming changes, -but merely a summary of important changes which may impact developers: +.. note:: + + **Upcoming Changes** + + As a heads-up, developers may be impacted by the following changes + planned for future releases: -* v1.8: + * **v1.8:** - - Removal of long-deprecated :class:`CryptPolicy` class. - - Removal of deprecated methods from :mod:`passlib.apache`. + - :mod:`passlib.context`: Removal of long-deprecated :class:`!CryptPolicy` class. + - :mod:`passlib.apache`: Removal of deprecated v1.5 compatibility methods. -* v2.0: + * **v2.0:** - - A *large* number of deprecated methods and features will be removed; - primarily the deprecated :meth:`!hasher.encrypt` alias. + .. currentmodule:: passlib.ifc - - CryptContexts will default to ``deprecated="auto"``, meaning - all but the first scheme will be considered deprecated unless - explicitly stated otherwise. + - A *large* number of deprecated methods and features will be removed; + primarily the deprecated :meth:`PasswordHash.encrypt` + and :meth:`CryptContext.encrypt` aliases. + + - :mod:`passlib.context`: :class:`!CryptContext` objects will default to ``deprecated="auto"``, + meaning all but the first scheme will be considered deprecated unless + explicitly stated otherwise. + +.. rst-class:: emphasize-children toc-always-open **1.7** (NOT YET RELEASED) ========================== @@ -56,15 +64,19 @@ Overview This release includes a number of new features, cleans up some long-standing design issues, and contains a number of internal - improvements; all part of the roadmap towards passlib 2.0. + improvements; all part of the roadmap towards a leaner and simpler Passlib 2.0. *Highlights include:* - * Support for :class:`~passlib.hash.argon2` and :class:`~passlib.hash.scrypt` + * Support for :class:`~passlib.hash.argon2` and + :class:`~passlib.hash.scrypt` hashes. + + .. currentmodule:: passlib.ifc - * The misnamed :meth:`~passlib.ifc.PasswordHash.encrypt` method is deprecated, new code should - now call :meth:`~passlib.ifc.PasswordHash.hash` instead. This is part of a much - larger project to clean up passlib's password hashing API. + * The misnamed :meth:`PasswordHash.encrypt` method is deprecated, new code should + now call :meth:`PasswordHash.hash` instead. This is part of a much + larger project to clean up passlib's password hashing API + (see *Deprecations* below) * Experimental TOTP (two factor authentication) helpers in the :mod:`passlib.totp` module. @@ -80,28 +92,33 @@ Requirements * The :mod:`passlib.ext.django` extension now requires Django 1.8 or better. Django 1.7 and earlier are no longer supported. -New Hashes ----------- - * :class:`~passlib.hash.argon2` -- Support for the Argon2 password hash (:issue:`69`). +New Features +------------ - * :class:`~passlib.hash.scrypt` -- New password hash format which uses - the SCrypt KDF (:issue:`8`). +*New Hashes* - * Added :class:`~passlib.hash.cisco_asa` which provides (tentative) - support for Cisco ASA 7.0 and newer hashes (:issue:`51`). + * :doc:`passlib.hash.argon2 </lib/passlib.hash.argon2>` -- + Support for the Argon2 password hash (:issue:`69`). + + * :doc:`passlib.hash.scrypt </lib/passlib.hash.scrypt>` -- + New password hash format which uses the SCrypt KDF (:issue:`8`). + + * :doc:`passlib.hash.cisco_asa </lib/passlib.hash.cisco_asa>` -- + Support for Cisco ASA 7.0 and newer hashes (:issue:`51`). + *Note: this should be considered experimental, and needs verification + of it's test vectors.* + +*New Modules* -New Features ------------- * New :mod:`passlib.totp` module provides full support for TOTP & HOTP tokens - on both client and server side. Contains both low-level primitives, and high-level - helpers for persisting and tracking client state. + on both client and server side. This module contains both low-level primitives, + and high-level helpers for persisting and tracking client state. * New :mod:`passlib.pwd` module added to aid in password generation. + Features support for alphanumeric passwords, or generation + of phrases using wordsets such as Diceware. - * The :func:`~passlib.crypto.digest.pbkdf2_hmac` function and all PBKDF2-based - hashes have been sped up by ~20% compared to Passlib 1.6. For an even greater - speedup, it will now use `fastpbk2 <https://pypi.python.org/pypi/fastpbkdf2>`_ - or stdlib's :func:`hashlib.pbkdf2_hmac` (when available). +*CryptContext Features* * The :class:`~passlib.context.CryptContext` object now has helper methods for dealing with hashes representing @@ -119,6 +136,13 @@ New Features This configurable via (for example) ``bcrypt.using(truncate_error=True).hash(secret)``, or globally as an option to CryptContext (:issue:`59`). +*Cryptographic Backends* + + * The :func:`~passlib.crypto.digest.pbkdf2_hmac` function and all PBKDF2-based + hashes have been sped up by ~20% compared to Passlib 1.6. For an even greater + speedup, it will now take advantage of the external `fastpbk2 <https://pypi.python.org/pypi/fastpbkdf2>`_ + library, or stdlib's :func:`hashlib.pbkdf2_hmac` (when available). + Bugfixes -------- * :class:`~passlib.hash.bcrypt`: Passlib will now detect and work around @@ -129,97 +153,121 @@ Bugfixes :doc:`bcrypt </lib/passlib.hash.bcrypt>` hash. * :class:`~passlib.CryptContext` instances now pass contextual keywords (such as `"user"`) - to the hashes that support them, but ignores them for hashes that don't. This should - fix :issue:`63`. + to the hashes that support them, but ignore them for hashes that don't (:issue:`63`). * The :mod:`passlib.apache` htpasswd helpers now preserve blank lines and comments, - rather than choking on them (:issue:`73`). + rather than throwing a parse error (:issue:`73`). * :mod:`passlib.ext.django` and unittests: compatibility fixes for Django 1.9, - and some internal cleanups (fixes :issue:`68`). + and some internal cleanups (:issue:`68`). * The :class:`~passlib.hash.django_disabled` hash now appends - a 40-char alphanumeric string, to match Django. + a 40-char alphanumeric string, to match Django's behavior. Other Changes ------------- +*Internal Changes* + + .. currentmodule:: passlib.ifc + * The majority of CryptContext's internal rounds handling & migration code has been - moved to the password hashes themselves, via the new :meth:`~passlib.ifc.PasswordHash.using` - and :meth:`~passlib.ifc.PasswordHash.needs_update` methods. + moved to the password hashes themselves, taking advantage of the new :meth:`PasswordHash.using` + and :meth:`PasswordHash.needs_update` methods. - This allows much more flexibility - when using a hash directly, rather than via CryptContext, as well making it easier for - CryptContext to support hash-specific parameters. + This allows much more flexibility when configuring a hasher directly, + as well making it easier for CryptContext to support hash-specific parameters. - * [minor] The shared :class:`!PasswordHash` unittests now check all hash handlers for + * The shared :class:`!PasswordHash` unittests now check all hash handlers for basic thread-safety (motivated by the pybcrypt 0.2 concurrency bug). - * [trivial] :func:`~passlib.utils.consteq` is now an alias for stdlib's :func:`hmac.compare_digest` - under python 3.3 and up. + * :func:`~passlib.utils.consteq` is now wraps stdlib's :func:`hmac.compare_digest` + when available (python 2.7.11, python 3.3 and up). + +.. _encrypt-method-cleanup: Deprecations ------------ As part of a long-range plan to restructure and simplify both the API and the internals of Passlib, a number of methods have been deprecated & replaced. The eventually goal is a large cleanup -and overhaul as part of Passlib 2.0. There will be at least one more major release (1.8 or 1.9) -before Passlib 2.0 is released. +and overhaul as part of Passlib 2.0. There will be at least one more 1.x version +before Passlib 2.0, to provide a final transitional release. -Password Hash API -................. -Towards that end, the :class:`~passlib.ifc.PasswordHash` API (used by all hashes in passlib), -has had a number of changes made: +Password Hash API Deprecations +.............................. + .. currentmodule:: passlib.ifc - * [major] The :class:`!PasswordHash` method :meth:`!encrypt` - has been renamed to :meth:`~passlib.ifc.PasswordHash.hash`, + As part of this cleanup, the :class:`~passlib.ifc.PasswordHash` API (used by all hashes in passlib), + has had a number of changes: + + * **[major]** The :meth:`!PasswordHash.encrypt` method + has been renamed to :meth:`PasswordHash.hash`, to clarify that it's performing one-way hashing rather than reversiable encryption. A compatibility alias will remain in place until Passlib 2.0. This should fix the longstanding :issue:`21`. - * [major] Settings explicit configuration options like ``rounds`` and ``salt_size`` - should no longer be passed to :meth:`~passlib.ifc.PasswordHash.hash` (née :meth:`encrypt`). Instead, callers - should use the new :meth:`~passlib.ifc.PasswordHash.using` + * **[major]** Passing explicit configuration options to the :meth:`!PasswordHash.encrypt` method + (now called :meth:`PasswordHash.hash`) is deprecated. + To provide settings such as ``rounds`` and ``salt_size``, callers + should use the new :meth:`PasswordHash.using` method, which generates a new hasher with a customized configuration. - For example, ``sha256_crypt.encrypt("secret", rounds=12345)`` should now be - ``sha256_crypt.using(rounds=12345).hash("secret")``. Support for the old syntax - will be removed in Passlib 2.0. + >>> # for example, instead of this: + >>> sha256_crypt.encrypt("secret", rounds=12345) + + >>> # callers should now use: + >>> sha256_crypt.using(rounds=12345).hash("secret") + + Support for the old syntax will be removed in Passlib 2.0. - * [minor] The little-used :class:`!PasswordHash` methods :meth:`~passlib.ifc.PasswordHash.genhash` and - :meth:`~passlib.ifc.PasswordHash.genconfig` have been deprecated. + .. note:: + + This doesn't apply to contextual options such as :class:`~passlib.hash.cisco_pix`'s + ``user`` keyword, which should still be passed into the :meth:`!hash` method. + + * **[minor]** The little-used :meth:`PasswordHash.genhash` and + :meth:`PasswordHash.genconfig` methods have been deprecated. Compatibility aliases will remain in place until Passlib 2.0, at which point they will be removed entirely. -Crypt Context API -................. -Applications which use passlib's :class:`~passlib.context.CryptContext` should not be -greatly affected by this release; only one major deprecation was made: +Crypt Context API Deprecations +.............................. + .. currentmodule:: passlib.context - * [major] The :meth:`!encrypt` method was renamed to :meth:`!hash` to match the - :class:`~passlib.ifc.PasswordHash` API changes listed above. - The old method will remain around until Passlib 2.0. + Applications which use passlib's :class:`~passlib.context.CryptContext` should not be + greatly affected by this release; only one major deprecation was made: -A fewer internal options and infrequently used features have been deprecated: + * **[major]** To match the :class:`!PasswordHash` API changes above, + the :meth:`!CryptContext.encrypt` method was renamed to :meth:`CryptContext.hash`. + A compatibility alias will remain until Passlib 2.0. - * [minor] :meth:`~passlib.context.CryptContext.hash`, :meth:`~passlib.context.CryptContext.verify`, - :meth:`~passlib.context.CryptContext.verify_and_update`, and - :meth:`~passlib.context.CryptContext.needs_update`: + A fewer internal options and infrequently used features have been deprecated: + + * **[minor]** :meth:`CryptContext.hash`, :meth:`~CryptContext.verify`, + :meth:`~CryptContext.verify_and_update`, and + :meth:`~CryptContext.needs_update`: The ``scheme`` keyword is now deprecated; support will be removed in Passlib 2.0. - * [minor] :meth:`~passlib.context.CryptContext.hash`: Passing - settings to the .hash() method such as "rounds" and "salt" is deprecated. - Callers should use ``context.handler().using(**settings).hash()`` instead. + * **[minor]** :meth:`CryptContext.hash`: Passing + settings keywords to :meth:`!hash` such as ``rounds`` and ``salt`` is deprecated. + Code should now get ahold of the default hasher, and invoke it explicitly:: + + >>> # for example, calls that did this: + >>> context.hash(secret, rounds=1234) - * [minor] The ``vary_rounds`` option has been deprecated, + >>> # should use this instead: + >>> context.handler().using(rounds=1234).hash(secret) + + * **[minor]** The ``vary_rounds`` option has been deprecated, and will be removed in Passlib 2.0. It provided very little security benefit, and was judged not worth the additional code complexity it requires. - * [minor] The special wildcard ``all`` scheme name + * **[minor]** The special wildcard ``all`` scheme name has been deprecated, and will be removed in Passlib 2.0. The only legitimate use was to support ``vary_rounds``, which itself will be removed in 2.0. Other Deprecations .................. -A few other assorted deprecations have been made: + A few other assorted deprecations have been made: * The :func:`~passlib.utils.generate_secret` function has been deprecated in favor of the new :mod:`passlib.pwd` module, and the old function will be removed @@ -236,52 +284,61 @@ A few other assorted deprecations have been made: * Some deprecations and internal changes have been made to the :mod:`passlib.utils.handlers` module, which provides the common framework Passlib uses to implement hashers. - .. warning:: + .. warning:: - Developers who are using :mod:`!passlib.utils.handlers` directly are strongly encouraged - to contact the Passlib message board. It is likely breaking changes will occur in the - Passlib 1.8 / 1.9 releases. + Developers who are importing from the :mod:`!passlib.utils.handlers` module directly are strongly encouraged + to contact the Passlib message board. Backwards-incompatible relocations will occur in the + Passlib 1.8 / 1.9 releases. Backwards Incompatibilities --------------------------- Changes in existing behavior: - * [moderate] New hashes generated by :class:`~passlib.apache.HtpasswdFile` now use the strongest + * **[moderate]** :mod:`passlib.apache`: New hashes generated by :class:`~passlib.apache.HtpasswdFile` now use the strongest algorithm available on the host, rather than one that is guaranteed to be portable. - Applications can explicitly set ``default_scheme="portable"`` to restore the old behavior. + Applications can explicitly set ``HtPasswdFile(default_scheme="portable")`` to restore the old behavior. - * [minor] M2Crypto no longer used to accelerate pbkdf2-hmac-sha1; applications relying on this + * **[minor]** M2Crypto no longer used to accelerate pbkdf2-hmac-sha1; applications relying on this to speed up :class:`~passlib.hash.pbkdf2_sha1` should install `fastpbkdf2 <https://pypi.python.org/pypi/fastpbkdf2>`_. Scheduled removal of features: - * [minor] The :ref:`min_verify_time <context-min-verify-time-option>` keyword + * **[minor]** :mod:`passlib.context`: The :ref:`min_verify_time <context-min-verify-time-option>` keyword that was deprecated in release 1.6, is now completely ignored. Support will be removed entirely in release 1.8. See the new :ref:`harden_verify <context-harden-verify-option>` keyword that replaces it. - * [trivial] The internal :meth:`!PasswordHash.parse_rounds` method, deprecated in 1.6, has been removed. + * **[trivial]** :mod:`passlib.hash`: The internal :meth:`!PasswordHash.parse_rounds` method, deprecated in 1.6, has been removed. Minor incompatibilities: - * [minor] The little-used method :meth:`~passlib.ifc.PasswordHash.genconfig` + * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genconfig` will now always return a valid hash, rather than a truncated configuration string or ``None``. - * [minor] The little-used method :meth:`~passlib.ifc.PasswordHash.genhash` no longer accepts + * **[minor]** :mod:`passlib.hash`: The little-used method :meth:`~passlib.ifc.PasswordHash.genhash` no longer accepts ``None`` as a config argument. - * [trivial] :func:`passlib.utils.pbkdf2.pbkdf2` no longer supports custom PRF callables. + * **[trivial]** :func:`passlib.utils.pbkdf2.pbkdf2` no longer supports custom PRF callables. this was an unused feature, and prevented some useful optimizations. +----- + +.. centered:: + **END OF 1.7 RELEASE NOTES** + +----- + **1.6.5** (2015-08-04) ====================== Fixed some minor bugs in the test suite which were causing erroneous test failures (:issue:`57` and :issue:`58`). The passlib library itself is unchanged. - + +.. rst-class:: toc-always-toggle + **1.6.4** (2015-07-25) ====================== @@ -330,9 +387,10 @@ Other Changes * Passlib releases are now published as wheels instead of eggs. -.. note:: +**1.6.3** (2015-07-25) +====================== - Release **1.6.3** was skipped due to upload issues. + This was relabeled as **1.6.4** due to PyPI upload issues. **1.6.2** (2013-12-26) ====================== @@ -10,7 +10,7 @@ Passlib is (c) `Assurance Technologies <http://www.assurancetechnologies.com>`_, and is released under the `BSD license <http://www.opensource.org/licenses/bsd-license.php>`_:: Passlib - Copyright (c) 2008-2015 Assurance Technologies, LLC. + Copyright (c) 2008-2016 Assurance Technologies, LLC. All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/docs/conf.py b/docs/conf.py index 7c703e0..4761304 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,9 +66,6 @@ extensions = [ # allow table column alignment styling 'cloud_sptheme.ext.table_styling', - # modify logo per page - 'cloud_sptheme.ext.perpage', - # monkeypatch sphinx to support a few extra things we can't do with extensions. 'cloud_sptheme.ext.autodoc_sections', 'cloud_sptheme.ext.autoattribute_search_bases', @@ -94,7 +91,8 @@ index_doc = 'index' # General information about the project. project = 'Passlib' author = "Assurance Technologies, LLC" -copyright = "2008-%d, %s" % (datetime.date.today().year, author) +updated = datetime.date.today().isoformat() +copyright = "2008-%d, %s. Last Updated %s" % (datetime.date.today().year, author, updated) # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -147,6 +145,9 @@ pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. modindex_common_prefix = ["passlib."] +# appended to all pages +rst_epilog = "\n.. |updated| replace:: %s\n" % updated + #============================================================================= # Options for all output #============================================================================= @@ -172,14 +173,16 @@ if csp.is_cloud_theme(html_theme): # lighter_decor=True, borderless_decor=True, sidebarbgcolor='transparent', + small_sidebar_bg_color='#EBEBEB', bodytrimcolor='transparent', max_width="12.5in", sidebarwidth="3in", large_sidebar_width="3.5in", hyphenation_language="en", headfont='"Bitstream Vera Sans", sans-serif', - bodyfont='arial, helvetica, sans-serif', + # bodyfont='arial, helvetica, sans-serif', relbarbgcolor='#821f4d', + footerbgcolor='#521330', sectionbgcolor='#964361', rubricbgcolor='#B4748B', sidebarlinkcolor='#6A3051', @@ -207,9 +210,6 @@ html_short_title = "%s %s Documentation" % (project, version) # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = os.path.join("_static", "masthead.png") -perpage_html_logo = { - 'index': None, -} # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -230,14 +230,7 @@ html_static_path = ['_static'] html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -# common_sidebars = ['quicklinks.html', 'searchbox.html'] -# html_sidebars = { -# '**': ['localtoc.html', 'relations.html'] + common_sidebars, -# 'py-modindex': common_sidebars, -# 'genindex': common_sidebars, -# 'search': common_sidebars, -# } -html_sidebars = {'**': ['globaltoc.html', 'searchbox.html']} +html_sidebars = {'**': ['searchbox.html', 'globaltoc.html']} # Additional templates that should be rendered to pages, maps page names to # template names. diff --git a/docs/contents.rst b/docs/contents.rst index 309d7cb..0be84f5 100644 --- a/docs/contents.rst +++ b/docs/contents.rst @@ -5,33 +5,10 @@ Table Of Contents .. toctree:: :maxdepth: 4 - Front Page <index> - install - - overview - new_app_quickstart - - lib/passlib.hash - - lib/passlib.context-tutorial - lib/passlib.context - lib/passlib.apps - lib/passlib.hosts - - lib/passlib.apache - lib/passlib.ext.django - lib/passlib.pwd - lib/passlib.totp - - lib/passlib.exc - lib/passlib.registry - lib/passlib.utils - lib/passlib.crypto - - modular_crypt_format - - history - copyright + Introduction <index> + narrative + reference + other * :ref:`General Index <genindex>` * :ref:`Module List <modindex>` diff --git a/docs/index.rst b/docs/index.rst index f22231f..7f9aace 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,10 @@ .. image:: _static/masthead.png :align: center + :class: show-for-small + +.. rst-class:: float-right without-title + +.. seealso:: :ref:`What's new in Passlib 1.7 <whats-new>` ========================================== Passlib |release| documentation @@ -38,88 +43,29 @@ using the :doc:`PBKDF2-SHA256 </lib/passlib.hash.pbkdf2_digest>` algorithm:: >>> pbkdf2_sha256.verify("joshua", hash) False -Content Summary -=============== - -.. rst-class:: float-right inline-title - -.. seealso:: :ref:`What's new in Passlib 1.7 <whats-new>` - -Introductory Materials ----------------------- - - :doc:`install` - requirements & installation instructions - - :doc:`overview` - describes how Passlib is laid out +.. rst-class:: toc-always-open - :doc:`New Application Quickstart <new_app_quickstart>` - choosing a password hash for new applications - ----- - -Password Hashing Algorithms ---------------------------- - :mod:`passlib.hash` - all the password hashes supported by Passlib -- - - :doc:`Overview <lib/passlib.hash>` - - :ref:`mcf-hashes` - - :ref:`ldap-hashes` - - :ref:`database-hashes` - - :ref:`windows-hashes` - - :ref:`other-hashes` - - :doc:`PasswordHash interface <password_hash_api>` - examples & documentation of the common hash interface - used by all the hash algorithms in Passlib. - -CryptContext Objects --------------------- - :mod:`passlib.context` - provides the :class:`!CryptContext` class, a flexible container - for managing and migrating between multiple hash algorithms. - - :mod:`passlib.apps` - predefined CryptContext objects for managing the hashes used by - MySQL, PostgreSQL, OpenLDAP, and others applications. - - :mod:`passlib.hosts` - predefined CryptContext objects for managing the hashes - found in Linux & BSD "shadow" files. - -Application Helpers -------------------- - :mod:`passlib.apache` - classes for manipulating Apache's ``htpasswd`` and ``htdigest`` files. - - :mod:`passlib.ext.django` - Django plugin which monkeypatches support for (almost) any hash in Passlib. +Getting Started +=============== - :mod:`passlib.pwd` - Password generation helpers. +This documentation is organized into two main parts: +a narrative walkthrough of Passlib, and a top-down API reference. - :mod:`passlib.totp` - TOTP / Two Factor Authentication +:doc:`narrative` -.. - Support Modules - --------------- - :mod:`passlib.exc` + New users in particular will want to visit the walkthrough, as it provides + introductory documentation including installation requirements, + an overview of what passlib provides, and a guide for getting started quickly. - custom warnings and exceptions used by Passlib - :mod:`passlib.registry` - :mod:`passlib.utils` +:doc:`reference` ----- + The API reference contains a top-down reference of the :mod:`!passlib` package. -Other Documents ---------------- - :doc:`modular_crypt_format` - reference listing "modular crypt format" support across Unix systems. +:doc:`other` - :doc:`Changelog <history>` - Passlib's release history + This section contains additional things that don't + fit anywhere else, including an :doc:`FAQ <faq>` and a complete + :doc:`changelog <history>`. Online Resources ================ @@ -128,12 +74,9 @@ Online Resources :class: fullwidth :column-alignment: lr - ================ =================================================== - Homepage: `<https://bitbucket.org/ecollins/passlib>`_ - Online Docs: `<http://packages.python.org/passlib>`_ - Discussion: `<http://groups.google.com/group/passlib-users>`_ - ---------------- --------------------------------------------------- - ---------------- --------------------------------------------------- - Downloads: `<https://pypi.python.org/pypi/passlib>`_ - Source: `<https://bitbucket.org/ecollins/passlib/src>`_ - ================ =================================================== + =================== =================================================== + Latest Docs: `<http://packages.python.org/passlib>`_ + Project Home: `<https://bitbucket.org/ecollins/passlib>`_ + News & Discussion: `<http://groups.google.com/group/passlib-users>`_ + Downloads @ PyPI: `<https://pypi.python.org/pypi/passlib>`_ + =================== =================================================== diff --git a/docs/lib/passlib.context-tutorial.rst b/docs/lib/passlib.context-tutorial.rst index 19bdb2b..9d0cdc3 100644 --- a/docs/lib/passlib.context-tutorial.rst +++ b/docs/lib/passlib.context-tutorial.rst @@ -3,12 +3,11 @@ .. _context-overview: .. _context-tutorial: -========================================================= -:mod:`passlib.context` - CryptContext Overview & Tutorial -========================================================= +.. currentmodule:: passlib.context -.. module:: passlib.context - :synopsis: CryptContext class, for managing multiple password hash schemes +============================================== +:mod:`passlib.context` - CryptContext Tutorial +============================================== Overview ======== @@ -26,7 +25,7 @@ password hashes at once: The following sections contain a walkthrough of this class, starting with some simple examples, and working up to a complex "full-integration" example. -.. seealso:: The :ref:`CryptContext Reference <context-reference>` document, +.. seealso:: The :mod:`passlib.context` api reference, which lists all the options and methods supported by this class. .. index:: CryptContext; usage examples diff --git a/docs/lib/passlib.context.rst b/docs/lib/passlib.context.rst index 72524e8..ecb954d 100644 --- a/docs/lib/passlib.context.rst +++ b/docs/lib/passlib.context.rst @@ -1,11 +1,12 @@ .. index:: CryptContext; reference -.. currentmodule:: passlib.context +.. module:: passlib.context + :synopsis: CryptContext class, for managing multiple password hash schemes .. _context-reference: ====================================================== -:mod:`passlib.context` - CryptContext Reference +:mod:`passlib.context` - CryptContext ====================================================== This page provides a complete reference of all the methods and options supported by the :class:`!CryptContext` class @@ -16,7 +17,7 @@ and helper utilities. * :ref:`CryptContext Overview & Tutorial <context-overview>` -- overview of this class and walkthrough of how to use it. -.. rst-class:: emphasize-children +.. rst-class:: emphasize-children toc-always-open The CryptContext Class ====================== @@ -45,7 +46,7 @@ The CryptContext Class .. index:: CryptContext; keyword options -.. rst-class:: html-toggle expanded +.. rst-class:: html-toggle expanded toc-always-open Constructor Keywords -------------------- diff --git a/docs/lib/passlib.exc.rst b/docs/lib/passlib.exc.rst index f90f330..4b36a2b 100644 --- a/docs/lib/passlib.exc.rst +++ b/docs/lib/passlib.exc.rst @@ -1,6 +1,6 @@ -=============================================================== -:mod:`passlib.exc` - exceptions and warnings raised by Passlib -=============================================================== +============================================ +:mod:`passlib.exc` - Exceptions and warnings +============================================ .. module:: passlib.exc :synopsis: exceptions & warnings raised by Passlib diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst index e5a7a56..946c5ff 100644 --- a/docs/lib/passlib.hash.bcrypt.rst +++ b/docs/lib/passlib.hash.bcrypt.rst @@ -82,11 +82,14 @@ you need to upgrade the external package being used as the backend Format & Algorithm ================== -Bcrypt is compatible with the :ref:`modular-crypt-format`, and uses ``$2$`` and ``$2a$`` as the identifying prefix -for all its strings (``$2$`` is seen only for legacy hashes which used an older version of Bcrypt). +Bcrypt is compatible with the :ref:`modular-crypt-format`, and uses a number of identifying +prefixes: ``$2$``, ``$2a$``, ``$2x$``, ``$2y$``, and ``$2b$``. Each prefix indicates +a different revision of the BCrypt algorithm; and all but the ``$2b$`` identifier are +considered deprecated. + An example hash (of ``password``) is: - ``$2a$12$GhvMmNVjRW29ulnudl.LbuAnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m`` + ``$2b$12$GhvMmNVjRW29ulnudl.LbuAnUtN/LRfe1JsBm1Xu6LE3059z5Tr8m`` Bcrypt hashes have the format :samp:`$2a${rounds}${salt}{checksum}`, where: diff --git a/docs/lib/passlib.hash.rst b/docs/lib/passlib.hash.rst index e17b710..03a28b1 100644 --- a/docs/lib/passlib.hash.rst +++ b/docs/lib/passlib.hash.rst @@ -8,20 +8,30 @@ Overview ======== The :mod:`!passlib.hash` module contains all the password hash algorithms built into Passlib. -While each hash has its own options and output format, they all share a common interface, -documented in detail in the :ref:`password-hash-api`. The following pages -describe the common interface, and then describe each hash in detail -(including its format, underlying algorithm, and known security issues). +While each hash has its own options and output format, +they all inherit from the :mod:`passlib.ifc`.\ :class:`!PasswordHash` API. +The following pages describe each hash in detail, +including its format, underlying algorithm, and known security issues. -.. seealso:: :doc:`Quickstart Guide </new_app_quickstart>` -- advice on - choosing an appropriately secure hash for your new application. +.. warning:: + + **Many of the hash algorithms listed below are *NOT* secure.** + + Passlib supports a wide array of hash algorithms, primarily to + support dealing with legacy data and systems. + + If you're looking to choose a hash algorithm for a new application, + see the :doc:`Quickstart Guide </new_app_quickstart>` instead of picking + one from this list. + +.. rst-class:: html-toggle Usage -===== -All of the hashes in this module can used in two ways: +----- +All of the hashes in this module can be used in two ways: -1. They can be imported and used directly, as in the following example - with the :class:`md5_crypt` hash:: +1. They can be imported from :mod:`!passlib.hash` and used directly, + as in the following example with the :class:`md5_crypt` hash:: >>> # import the desired hash >>> from passlib.hash import md5_crypt @@ -61,87 +71,124 @@ All of the hashes in this module can used in two ways: >>> pwd_context.verify("letmein", hash2) True -For additional details, usage examples, and full documentation of all -methods and attributes provided by the common hash interface: - -.. toctree:: - :maxdepth: 2 +.. seealso:: - /password_hash_api + For additional details and usage examples, see the + :doc:`PasswordHash </password_hash_api>` and :doc:`CryptContext </lib/passlib.context>` + reference. .. _mcf-hashes: -Unix & "Modular Crypt" Hashes -============================= -Aside from the "archaic" schemes below, most modern Unix flavors -use password hashes which follow the :ref:`modular crypt format <modular-crypt-format>`, +Unix Hashes +=========== +Aside from "archaic" schemes such as :class:`!des_crypt`, +most of the password hashes supported by modern Unix flavors +adhere to the :ref:`modular crypt format <modular-crypt-format>`, allowing them to be easily distinguished when used within the same file. -The basic format :samp:`${scheme}${hash}` has also been adopted for use +The basic of format :samp:`${scheme}${hash}` has also been adopted for use by other applications and password hash schemes. -.. _archaic-unix-schemes: +.. _standard-unix-hashes: -Archaic Unix Schemes --------------------- -All of the following hashes are/were used by various Unix flavors -to store user passwords; most are based on the DES block cipher, -and predate the arrival of the modular crypt format. -They should all be considered insecure at best, but may be useful when reading -legacy password entries: +.. rst-class:: toc-always-open + +Active Unix Hashes +------------------ +All these schemes are actively in use by various Unix flavors to store user passwords. +They all follow the modular crypt format. .. toctree:: :maxdepth: 1 - passlib.hash.des_crypt - passlib.hash.bsdi_crypt - passlib.hash.bigcrypt - passlib.hash.crypt16 + passlib.hash.bcrypt + passlib.hash.sha256_crypt + passlib.hash.sha512_crypt -.. _standard-unix-hashes: +Special note should be made of the following fallback helper, +which is not an actual hash scheme, but implements the "disabled account marker" +found in many Linux & BSD password files: -Standard Unix Schemes ---------------------- -All these schemes are currently used by various Unix flavors to store user passwords. -They all follow the modular crypt format. +.. toctree:: + :maxdepth: 1 + + passlib.hash.unix_disabled + +.. rst-class:: toc-always-open + +Deprecated Unix Hashes +---------------------- +The following schemes are supported by various Unix systems +use the modular crypt format, and are noticably stronger than the previous group. +However, they have all since been deprecated in favor of stronger algorithms: + +* :class:`passlib.hash.bsd_nthash` - FreeBSD's MCF-compatible encoding of :doc:`nthash <passlib.hash.nthash>` digests .. toctree:: :maxdepth: 1 passlib.hash.md5_crypt - passlib.hash.bcrypt passlib.hash.sha1_crypt passlib.hash.sun_md5_crypt - passlib.hash.sha256_crypt - passlib.hash.sha512_crypt -Other Modular Crypt Schemes ---------------------------- -While most of these schemes are not (commonly) used by any Unix flavor to store user passwords, -they can be used compatibly along side other modular crypt format hashes. +.. _archaic-unix-schemes: + +.. rst-class:: toc-always-open + +Archaic Unix Hashes +------------------- +The following schemes are supported by certain Unix systems, +but are considered particularly archaic: Not only do they predate +the modular crypt format, but they're based on the outmoded DES block cipher, +and are woefully insecure: .. toctree:: :maxdepth: 1 - passlib.hash.apr_md5_crypt + passlib.hash.des_crypt + passlib.hash.bsdi_crypt + passlib.hash.bigcrypt + passlib.hash.crypt16 + +Other "Modular Crypt" Hashes +============================ +The :ref:`modular crypt format <modular-crypt-format>` is a loose standard +for password hash strings which started life under the Unix operating system, +and is used by many of the Unix hashes (above). However, it's +it's basic :samp:`${scheme}${hash}` format has also been adopted by a number +of application-specific hash algorithms: + +.. rst-class:: toc-always-open + +Active Hashes +------------- +While most of these schemes generally require an application-specific +implementation, natively used by any Unix flavor to store user passwords, +they can be used compatibly along side other modular crypt format hashes: + +.. toctree:: + :maxdepth: 1 + + passlib.hash.argon2 passlib.hash.bcrypt_sha256 passlib.hash.phpass passlib.hash.pbkdf2_digest - passlib.hash.cta_pbkdf2_sha1 - passlib.hash.dlitz_pbkdf2_sha1 passlib.hash.scram passlib.hash.scrypt - passlib.hash.argon2 -* :class:`passlib.hash.bsd_nthash` - FreeBSD's MCF-compatible :doc:`nthash <passlib.hash.nthash>` encoding +.. rst-class:: toc-always-open -Special note should be made of the fallback helper, -which is not an actual hash scheme, but provides "disabled account" -behavior found in many Linux & BSD password files: +Deprecated Hashes +----------------- +The following are some additional application-specific hashes which are still +occasionally seen, use the modular crypt format, but are rarely used or weak +enough that they have been deprecated: .. toctree:: :maxdepth: 1 - passlib.hash.unix_disabled + passlib.hash.apr_md5_crypt + passlib.hash.cta_pbkdf2_sha1 + passlib.hash.dlitz_pbkdf2_sha1 .. _ldap-hashes: @@ -152,9 +199,6 @@ All of the following hashes use a variant of the password hash format used by LDAPv2. Originally specified in :rfc:`2307` and used by OpenLDAP [#openldap]_, the basic format ``{SCHEME}HASH`` has seen widespread adoption in a number of programs. -.. [#openldap] OpenLDAP homepage - `<http://www.openldap.org/>`_. - - .. _standard-ldap-hashes: Standard LDAP Schemes @@ -237,13 +281,11 @@ no identifying markers, identifying them is pretty much context-dependant. passlib.hash.msdcc passlib.hash.msdcc2 -.. _other-hashes: +.. rst-class:: toc-always-toggle -Other Hashes +Cisco Hashes ============ -The following schemes are used in various contexts, -but have formats or uses which cannot be easily placed -in one of the above categories: +The following hashes are used in various places on Cisco IOS and ASA devices: .. toctree:: :maxdepth: 1 @@ -251,13 +293,31 @@ in one of the above categories: passlib.hash.cisco_pix passlib.hash.cisco_asa -* *Cisco "Type 5" hashes* - see :doc:`md5_crypt <passlib.hash.md5_crypt>` +* **Cisco "Type 5" hashes** - these are the same as :doc:`md5_crypt <passlib.hash.md5_crypt>` .. toctree:: :maxdepth: 1 passlib.hash.cisco_type7 + +.. _other-hashes: + +Other Hashes +============ +The following schemes are used in various contexts, +but have formats or uses which cannot be easily placed +in one of the above categories: + +.. toctree:: + :maxdepth: 1 + passlib.hash.django_std passlib.hash.grub_pbkdf2_sha512 passlib.hash.hex_digests passlib.hash.plaintext + +.. rubric:: Footnotes + +.. [#openldap] OpenLDAP homepage - `<http://www.openldap.org/>`_. + + diff --git a/docs/lib/passlib.pwd.rst b/docs/lib/passlib.pwd.rst index 0b4b556..505230c 100644 --- a/docs/lib/passlib.pwd.rst +++ b/docs/lib/passlib.pwd.rst @@ -2,7 +2,7 @@ :synopsis: password generation helpers ================================================= -:mod:`passlib.pwd` -- password generation helpers +:mod:`passlib.pwd` -- Password generation helpers ================================================= .. versionadded:: 1.7 diff --git a/docs/lib/passlib.totp-tutorial.rst b/docs/lib/passlib.totp-tutorial.rst new file mode 100644 index 0000000..0982825 --- /dev/null +++ b/docs/lib/passlib.totp-tutorial.rst @@ -0,0 +1,36 @@ +.. index:: TOTP; overview +.. _totp-tutorial: + +.. currentmodule:: passlib.totp + +=================================== +:mod:`passlib.totp` - TOTP Tutorial +=================================== + +Overview +======== +The :mod:`passlib.totp` module provides a set of classes for adding +two-factor authentication (2FA) support into your application, +using the widely supported TOTP / HOTP specifications. + +This module provides a number of classes, designed to support a variety +of use cases, including: + + * Low-level methods for calculating tokens on the client side. + + * Low-level methods for generating OTP keys & verifying tokens on the server side. + + * High level methods for server-side storage of OTP keys *along with + state and history*, making it easy to add TOTP integration. + +.. seealso:: The :mod:`passlib.totp` api reference, + which lists all details of all the classes and methods mentioned here. + +.. index:: TOTP; usage examples + +.. rst-class:: emphasize-children + +Tutorial / Walkthrough +====================== + +.. todo:: this content needs writing
\ No newline at end of file diff --git a/docs/lib/passlib.totp.rst b/docs/lib/passlib.totp.rst index fdb5fe4..961bf46 100644 --- a/docs/lib/passlib.totp.rst +++ b/docs/lib/passlib.totp.rst @@ -5,14 +5,14 @@ :mod:`passlib.totp` -- TOTP / Two Factor Authentication ======================================================= -.. versionadded:: 1.7 - .. todo:: This module is still a work in progress, it's API may change before release. Things left: + * convert TOTP 'offset' to 'skew' (inverting sense) + * TOTO & helper should track *next* counter, to match HTOP (as well as default reuse=False behavior) * finish unittests (there are a few cases left) * write narrative documentation * get api documentation formatted better (whether by getting nested sections integrated into TOC, @@ -24,34 +24,35 @@ * more verification against other TOTP servers & clients. * consider native pyqrcode integration (e.g. a ``to_qrcode()`` method) -.. rst-class:: emphasize-children +.. versionadded:: 1.7 + +The :mod:`!passlib.totp` module provides a number of classes for implementing +two-factor authentication (2FA) using the TOTP / HOTP specifications. +This page provides a reference to all the classes and methods in this module. -API Reference -============= +.. seealso:: + + * :ref:`TOTP Tutorial <totp-overview>` -- + overview of this module and walkthrough of how to use it. + +.. rst-class:: emphasize-children OTPContext ----------- +========== .. autoclass:: OTPContext .. autofunction:: generate_secret Common Interface ----------------- +================ .. autoclass:: BaseOTP() TOTP (Timed-based tokens) -------------------------- +========================= .. autoclass:: TOTP(key=None, format="base32", \*, new=False, \*\*kwds) -Helper Classes -.............. - -.. autoclass:: TotpToken() - -.. autoclass:: TotpMatch() - HOTP (Counter-based tokens) ---------------------------- +=========================== .. note:: HOTP is used much less frequently, since it's fragile @@ -60,9 +61,10 @@ HOTP (Counter-based tokens) .. autoclass:: HOTP(key=None, format="base32", \*, new=False, \*\*kwds) -Helper Classes -.............. - +Support Classes +=============== +.. autoclass:: TotpToken() +.. autoclass:: TotpMatch() .. autoclass:: HotpMatch() Deviations diff --git a/docs/modular_crypt_format.rst b/docs/modular_crypt_format.rst index 86988a6..43dc846 100644 --- a/docs/modular_crypt_format.rst +++ b/docs/modular_crypt_format.rst @@ -8,7 +8,14 @@ Modular Crypt Format ==================== -.. centered:: *or*, a side note about a standard that isn't +.. rst-class:: subtitle + + A explanation about a standard that isn't + +Overview +======== +A number of the hashes in Passlib are described as adhering to the "Modular Crypt Format". +This page is an attempt to document what that means. In short, the modular crypt format (MCF) is a standard for encoding password hash strings, which requires hashes @@ -18,9 +25,12 @@ identifying a particular scheme, and :samp:`{content}` is the contents of the scheme, using only the characters in the regexp range ``[a-zA-Z0-9./]``. -However, there appears to be no central registry of identifiers, -no specification document, and no actual rules; -so the modular crypt format is more of an ad-hoc idea rather than a true standard. +However, there's no official specification document describing this format. +Nor is there a central registry of identifiers, or actual rules. +The modular crypt format is more of an ad-hoc idea rather than a true standard. + +The rest of this page is an attempt to describe what is known, +at least as far as the hashes supported by Passlib. History ======= @@ -73,11 +83,10 @@ by the modular crypt format hashes found in Passlib: they may use the ``$`` character as an internal field separator. This is the least adhered-to of any modular crypt format convention. - Other characters (such as ``+=,-``) are sometimes - used by various formats, though sparingly. + Other characters (such as ``+=,-``) are used by various formats. The only hard and fast stricture - is that ``:;!*`` and all non-printable characters be avoided, + is that ``:;!*`` and all non-printable or 8-bit characters be avoided, since this would interfere with parsing of the Unix shadow password file, where these hashes are typically stored. @@ -142,7 +151,8 @@ and indicates which operating systems offer native support: :class:`~passlib.hash.bsdi_crypt` ``_`` y y y :class:`~passlib.hash.md5_crypt` ``$1$`` y y y y y :class:`~passlib.hash.bcrypt` ``$2$``, ``$2a$``, - ``$2x$``, ``$2y$`` y y y y + ``$2x$``, ``$2y$`` + ``$2b$`` y y y y :class:`~passlib.hash.bsd_nthash` ``$3$`` y :class:`~passlib.hash.sha256_crypt` ``$5$`` y 8.3+ y :class:`~passlib.hash.sha512_crypt` ``$6$`` y 8.3+ y @@ -165,7 +175,7 @@ by the following operating systems and platforms: **Google App Engine** As of 2011-08-19, Google App Engine's :func:`!crypt` implementation appears to match that of a typical Linux - system. + system (as listed in the previous table). ===================== ============================================================== Application-Defined Hashes @@ -183,6 +193,8 @@ These hashes can be found in various libraries and applications Scheme Prefix Primary Use (if known) =========================================== =================== =========================== :class:`~passlib.hash.apr_md5_crypt` ``$apr1$`` Apache htdigest files + :class:`~passlib.hash.argon2` ``$argon2i$``, + ``$argon2d$`` :class:`~passlib.hash.bcrypt_sha256` ``$bcrypt-sha256$`` Passlib-specific :class:`~passlib.hash.phpass` ``$P$``, ``$H$`` PHPass-based applications :class:`~passlib.hash.pbkdf2_sha1` ``$pbkdf2$`` Passlib-specific diff --git a/docs/new_app_quickstart.rst b/docs/new_app_quickstart.rst index 2dccb30..51a7ae0 100644 --- a/docs/new_app_quickstart.rst +++ b/docs/new_app_quickstart.rst @@ -38,6 +38,7 @@ instance; see below for more... .. index:: Passlib; recommended hash algorithms .. _recommended-hashes: +.. rst-class:: toc-always-open Choosing a Hash ================ @@ -187,20 +188,20 @@ For new applications, this decision comes down to a couple of questions: 1. Does the hash need to be natively supported by your operating system's :func:`!crypt` api, in order to allow inter-operation with third-party applications on the host? - * If so, the right choice is either :class:`~passlib.hash.bcrypt` for BSD variants, + * If yes, the right choice is either :class:`~passlib.hash.bcrypt` for BSD variants, or :class:`~passlib.hash.sha512_crypt` for Linux; since these are natively supported. - * If not, continue... + * If no, continue... -2. Does your hosting prevent you from installing C extensions? +2. Does your hosting provider allow you to install C extensions? - * If yes, you probably want to use :class:`~passlib.hash.pbkdf2_sha256` / :class:`~passlib.hash.pbkdf2_sha512`; - This is currently the option with the fastest pure-python backend. + * If no, you probably want to use :class:`~passlib.hash.pbkdf2_sha256`, + as this currently has the fastest pure-python backend. * If they allow C extensions, continue... -3. Do you want to use the latest, greatest, and don't mind increased memory usage - per hash? +3. Do you want to use the latest & greatest, and don't mind increased memory usage + when hashing? * :class:`~passlib.hash.argon2` is a next-generation hashing algorithm, attempting to become the new standard. It's design has been being slightly tweaked @@ -208,12 +209,12 @@ For new applications, this decision comes down to a couple of questions: You'll need to install the `argon2_cffi <https://pypi.python.org/pypi/argon2_cffi>`_ support library. - * If you want something secure, but battle tested, continue... + * If you want something secure, but more battle tested, continue... -4. The top two choices left are :class:`~passlib.hash.bcrypt` and :class:`~passlib.hash.pbkdf2_sha256`. +4. The top choices left are :class:`~passlib.hash.bcrypt` and :class:`~passlib.hash.pbkdf2_sha256`. Both have advantages, and their respective rough edges; - though currently the balance is in favor of :class:`~passlib.hash.bcrypt` + though currently the balance is in favor of bcrypt (pbkdf2 can be cracked somewhat more efficiently). * If choosing bcrypt, we strongly recommend installing the `bcrypt <https://pypi.python.org/pypi/bcrypt>`_ diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst index bd8168b..a2daf45 100644 --- a/docs/password_hash_api.rst +++ b/docs/password_hash_api.rst @@ -8,7 +8,7 @@ .. _password-hash-api: ============================================= -Password Hash Interface +:mod:`passlib.ifc` -- Password Hash Interface ============================================= Overview |