{ "info": { "author": "Agiliq", "author_email": "hello@agiliq.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "Django Secure Login\n=======================\n\n[![Build Status](https://travis-ci.org/agiliq/django-secure-login.png?branch=master)](https://travis-ci.org/agiliq/django-secure-login)\n[![Coverage Status](https://coveralls.io/repos/agiliq/django-secure-login/badge.png)](https://coveralls.io/r/agiliq/django-secure-login)\n\nOverview\n------------\nDjango secure login provides utilities to add simple security steps around login and registration. It provides two mixins, `SecureLoginBackendMixin` and `SecureFormMixin` which check for common vulnerabilities while logging in.\n\n* `SecureLoginBackendMixin` can be used with any Backend which has a concept of username and password\n* `SecureFormMixin` can be used with any Form which has a concept of username and password. (eg login form, registration form etc)\n\nSettings\n-----------\n\n* `SECURE_LOGIN_CHECKERS`: A list of strings which can be evaluated to callables. The callable should return True if it wants the authentication to go through.\n* `SECURE_LOGIN_ON_FAIL`: A list of strings which can be evaluated to callables. Can take any action appropriate to a failed login.\n* `SECURE_LOGIN_MAX_HOURLY_ATTEMPTS`: Max failed attempts per hour before the user is locked out.\n\nFeatures\n---------\n\n* Works with any Backend and Form which has usename-y and password-y attributes.\n* Ensure that passwords have a minimum length (default 6)\n* Ensure that the password is not in the list of known weak passwords.\n* Ensure username is not same as password\n* Email user on a failed login attempt for them.\n* Lockout after 10 failed attempts within an hour.\n\nUsage\n-----------\n\n\nSimple\n===========\n\nSet\n\n AUTHENTICATION_BACKENDS = (\"secure_login.backends.SecureLoginBackend\", )\n\nWhich will run all the default checkers.\n\nAdvanced\n===========\n\n AUTHENTICATION_BACKENDS = (\"secure_login.backends.SecureLoginBackend\", )\n\nAnd\n\n SECURE_LOGIN_CHECKERS = [\n \"secure_login.checkers.no_weak_passwords\",\n \"secure_login.checkers.no_short_passwords\",\n ]\n\n`SECURE_LOGIN_CHECKERS` should be a list of callables. Each callable should only return true if it wants the authentication to go through.\n\nAnd\n\n SECURE_LOGIN_ON_FAIL = [\n \"secure_login.on_fail.email_user\",\n \"secure_login.on_fail.populate_failed_requests\",\n ]\n\n`SECURE_LOGIN_ON_FAIL` should be a list of callables. Each callable would be called in order if the authentication falls.\n\nWriting new secure backends.\n=================================\n\nIf you have an existing backend `FooBackend`, you can add SecureBackend like this.\n\n class SecureFooLoginBackend(SecureLoginBackendMixin, FooBackend):\n pass\n\nIf this backend has `email` as an username like identifier.\n\n class SecureFooLoginBackend(SecureLoginBackendMixin, FooBackend):\n\n def username_fieldname(self):\n return \"email\"\n\n\n\nSecure Form\n============\n\nUse the `SecureFormMixin` with your usual forms. If you have an existing for `FooForm`\n\n class SecureFooForm(SecureFormMixin, FooForm):\n pass\n\nIf this form uses email as username lke identifier\n\n class SecureFooForm(SecureFormMixin, FooForm):\n\n def username_fieldname(self):\n return \"email\"\n\n\n\n`SECURE_LOGIN_CHECKERS` will be tested in the the clean method.\n\n\n\nTODO\n---------\n\n* Rate limits login attempts per IP.\n* Rate limits login attempts per user.\n* Emails admins on X failed attempts.\n* Integrate with fail2ban.\n* Support 2F authentication", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/agiliq/django-secure-login", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "django-secure-login", "package_url": "https://pypi.org/project/django-secure-login/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-secure-login/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/agiliq/django-secure-login" }, "release_url": "https://pypi.org/project/django-secure-login/0.3.4/", "requires_dist": null, "requires_python": null, "summary": "Django app to harden the security around login", "version": "0.3.4" }, "last_serial": 1017241, "releases": { "0.3.1": [ { "comment_text": "", "digests": { "md5": "707bff332ba41f72aeca4a63eaf34f78", "sha256": "77b02df5214f79ef330c30b9d2e02742ab85e55973204bb1f529a0d2107c9480" }, "downloads": -1, "filename": "django-secure-login-0.3.1.tar.gz", "has_sig": false, "md5_digest": "707bff332ba41f72aeca4a63eaf34f78", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9245, "upload_time": "2014-02-25T10:44:07", "url": "https://files.pythonhosted.org/packages/39/aa/02520c63fa2027ca7ee2d3fa50e3c2242b9d882d7812042106ad703e0458/django-secure-login-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "1d878763d438fd43b1ced04fde851475", "sha256": "179198fa72e58947cefc5f6298ad94c81a4fa7fe71aedf422802feecd527fd16" }, "downloads": -1, "filename": "django-secure-login-0.3.2.tar.gz", "has_sig": false, "md5_digest": "1d878763d438fd43b1ced04fde851475", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9673, "upload_time": "2014-02-25T12:36:13", "url": "https://files.pythonhosted.org/packages/76/0e/7832eb0dc1325d08add0c109a95ed9b0a1e93dc6586374c7576c8f0dce9f/django-secure-login-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "1672e750f896d28147f2ddf972d1d64a", "sha256": "f6a26b66f7236870f70f85166e486706950ec860f4effac601b640e2ad41cc17" }, "downloads": -1, "filename": "django-secure-login-0.3.3.tar.gz", "has_sig": false, "md5_digest": "1672e750f896d28147f2ddf972d1d64a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9740, "upload_time": "2014-02-25T16:24:56", "url": "https://files.pythonhosted.org/packages/73/63/4df511181cc74a3435d24db5f98aa3564e4d210307a4882401f10e53aaf0/django-secure-login-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "d39a90f2b0355fb28c50a11d77087994", "sha256": "65f5e4e3da86f31615c0008f63d6213270c060cc92a3481bf6350d425f2b3844" }, "downloads": -1, "filename": "django-secure-login-0.3.4.tar.gz", "has_sig": false, "md5_digest": "d39a90f2b0355fb28c50a11d77087994", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6598, "upload_time": "2014-03-03T12:25:17", "url": "https://files.pythonhosted.org/packages/1c/51/965f89e7fbbf5b3cfa7623ded012d4bad3b41ebb6982e6026710b206f21b/django-secure-login-0.3.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d39a90f2b0355fb28c50a11d77087994", "sha256": "65f5e4e3da86f31615c0008f63d6213270c060cc92a3481bf6350d425f2b3844" }, "downloads": -1, "filename": "django-secure-login-0.3.4.tar.gz", "has_sig": false, "md5_digest": "d39a90f2b0355fb28c50a11d77087994", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6598, "upload_time": "2014-03-03T12:25:17", "url": "https://files.pythonhosted.org/packages/1c/51/965f89e7fbbf5b3cfa7623ded012d4bad3b41ebb6982e6026710b206f21b/django-secure-login-0.3.4.tar.gz" } ] }