diff --git a/pandora/settings.py b/pandora/settings.py index 7c9a890a..cc6b8e76 100644 --- a/pandora/settings.py +++ b/pandora/settings.py @@ -103,6 +103,7 @@ MIDDLEWARE = ( 'django.contrib.messages.middleware.MessageMiddleware', 'oxdjango.middleware.ExceptionMiddleware', 'oxdjango.middleware.ChromeFrameMiddleware', + 'user.middleware.TokenSession', 'user.middleware.UpdateSession', ) diff --git a/pandora/user/middleware.py b/pandora/user/middleware.py index 36291497..d6b71c52 100644 --- a/pandora/user/middleware.py +++ b/pandora/user/middleware.py @@ -2,6 +2,7 @@ from django.conf import settings from django.contrib.sessions.models import Session from django.utils.deprecation import MiddlewareMixin +import django.contrib.auth class UpdateSession(MiddlewareMixin): @@ -13,3 +14,22 @@ class UpdateSession(MiddlewareMixin): def process_response(self, request, response): return response + + +class TokenSession(MiddlewareMixin): + + def process_request(self, request): + from . import models + value = request.GET.get("token") + if not value: + auth = request.META.get("HTTP_AUTHORIZATION", "").split() + if auth and auth[0].lower() == 'bearer' and len(auth) == 2: + value = auth[1] + if value: + token = models.AccessToken.objects.filter(value=value).first() + if token: + #django.contrib.auth.login(request, token.user) + request.user = token.user + + def process_response(self, request, response): + return response diff --git a/pandora/user/migrations/0006_accesstoken.py b/pandora/user/migrations/0006_accesstoken.py new file mode 100644 index 00000000..5126c483 --- /dev/null +++ b/pandora/user/migrations/0006_accesstoken.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.26 on 2026-01-10 13:54 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('user', '0005_id_bigint_jsonfield'), + ] + + operations = [ + migrations.CreateModel( + name='AccessToken', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('value', models.CharField(max_length=36, unique=True)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/pandora/user/models.py b/pandora/user/models.py index 78c68483..d3827428 100644 --- a/pandora/user/models.py +++ b/pandora/user/models.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- -import copy from datetime import datetime +import copy +import uuid from django.contrib.auth.models import Group from django.contrib.auth import get_user_model @@ -457,3 +458,16 @@ def merge_users(old, new): old.log_set.all().update(user=new) old.changelog.all().update(user=new) old.logentry_set.all().update(user=new) + + +class AccessToken(models.Model): + user = models.ForeignKey(User, related_name='tokens', on_delete=models.CASCADE) + value = models.CharField(max_length=36, unique=True) + + def save(self, *args, **kwargs): + if not self.value: + self.value = str(uuid.uuid1()) + super(AccessToken, self).save(*args, **kwargs) + + def __str__(self): + return '%s (%s)' % (self.value, self.user.username)