core: delete session when user is set to inactive
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
c9c059a008
commit
31ef6fb6a6
|
@ -4,6 +4,8 @@ from json import loads
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from django.contrib.auth import update_session_auth_hash
|
from django.contrib.auth import update_session_auth_hash
|
||||||
|
from django.contrib.sessions.backends.cache import KEY_PREFIX
|
||||||
|
from django.core.cache import cache
|
||||||
from django.db.models.functions import ExtractHour
|
from django.db.models.functions import ExtractHour
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.db.transaction import atomic
|
from django.db.transaction import atomic
|
||||||
|
@ -57,6 +59,7 @@ from authentik.core.models import (
|
||||||
USER_ATTRIBUTE_SA,
|
USER_ATTRIBUTE_SA,
|
||||||
USER_ATTRIBUTE_TOKEN_EXPIRING,
|
USER_ATTRIBUTE_TOKEN_EXPIRING,
|
||||||
USER_PATH_SERVICE_ACCOUNT,
|
USER_PATH_SERVICE_ACCOUNT,
|
||||||
|
AuthenticatedSession,
|
||||||
Group,
|
Group,
|
||||||
Token,
|
Token,
|
||||||
TokenIntents,
|
TokenIntents,
|
||||||
|
@ -561,3 +564,14 @@ class UserViewSet(UsedByMixin, ModelViewSet):
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def partial_update(self, request: Request, *args, **kwargs) -> Response:
|
||||||
|
response = super().partial_update(request, *args, **kwargs)
|
||||||
|
instance: User = self.get_object()
|
||||||
|
if not instance.is_active:
|
||||||
|
sessions = AuthenticatedSession.objects.filter(user=instance)
|
||||||
|
session_ids = sessions.values_list("session_key", flat=True)
|
||||||
|
cache.delete_many(f"{KEY_PREFIX}{session}" for session in session_ids)
|
||||||
|
sessions.delete()
|
||||||
|
LOGGER.debug("Deleted user's sessions", user=instance.username)
|
||||||
|
return response
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
"""Test Users API"""
|
"""Test Users API"""
|
||||||
from json import loads
|
from json import loads
|
||||||
|
|
||||||
|
from django.contrib.sessions.backends.cache import KEY_PREFIX
|
||||||
|
from django.core.cache import cache
|
||||||
from django.urls.base import reverse
|
from django.urls.base import reverse
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import AuthenticatedSession, User
|
||||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_tenant
|
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_tenant
|
||||||
from authentik.flows.models import FlowDesignation
|
from authentik.flows.models import FlowDesignation
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
|
@ -257,3 +259,26 @@ class TestUsersAPI(APITestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
body = loads(response.content.decode())
|
body = loads(response.content.decode())
|
||||||
self.assertEqual(body["user"]["avatar"], "bar")
|
self.assertEqual(body["user"]["avatar"], "bar")
|
||||||
|
|
||||||
|
def test_session_delete(self):
|
||||||
|
"""Ensure sessions are deleted when a user is deactivated"""
|
||||||
|
user = create_test_admin_user()
|
||||||
|
session_id = generate_id()
|
||||||
|
AuthenticatedSession.objects.create(
|
||||||
|
user=user,
|
||||||
|
session_key=session_id,
|
||||||
|
last_ip="",
|
||||||
|
)
|
||||||
|
cache.set(KEY_PREFIX + session_id, "foo")
|
||||||
|
|
||||||
|
self.client.force_login(self.admin)
|
||||||
|
response = self.client.patch(
|
||||||
|
reverse("authentik_api:user-detail", kwargs={"pk": user.pk}),
|
||||||
|
data={
|
||||||
|
"is_active": False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
self.assertIsNone(cache.get(KEY_PREFIX + session_id))
|
||||||
|
self.assertFalse(AuthenticatedSession.objects.filter(session_key=session_id).exists())
|
||||||
|
|
Reference in a new issue