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:
parent
61bf73d2f9
commit
fab6a8f8c9
|
@ -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,
|
||||||
|
|
|
@ -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()), [])
|
||||||
|
|
Reference in New Issue