# -*- coding: utf-8 -*-
from setuptools import setup

package_dir = \
{'': 'src'}

packages = \
['django_pat', 'django_pat.migrations', 'django_pat.rest_framework']

package_data = \
{'': ['*'], 'django_pat': ['templates/personal_access_token/*']}

extras_require = \
{':python_version == "3.7"': ['django>=3.2,<3.3'],
 ':python_version >= "3.8"': ['django>=3.2,<4.2'],
 'djangorestframework': ['djangorestframework>=3.11,<4.0']}

setup_kwargs = {
    'name': 'django-pat',
    'version': '0.1.1',
    'description': 'A Django package for creating, using, and managing personal access tokens.',
    'long_description': '# Django PAT (Personal Access Tokens)\n\n![Tests](https://github.com/camuthig/django-pat/actions/workflows/ci.yml/badge.svg)\n[![codecov](https://codecov.io/gh/camuthig/django-pat/branch/main/graph/badge.svg?token=GAGIIZXC95)](https://codecov.io/gh/camuthig/django-pat)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nThis application creates personal access tokens that clients can send via HTTP headers to authenticate as a particular user.\nThis application expands on the standard functionality provided in REST Framework tokens by allowing users to create\nmore than one token and cycle/revoke tokens for security purposes.\n\nPersonal access tokens are API keys that allow clients to pass a secure value to an API without having to first exchange\na username and password. This  makes interactions between machines straightforward and consistent. While these tokens are\neasy to use, it is important to ensure they are secure. This application accomplishes this security by:\n\n1. Hashing all token values after creation. This ensures admins of the application and malicious actors are never be able\n   to access token values in plain text via a data breach.\n2. Allowing for tokens to be "cycled". This is accomplished by revoking existing tokens and creating new ones. Clients\n   can do this easily via APIs on a regular basis or as needed, if they believe a token has been compromised.\n\n## Usage\n\nBy default, both the standard middleware and the REST Framework authentication will look for the token in the\n`Authorization` HTTP header with a prefix of `Access-Token`. So this might look like\n\n```\nAuthorization: Access-Token 41ecea63-66eb-4e6a-bffd-e85cd29718ab\n```\n\n### Initial Setup\n1. Install the package: `pip install git+https://github.com/camuthig/django-pat.git@master` (not yet available on pypi)\n2. Add `django_pat` to the `INSTALLED_APPS` of your project\n3. Add the `PAT_SECRET` value to your settings file to hash secrets. This value should be kept secret!\n    ```python\n    PAT_SECRET = "super-secret-hashing-key"\n    ```\n\n\n### Django Middleware\n\n1. Add the middleware to your middleware stack\n   ```python\n   MIDDLEWARE = [\n       "django.contrib.auth.middleware.AuthenticationMiddleware",\n       "django_pat.middleware.PatAuthenticationMiddleware",\n   ]\n   ```\n\n### REST Framework\n\n1. Add the authentication class to your DRF default authentication classes\n   ```python\n   REST_FRAMEWORK = {\n       "DEFAULT_AUTHENTICATION_CLASSES": [\n           "django_pat.rest_framework.auth.PatAuthentication",\n           "rest_framework.authentication.SessionAuthentication",\n       ],\n   }\n   ```\n\n**Optional: Add Personal Access Token Views**\n\nAPIs can be added to your Django application to create, retrieve, and revoke tokens out of the box.\n\n```python\n# urls.py\nfrom django.urls import include\nfrom django.urls import path\n\nfrom django_pat.rest_framework.urls import router as pat_router\n\nurlpatterns = [\n    # other routes...\n\n    path("api/", include(pat_router.urls)),\n]\n```\n\n## Configuration\n\nAlong with the `PAT_SECRET` value that is required, you can also configure certain behaviors of the package in your Django\napplication settings.\n\n* `PAT_CUSTOM_HEADER` - Sets the HTTP header to check for the token. This defaults to `Authorization`\n* `PAT_CUSTOM_HEADER_PREFIX` - Sets the prefix for the header value. This defaults to `Access-Token`. The middleware\n    and the REST authentication expect a space between the prefix and the token value.\n* `PAT_USES_SHARED_HEADER` - If set to True, then the package will not attempt to validate the prefix on the authorization\n    header. This is most useful when different prefixes are used for different types of authentication, but are all sent\n    using the same HTTP header.\n\n## Implementation Details\n\nAccess token values are implemented as UUID4 values. These are sufficiently unique to remain secure and avoid collisions.\n\n## Security Concerns\n\n**Personal access token records should NOT be deleted from the database, even if revoked.** If tokens are deleted, there is the\npossibility that the token value could be reassigned to a different user at a later time. If the user originally provided\nthe token retains it, they may later use it to inadvertently access the API as the new user. The default behavior of this\napplication in the admin is to _revoke_ token instead of deleting them, and it is recommended users follow this same\npattern.\n\nIf a brute force attack is a concern, then rate limiting should be applied to API views. The possibility of brute\nforcing all possible UUID4 values is unlikely, but rate limiting provides another way to avoid it.\n\n## Alternative Packages\n\n* [Django REST Framework API Key](https://florimondmanca.github.io/djangorestframework-api-key/guide/) This project\n  similarly provides the ability to create and manage API keys for machine-to-machine API calls. It is focused on\n  supporting unauthorized requests, i.e. those not linked to a particular user. There are a few reasons I chose to go\n  with a different option.\n  * The Django REST Framework API Keys is tightly coupled with Django REST Framework. I wanted this package to support\n    DRF without being coupled to it, such that developers who want to build APIs without DRF have the option.\n  * The default behavior of Django REST Framework API Keys is not linked to users. The key can be extended to have a\n    reference to the user, but this requires additional configuration and the default model table is still created for\n    the base API key model. This means that by default developers will be able to use existing user permissions with\n    working with a User API Key. See: [Issue 180](https://github.com/florimondmanca/djangorestframework-api-key/issues/180)\n  * The Django REST Framework API Key encryption technique used by the application creates a slower API. This has been\n    alleviated in Django User API Key by using HMAC hashing instead. See:\n    [Issue 173](https://github.com/florimondmanca/djangorestframework-api-key/issues/173)\n  * The primary key pattern of the Django REST Framework API Key records use special characters, making them difficult\n    to encode for browsers. See: [Issue 128](https://github.com/florimondmanca/djangorestframework-api-key/issues/128)\n* [Django REST Framework TokenAuthentication](https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication)\n  The standard DRF `TokenAuthentication` model has a couple of drawbacks that this project attempts to avoid by\n  expanding on the pattern. In the standard token pattern:\n  * The token value is stored in a plain-text format\n  * The token value acts as the primary key of the token. If building an API to retrieve the token, you would not\n    want to use this key in a URL, as it would go over the network in plain-text.\n  * Each user can only have a single token.\n  * Revoking one user\'s token opens up the possibility of generating the same token again for a different user.\n',
    'author': 'Chris Muthig',
    'author_email': 'camuthig@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'package_dir': package_dir,
    'packages': packages,
    'package_data': package_data,
    'extras_require': extras_require,
    'python_requires': '>=3.7,<3.12',
}


setup(**setup_kwargs)
