Add API token management: implement APIToken model, views, and templates for creating and revoking tokens

This commit is contained in:
Ross
2026-02-23 11:57:57 +00:00
parent 83d1b48213
commit d7f3ebf950
8 changed files with 309 additions and 17 deletions
+38
View File
@@ -230,6 +230,44 @@ class SynMixin(object):
return format_html("<a href='{}'>{}</a>", self.get_absolute_url(), self.name)
class APIToken(models.Model):
"""Personal Access Token for API access.
Stores only a hash of the token. The raw token is returned once at
creation and never stored in plaintext.
"""
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="api_tokens")
name = models.CharField(max_length=200, blank=True, help_text="Friendly name for this token")
token_hash = models.CharField(max_length=64, db_index=True)
scopes = models.CharField(max_length=255, blank=True, help_text="Space-separated scopes")
created = models.DateTimeField(auto_now_add=True)
expires = models.DateTimeField(null=True, blank=True)
revoked = models.BooleanField(default=False)
last_used = models.DateTimeField(null=True, blank=True)
class Meta:
verbose_name = "API token"
verbose_name_plural = "API tokens"
def __str__(self):
return f"APIToken(user={self.user}, name={self.name})"
@classmethod
def create_token(cls, user, name="", scopes="", expires=None):
import secrets, hashlib
token = secrets.token_urlsafe(32)
token_hash = hashlib.sha256(token.encode()).hexdigest()
obj = cls.objects.create(user=user, name=name, token_hash=token_hash, scopes=scopes, expires=expires)
return token, obj
def mark_used(self):
from django.utils import timezone
self.last_used = timezone.now()
self.save(update_fields=["last_used"])
class Finding(SynMixin, models.Model):
name = models.CharField(max_length=255, unique=True)
# New canonical/alias field: if set, this Finding is an alias and points