Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions aboutcode/api_auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,18 @@ def generate_key(cls):
"""Generate a plain (not encrypted) key."""
return secrets.token_hex(32)

def set_key(self, plain_key):
"""Set the prefix and hashed key from a plain key. Does not save."""
self.prefix = plain_key[: self.PREFIX_LENGTH]
self.key_hash = make_password(plain_key)

@classmethod
def create_token(cls, user):
"""Generate a new token for the given user and return the plain key once."""
plain_key = cls.generate_key()
prefix = plain_key[: cls.PREFIX_LENGTH]
cls.objects.create(
user=user,
prefix=prefix,
key_hash=make_password(plain_key),
)
token = cls(user=user)
token.set_key(plain_key)
token.save()
return plain_key

@classmethod
Expand Down
14 changes: 14 additions & 0 deletions dje/tests/test_api_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# See https://aboutcode.org for more information about AboutCode FOSS projects.
#

from django.contrib.auth.hashers import check_password
from django.db.utils import IntegrityError
from django.test import TestCase

Expand Down Expand Up @@ -80,3 +81,16 @@ def test_api_auth_api_token_authentication_authenticate_credentials(self):
self.base_user.save()
with self.assertRaisesMessage(AuthenticationFailed, "User inactive or deleted."):
api_token_auth.authenticate_credentials(plain_key=plain_key)

def test_api_auth_api_token_model_set_key(self):
plain_key = APIToken.generate_key()
token = APIToken(user=self.base_user)
token.set_key(plain_key)

self.assertEqual(plain_key[: APIToken.PREFIX_LENGTH], token.prefix)
self.assertEqual(59, len(token.key_hash))
self.assertTrue(check_password(plain_key, token.key_hash))
# set_key must not save the instance
self.assertEqual(0, APIToken.objects.count())
token.save()
self.assertEqual(1, APIToken.objects.count())
Loading