stages/user_login: expiry before login (#4920)

* stages/user_write: run set_expiry before login, so that session used in Signal has correct expiry

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-03-13 15:31:06 +01:00 committed by GitHub
parent 61bf73d2f9
commit fab6a8f8c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 5 deletions

View File

@ -32,16 +32,16 @@ class UserLoginStageView(StageView):
user: User = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] user: User = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
if not user.is_active: if not user.is_active:
self.logger.warning("User is not active, login will not work.") self.logger.warning("User is not active, login will not work.")
login(
self.request,
user,
backend=backend,
)
delta = timedelta_from_string(self.executor.current_stage.session_duration) delta = timedelta_from_string(self.executor.current_stage.session_duration)
if delta.total_seconds() == 0: if delta.total_seconds() == 0:
self.request.session.set_expiry(0) self.request.session.set_expiry(0)
else: else:
self.request.session.set_expiry(delta) self.request.session.set_expiry(delta)
login(
self.request,
user,
backend=backend,
)
self.logger.debug( self.logger.debug(
"Logged in", "Logged in",
backend=backend, backend=backend,

View File

@ -5,6 +5,7 @@ from unittest.mock import patch
from django.contrib.sessions.backends.cache import KEY_PREFIX from django.contrib.sessions.backends.cache import KEY_PREFIX
from django.core.cache import cache from django.core.cache import cache
from django.urls import reverse from django.urls import reverse
from django.utils.timezone import now
from authentik.core.models import AuthenticatedSession from authentik.core.models import AuthenticatedSession
from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.core.tests.utils import create_test_admin_user, create_test_flow
@ -16,6 +17,7 @@ from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views.executor import SESSION_KEY_PLAN from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.generators import generate_id from authentik.lib.generators import generate_id
from authentik.lib.utils.http import DEFAULT_IP from authentik.lib.utils.http import DEFAULT_IP
from authentik.lib.utils.time import timedelta_from_string
from authentik.stages.user_login.models import UserLoginStage from authentik.stages.user_login.models import UserLoginStage
@ -103,6 +105,13 @@ class TestUserLoginStage(FlowTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect")) self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
self.assertNotEqual(list(self.client.session.keys()), []) self.assertNotEqual(list(self.client.session.keys()), [])
session_key = self.client.session.session_key
session = AuthenticatedSession.objects.filter(session_key=session_key).first()
self.assertAlmostEqual(
session.expires.timestamp() - now().timestamp(),
timedelta_from_string(self.stage.session_duration).total_seconds(),
delta=1,
)
sleep(3) sleep(3)
self.client.session.clear_expired() self.client.session.clear_expired()
self.assertEqual(list(self.client.session.keys()), []) self.assertEqual(list(self.client.session.keys()), [])