stages/user_login: use timedelta_string_validator instead of seconds

This commit is contained in:
Jens Langhammer 2020-10-26 21:30:22 +01:00
parent 6b3411f63b
commit 054b819262
10 changed files with 65 additions and 11 deletions

View File

@ -117,7 +117,7 @@
}, },
"model": "passbook_stages_user_login.userloginstage", "model": "passbook_stages_user_login.userloginstage",
"attrs": { "attrs": {
"session_duration": 0 "session_duration": "seconds=-1"
} }
}, },
{ {

View File

@ -136,7 +136,7 @@
}, },
"model": "passbook_stages_user_login.userloginstage", "model": "passbook_stages_user_login.userloginstage",
"attrs": { "attrs": {
"session_duration": 0 "session_duration": "seconds=-1"
} }
}, },
{ {

View File

@ -20,7 +20,7 @@
}, },
"model": "passbook_stages_user_login.userloginstage", "model": "passbook_stages_user_login.userloginstage",
"attrs": { "attrs": {
"session_duration": 0 "session_duration": "seconds=-1"
} }
}, },
{ {

View File

@ -20,7 +20,7 @@
}, },
"model": "passbook_stages_user_login.userloginstage", "model": "passbook_stages_user_login.userloginstage",
"attrs": { "attrs": {
"session_duration": 0 "session_duration": "seconds=-1"
} }
}, },
{ {

View File

@ -118,7 +118,7 @@
}, },
"model": "passbook_stages_user_login.userloginstage", "model": "passbook_stages_user_login.userloginstage",
"attrs": { "attrs": {
"session_duration": 0 "session_duration": "seconds=-1"
} }
}, },
{ {

View File

@ -13,4 +13,5 @@ class UserLoginStageForm(forms.ModelForm):
fields = ["name", "session_duration"] fields = ["name", "session_duration"]
widgets = { widgets = {
"name": forms.TextInput(), "name": forms.TextInput(),
"session_duration": forms.TextInput(),
} }

View File

@ -0,0 +1,41 @@
# Generated by Django 3.1.2 on 2020-10-26 20:21
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
import passbook.lib.utils.time
def update_duration(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
UserLoginStage = apps.get_model("passbook_stages_user_login", "userloginstage")
db_alias = schema_editor.connection.alias
for stage in UserLoginStage.objects.using(db_alias).all():
if stage.session_duration.isdigit():
if stage.session_duration == 0:
stage.session_duration = "seconds=1"
else:
stage.session_duration = f"seconds={stage.session_duration}"
stage.save()
class Migration(migrations.Migration):
dependencies = [
("passbook_stages_user_login", "0002_userloginstage_session_duration"),
]
operations = [
migrations.AlterField(
model_name="userloginstage",
name="session_duration",
field=models.TextField(
default="seconds=-1",
help_text="Determines how long a session lasts. Default of -1 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)",
validators=[passbook.lib.utils.time.timedelta_string_validator],
),
),
migrations.RunPython(update_duration),
]

View File

@ -8,16 +8,19 @@ from django.views import View
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from passbook.flows.models import Stage from passbook.flows.models import Stage
from passbook.lib.utils.time import timedelta_string_validator
class UserLoginStage(Stage): class UserLoginStage(Stage):
"""Attaches the currently pending user to the current session.""" """Attaches the currently pending user to the current session."""
session_duration = models.PositiveIntegerField( session_duration = models.TextField(
default=0, default="seconds=-1",
validators=[timedelta_string_validator],
help_text=_( help_text=_(
"Determines how long a session lasts, in seconds. Default of 0 means" "Determines how long a session lasts. Default of -1 means "
"that the sessions lasts until the browser is closed. " "that the sessions lasts until the browser is closed. "
"(Format: hours=-1;minutes=-2;seconds=-3)"
), ),
) )

View File

@ -2,11 +2,13 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import login from django.contrib.auth import login
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.utils.timezone import now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from structlog import get_logger from structlog import get_logger
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER
from passbook.flows.stage import StageView from passbook.flows.stage import StageView
from passbook.lib.utils.time import timedelta_from_string
from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
LOGGER = get_logger() LOGGER = get_logger()
@ -32,7 +34,12 @@ class UserLoginStageView(StageView):
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER], self.executor.plan.context[PLAN_CONTEXT_PENDING_USER],
backend=backend, backend=backend,
) )
self.request.session.set_expiry(self.executor.current_stage.session_duration) delta = timedelta_from_string(self.executor.current_stage.session_duration)
if delta.seconds == -1:
self.request.session.set_expiry(0)
else:
expiry = now() + delta
self.request.session.set_expiry(expiry)
LOGGER.debug( LOGGER.debug(
"Logged in", "Logged in",
user=self.executor.plan.context[PLAN_CONTEXT_PENDING_USER], user=self.executor.plan.context[PLAN_CONTEXT_PENDING_USER],

View File

@ -105,5 +105,7 @@ class TestUserLoginStage(TestCase):
def test_form(self): def test_form(self):
"""Test Form""" """Test Form"""
data = {"name": "test", "session_duration": 0} data = {"name": "test", "session_duration": "seconds=0"}
self.assertEqual(UserLoginStageForm(data).is_valid(), True) self.assertEqual(UserLoginStageForm(data).is_valid(), True)
data = {"name": "test", "session_duration": "123"}
self.assertEqual(UserLoginStageForm(data).is_valid(), False)