-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This vendors Django Rest Knox from v4.2.0, and removes many settings and features that we do not use. The implementation is now closer to Django Rest Frameworks `TokenAuthentication`, but with multiple tokens per user, the token digests being stored, and expiry dates added. Closes DIAGNijmegen/rse-grand-challenge-admin#387
- Loading branch information
Showing
28 changed files
with
626 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2015 James McMahon | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
Metadata-Version: 2.1 | ||
Name: django-rest-knox | ||
Version: 4.2.0 | ||
Summary: Authentication for django rest framework | ||
Home-page: https://github.com/James1345/django-rest-knox | ||
Author: James McMahon | ||
Author-email: james1345@googlemail.com | ||
License: MIT | ||
Keywords: django rest authentication login | ||
Platform: UNKNOWN | ||
Classifier: Development Status :: 5 - Production/Stable | ||
Classifier: Intended Audience :: Developers | ||
Classifier: Topic :: Internet :: WWW/HTTP :: Session | ||
Classifier: License :: OSI Approved :: MIT License | ||
Classifier: Programming Language :: Python :: 3 | ||
Classifier: Programming Language :: Python :: 3.7 | ||
Classifier: Programming Language :: Python :: 3.8 | ||
Classifier: Programming Language :: Python :: 3.9 | ||
Classifier: Programming Language :: Python :: 3.10 | ||
Requires-Python: >=3.6 | ||
Description-Content-Type: text/markdown | ||
License-File: LICENSE | ||
Requires-Dist: cryptography | ||
Requires-Dist: django (>=3.2) | ||
Requires-Dist: djangorestframework | ||
Provides-Extra: dev | ||
Provides-Extra: test | ||
|
||
django-rest-knox | ||
================ | ||
|
||
[![image](https://github.com/James1345/django-rest-knox/workflows/Test/badge.svg?branch=develop)](https://github.com/James1345/django-rest-knox/actions) | ||
|
||
Authentication Module for django rest auth | ||
|
||
Knox provides easy to use authentication for [Django REST | ||
Framework](https://www.django-rest-framework.org/) The aim is to allow | ||
for common patterns in applications that are REST based, with little | ||
extra effort; and to ensure that connections remain secure. | ||
|
||
Knox authentication is token based, similar to the `TokenAuthentication` | ||
built in to DRF. However, it overcomes some problems present in the | ||
default implementation: | ||
|
||
- DRF tokens are limited to one per user. This does not facilitate | ||
securely signing in from multiple devices, as the token is shared. | ||
It also requires *all* devices to be logged out if a server-side | ||
logout is required (i.e. the token is deleted). | ||
|
||
Knox provides one token per call to the login view - allowing each | ||
client to have its own token which is deleted on the server side | ||
when the client logs out. | ||
|
||
Knox also provides an option for a logged in client to remove *all* | ||
tokens that the server has - forcing all clients to re-authenticate. | ||
|
||
- DRF tokens are stored unencrypted in the database. This would allow | ||
an attacker unrestricted access to an account with a token if the | ||
database were compromised. | ||
|
||
Knox tokens are only stored in a secure hash form (like a password). Even if the | ||
database were somehow stolen, an attacker would not be able to log | ||
in with the stolen credentials. | ||
|
||
- DRF tokens track their creation time, but have no inbuilt mechanism | ||
for tokens expiring. Knox tokens can have an expiry configured in | ||
the app settings (default is 10 hours.) | ||
|
||
More information can be found in the | ||
[Documentation](https://james1345.github.io/django-rest-knox/) | ||
|
||
# Run the tests locally | ||
|
||
If you need to debug a test locally and if you have [docker](https://www.docker.com/) installed: | ||
|
||
simply run the ``./docker-run-tests.sh`` script and it will run the test suite in every Python / | ||
Django versions. | ||
|
||
You could also simply run regular ``tox`` in the root folder as well, but that would make testing the matrix of | ||
Python / Django versions a bit more tricky. | ||
|
||
# Work on the documentation | ||
|
||
Our documentation is generated by [Mkdocs](https://www.mkdocs.org). | ||
|
||
You can refer to their documentation on how to install it locally. | ||
|
||
Another option is to use `mkdocs.sh` in this repository. | ||
It will run mkdocs in a [docker](https://www.docker.com/) container. | ||
|
||
Running the script without any params triggers the `serve` command. | ||
The server is exposed on localhost on port 8000. | ||
|
||
To configure the port the `serve` command will be exposing the server to, you | ||
can use the following env var: | ||
|
||
``` | ||
MKDOCS_DEV_PORT="8080" | ||
``` | ||
|
||
You can also pass any `mkdocs` command like this: | ||
|
||
``` | ||
./mkdocs build | ||
./mkdocs --help | ||
``` | ||
|
||
Check the [Mkdocs documentation](https://www.mkdocs.org/) for more. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django.contrib import admin | ||
from knox import models | ||
|
||
|
||
@admin.register(models.AuthToken) | ||
class AuthTokenAdmin(admin.ModelAdmin): | ||
list_display = ( | ||
"key", | ||
"user", | ||
"created", | ||
"expiry", | ||
) | ||
fields = () | ||
raw_id_fields = ("user",) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import binascii | ||
|
||
from django.utils import timezone | ||
from django.utils.translation import gettext_lazy as _ | ||
from knox.crypto import hash_token | ||
from knox.models import AuthToken | ||
from rest_framework import exceptions | ||
from rest_framework.authentication import ( | ||
TokenAuthentication as BaseTokenAuthentication, | ||
) | ||
|
||
|
||
class TokenAuthentication(BaseTokenAuthentication): | ||
model = AuthToken | ||
keyword = "Bearer" | ||
|
||
def authenticate_credentials(self, key): | ||
try: | ||
digest = hash_token(key) | ||
except (TypeError, binascii.Error): | ||
raise exceptions.AuthenticationFailed(_("Invalid token.")) | ||
|
||
user, token = super().authenticate_credentials(key=digest) | ||
|
||
if token.expiry is not None and token.expiry < timezone.now(): | ||
raise exceptions.AuthenticationFailed(_("Invalid token.")) | ||
|
||
return (user, token) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import binascii | ||
import hashlib | ||
from os import urandom as generate_bytes | ||
|
||
|
||
def create_token_string(): | ||
auth_token_character_length = 64 | ||
return binascii.hexlify( | ||
generate_bytes(int(auth_token_character_length / 2)) | ||
).decode() | ||
|
||
|
||
def hash_token(token): | ||
""" | ||
Calculates the hash of a token. | ||
Token must contain an even number of hex digits or | ||
a binascii.Error exception will be raised. | ||
""" | ||
digest = hashlib.sha512() | ||
digest.update(binascii.unhexlify(token)) | ||
return digest.hexdigest() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from django.conf import settings | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="AuthToken", | ||
fields=[ | ||
( | ||
"key", | ||
models.CharField( | ||
max_length=64, serialize=False, primary_key=True | ||
), | ||
), | ||
("created", models.DateTimeField(auto_now_add=True)), | ||
( | ||
"user", | ||
models.ForeignKey( | ||
to=settings.AUTH_USER_MODEL, | ||
related_name="auth_token_set", | ||
on_delete=models.CASCADE, | ||
), | ||
), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from django.conf import settings | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("knox", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.DeleteModel("AuthToken"), | ||
migrations.CreateModel( | ||
name="AuthToken", | ||
fields=[ | ||
( | ||
"digest", | ||
models.CharField( | ||
max_length=64, serialize=False, primary_key=True | ||
), | ||
), | ||
( | ||
"salt", | ||
models.CharField( | ||
max_length=16, serialize=False, unique=True | ||
), | ||
), | ||
("created", models.DateTimeField(auto_now_add=True)), | ||
( | ||
"user", | ||
models.ForeignKey( | ||
to=settings.AUTH_USER_MODEL, | ||
related_name="auth_token_set", | ||
on_delete=models.CASCADE, | ||
), | ||
), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("knox", "0002_auto_20150916_1425"), | ||
] | ||
|
||
operations = [ | ||
migrations.AlterField( | ||
model_name="authtoken", | ||
name="digest", | ||
field=models.CharField( | ||
primary_key=True, serialize=False, max_length=128 | ||
), | ||
), | ||
migrations.AlterField( | ||
model_name="authtoken", | ||
name="salt", | ||
field=models.CharField(unique=True, max_length=16), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("knox", "0003_auto_20150916_1526"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="authtoken", | ||
name="expires", | ||
field=models.DateTimeField(null=True, blank=True), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Django 1.10 on 2016-08-18 09:23 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("knox", "0004_authtoken_expires"), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name="authtoken", | ||
name="token_key", | ||
field=models.CharField( | ||
blank=True, db_index=True, max_length=8, null=True | ||
), | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Generated by Django 1.10 on 2016-08-18 09:32 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
def cleanup_tokens(apps, schema_editor): | ||
AuthToken = apps.get_model("knox", "AuthToken") # noqa: N806 | ||
AuthToken.objects.filter(token_key__isnull=True).delete() | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("knox", "0005_authtoken_token_key"), | ||
] | ||
|
||
operations = [ | ||
migrations.RunPython(cleanup_tokens), | ||
migrations.AlterField( | ||
model_name="authtoken", | ||
name="token_key", | ||
field=models.CharField(db_index=True, default="", max_length=8), | ||
preserve_default=False, | ||
), | ||
] |
Oops, something went wrong.