{ "info": { "author": "Adam Knight", "author_email": "adam@movq.us", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Internet :: WWW/HTTP", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "drf-httpsig\n===========\n\nEasy `HTTP Signature`_ authentication support for the `Django REST framework`_.\n\n\nOverview\n--------\n\nThe HTTP Signature scheme provides a way to achieve origin authentication and message integrity for HTTP messages. Similar to Amazon's `HTTP Signature scheme`_, used by many of its services. The `HTTP Signature`_ specification is currently an IETF draft.\n\n\n.. contents::\n\nRequirements\n------------\n\n* Python 2.7, 3.3+ (currently tested up to 3.4)\n* `httpsig`_\n\n\nInstallation\n------------\n\nThis module uses `setuptools` and is hosted on PyPi so installation is as easy as::\n\n pip install drf-httpsig\n\nThis should also install the `httpsig`_ module which houses all the magic; this module is pure DRF glue (as it should be).\n\nYou can also run `setup.py` from inside a clone of the repository::\n\n python setup.py install\n\nNote that if you do so, modules with a version requirement may attempt to re-install the module as `versioneer` may report a different version, especially if your clone of the repo has any uncommitted/untagged changes.\n\n\nRunning the Tests\n-----------------\n\nTo run the tests for the module, use the following command on the repository root directory::\n\n python setup.py test\n\nNote that testing depends on `django-nose`, which will be installed before testing. You may also run the tests with `tox` using the included `tox.ini` file which has the benefit of keeping all testing dependances in a venv automatically.:\n\n tox -e py27,py32,...\n\n\nUsage\n-----\n\nTo actually authenticate HTTP requests with this module, you need to extend the ``SignatureAuthentication`` class, as follows:\n\n.. code:: python\n\n # my_api/auth.py\n\n from drf_httpsig.authentication import SignatureAuthentication\n\n class MyAPISignatureAuthentication(SignatureAuthentication):\n # The HTTP header used to pass the consumer key ID.\n\n # A method to fetch (User instance, user_secret_string) from the\n # consumer key ID, or None in case it is not found. Algorithm\n # will be what the client has sent, in the case that both RSA\n # and HMAC are supported at your site (and also for expansion).\n def fetch_user_data(self, key_id, algorithm=\"hmac-sha256\"):\n # ...\n # example implementation:\n try:\n user = User.objects.get(keyId=key_id, algo=algorithm)\n return (user, user.secret)\n except User.DoesNotExist:\n return (None, None)\n\n\n4. Configure DRF to use your authentication class; e.g.:\n\n.. code:: python\n\n # my_project/settings.py\n\n # ...\n REST_FRAMEWORK = {\n 'DEFAULT_AUTHENTICATION_CLASSES': (\n 'my_api.auth.MyAPISignatureAuthentication',\n ),\n 'DEFAULT_PERMISSION_CLASSES': (\n 'rest_framework.permissions.IsAuthenticated',\n )\n }\n # The above will force HTTP signature for all requests.\n # ...\n\n\nSupport\n-------\n\nPlease file any issues in the `issue tracker`_. You are also welcome to contribute features and fixes via pull requests.\n\n\nExample Usage and Session w/cURL\n--------------------------------\n\nAssuming the setup detailed above, a project running on ``localhost:8000`` could be probed with cURL as follows::\n\n # Pre-calculate this first bit.\n ~$ SSS=Base64(Hmac(SECRET, \"Date: Mon, 17 Feb 2014 06:11:05 GMT\", SHA256))\n ~$ curl -v -H 'Date: \"Mon, 17 Feb 2014 06:11:05 GMT\"' -H 'Authorization: Signature keyId=\"my-key\",algorithm=\"hmac-sha256\",headers=\"date\",signature=\"SSS\"'\n\nAnd, with much less pain, using the modules ``requests`` and ``httpsig``:\n\n.. code:: python\n\n import requests\n from httpsig.requests_auth import HTTPSignatureAuth\n\n KEY_ID = 'su-key'\n SECRET = 'my secret string'\n\n signature_headers = ['(request-target)', 'accept', 'date', 'host']\n headers = {\n 'Host': 'localhost:8000',\n 'Accept': 'application/json',\n 'Date': \"Mon, 17 Feb 2014 06:11:05 GMT\"\n }\n\n auth = HTTPSignatureAuth(key_id=KEY_ID, secret=SECRET,\n algorithm='hmac-sha256',\n headers=signature_headers)\n req = requests.get('http://localhost:8000/resource/',\n auth=auth, headers=headers)\n print(req.content)\n\n\n.. References:\n\n.. _`HTTP Signature`: https://datatracker.ietf.org/doc/draft-cavage-http-signatures/\n.. _`Django REST framework`: http://django-rest-framework.org/\n.. _`HTTP Signature scheme`: http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html\n.. _`httpsig`: https://github.com/ahknight/httpsig\n.. _`issue tracker`: https://github.com/ahknight/httpsig/issues\n\n\ndrf-httpsig Changes\n===================\n\nv1.2.0 (2018-Mar-28)\n--------------------\n\n* Updated to support and require httpsig 1.x.\n* Switched to pytest over nose\n\nv1.1.0 (2015-Feb-11)\n--------------------\n\n* Updated to support and require httpsig 1.1.\n* Updated requirements to simply Django<1.7 and DRF<3.0. Last version for those, I suspect.\n\nv1.0.2 (2014-Jul-24)\n--------------------\n\n* Updated authentication return value to set request.auth to the key_id used.\n\nv1.0.1 (2014-Jul-03)\n--------------------\n\n* Added/verified Python 3 support and tests (3.2+).\n* Added support for sending a DRF authorization challenge if we're the primary authenticator.\n* Switched to using the `httpsig` HeaderVerifier instead of doing it ourselves. Lots of code got deleted there.\n* Changed fetch_user_data to also receive the algorithm the keyID is for.\n* Updated README.\n* Removed models.py -- the client should handle that part entirely.\n\nv1.0b2/1.0.0 (2014-Jul-01)\n--------------------------\n\n* Added versioneer.\n* Updated requirements to use latest httpsig.\n* Added \"setup.py test\" and tox support.\n* Fixed a unit test.\n\nv1.0b1 (2014-Jun-27)\n--------------------\n\n* Renamed to drf-httpsig because I don't hate my hands.\n* Updated requirements versions to be more sane.\n* Switched to a different branch for http_signature.\n* Removed API_KEY_HEADER in favor of the keyId, per spec.\n* Cleaned up the repo a bit.\n* Cleaned up the code a bit.\n\n\ndjangorestframework-httpsignature (previous)\n============================================\n\nv0.1.5, 20140613 -- Document installation issue\n\n* Document workaround on installation problems.\n\nv0.1.4, 20140613 -- Improve installation\n\n* Make requirements file comply with docs.\n* Decide on http_signature commit.\n\nv0.1.3, 20140220 -- Upload to PyPI\n\n* Prepare docs to upload package to PyPI\n\nv0.1.2, 20140219 -- Package data and clean up\n\n* Updated package classifiers\n* Cleaned up unused code in authentication.py\n\nv0.1.1, 20140217 -- Documentation and clean up\n\n* The package can be installed.\n* Continuous integration via Travis.\n* Unit tests for the authentication code.\n* General docuementation in the README file.\n\nv0.1.0, 20140217 -- Initial release\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ahknight/drf-httpsig", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "drf-httpsig", "package_url": "https://pypi.org/project/drf-httpsig/", "platform": "", "project_url": "https://pypi.org/project/drf-httpsig/", "project_urls": { "Homepage": "https://github.com/ahknight/drf-httpsig" }, "release_url": "https://pypi.org/project/drf-httpsig/1.2.0/", "requires_dist": [ "djangorestframework (<3)", "django (<=1.7)", "httpsig (<2)" ], "requires_python": "", "summary": "HTTP Signature support for Django REST framework", "version": "1.2.0" }, "last_serial": 3715254, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "bc92857a1bc71de966ac4e1669a5fd24", "sha256": "1f6e2dd700d27e47f9a93bd997390c1b0efc294904728fc6aa727bc0574da4a3" }, "downloads": -1, "filename": "drf_httpsig-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "bc92857a1bc71de966ac4e1669a5fd24", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11142, "upload_time": "2014-07-01T21:07:55", "url": "https://files.pythonhosted.org/packages/76/b4/b38b10a8118b526fa85bd36da71988c3c9d8156feac1a33bef20d424571b/drf_httpsig-1.0.0-py2.py3-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "42f16a6af64c7d8dedcf10383a1e7f74", "sha256": "15f021a885203f45e50d0e28a8e3a01a1db1fbaf124b2e3a8be2bb4c892304e5" }, "downloads": -1, "filename": "drf_httpsig-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "42f16a6af64c7d8dedcf10383a1e7f74", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11973, "upload_time": "2014-07-03T18:39:41", "url": "https://files.pythonhosted.org/packages/70/78/afb54a0ad387d378b94f0e4afc9d877f9ec79c3cf003f6c1c8544880a29c/drf_httpsig-1.0.1-py2.py3-none-any.whl" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "9652c600fbaa5751f9aefa487f8914b6", "sha256": "0849e4227cfb629a4557ad34b562e8bc094cf1e42d4b84164587398aeb83c53b" }, "downloads": -1, "filename": "drf_httpsig-1.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9652c600fbaa5751f9aefa487f8914b6", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11671, "upload_time": "2014-07-24T17:09:43", "url": "https://files.pythonhosted.org/packages/79/2f/e8ac927ff9de2380d8fd1f5f9d64bcc110ef9689ddd48702860f8554c66e/drf_httpsig-1.0.2-py2.py3-none-any.whl" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "e334eabefa777e8a932ac988c91f0569", "sha256": "be3e6f74ac6959f70ecf3dd9e4630a23b4634e6b7588b099d8babc381cec9a1d" }, "downloads": -1, "filename": "drf_httpsig-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e334eabefa777e8a932ac988c91f0569", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11893, "upload_time": "2015-02-11T18:56:51", "url": "https://files.pythonhosted.org/packages/0d/92/dcb65bc17e07d348a593d55de60aa640b086e027d2a754d69ab6967e4614/drf_httpsig-1.1.0-py2.py3-none-any.whl" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "542fb008209af7361703c1421a432f2d", "sha256": "0f7aeaeacd3491e1a911f0927187f3495bced1d047285f5c65a8a6a8c0633f8b" }, "downloads": -1, "filename": "drf_httpsig-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "542fb008209af7361703c1421a432f2d", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 11943, "upload_time": "2015-02-11T19:56:06", "url": "https://files.pythonhosted.org/packages/ea/1c/e300dd196067d46b52100b63038b10db941264ffbc418772965781ee83eb/drf_httpsig-1.1.1-py2.py3-none-any.whl" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "cd99a81cde2a2e7f49e93e798dc77355", "sha256": "0ae0920adf81148fcd88799a7043de3117511a0960024058c316986918fc104e" }, "downloads": -1, "filename": "drf_httpsig-1.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cd99a81cde2a2e7f49e93e798dc77355", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11520, "upload_time": "2018-03-28T21:29:18", "url": "https://files.pythonhosted.org/packages/91/e8/da39da30c2117d4e9e0daace8f3d93c690f60dcb1b1ce5384011dc515479/drf_httpsig-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1168d2eece51bc849076a7085da400a3", "sha256": "4a0378679f35ce94cf32359dcc34e4d6894784f549f62e02584068ae6fa74f2f" }, "downloads": -1, "filename": "drf-httpsig-1.2.0.tar.gz", "has_sig": false, "md5_digest": "1168d2eece51bc849076a7085da400a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9219, "upload_time": "2018-03-28T21:29:20", "url": "https://files.pythonhosted.org/packages/68/55/64fa1f8a1e78d38692f4566bce217a2e263c520e8d5e8758f424f61541c8/drf-httpsig-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cd99a81cde2a2e7f49e93e798dc77355", "sha256": "0ae0920adf81148fcd88799a7043de3117511a0960024058c316986918fc104e" }, "downloads": -1, "filename": "drf_httpsig-1.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cd99a81cde2a2e7f49e93e798dc77355", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11520, "upload_time": "2018-03-28T21:29:18", "url": "https://files.pythonhosted.org/packages/91/e8/da39da30c2117d4e9e0daace8f3d93c690f60dcb1b1ce5384011dc515479/drf_httpsig-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1168d2eece51bc849076a7085da400a3", "sha256": "4a0378679f35ce94cf32359dcc34e4d6894784f549f62e02584068ae6fa74f2f" }, "downloads": -1, "filename": "drf-httpsig-1.2.0.tar.gz", "has_sig": false, "md5_digest": "1168d2eece51bc849076a7085da400a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9219, "upload_time": "2018-03-28T21:29:20", "url": "https://files.pythonhosted.org/packages/68/55/64fa1f8a1e78d38692f4566bce217a2e263c520e8d5e8758f424f61541c8/drf-httpsig-1.2.0.tar.gz" } ] }