From 10f54bc11ae430c6446c097c0834a2bd3cf7f084 Mon Sep 17 00:00:00 2001 From: Michael Karamuth Date: Mon, 20 Dec 2021 09:52:44 +0400 Subject: [PATCH] feature: Login remember me functionality - Improve wagtail/admin/views/account.py - Co-authored-by: Jake Howard --- CHANGELOG.txt | 1 + docs/releases/2.16.md | 1 + wagtail/admin/forms/auth.py | 8 +++++--- wagtail/admin/templates/wagtailadmin/login.html | 13 +++++-------- wagtail/admin/tests/test_views.py | 17 +++++++++++++++++ wagtail/admin/views/account.py | 11 +++++++++++ 6 files changed, 40 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 8c1adf330c..eb8dc63058 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -17,6 +17,7 @@ Changelog * Removed WOFF fonts * Add system check for missing core Page fields in `search_fields` (LB (Ben Johnston)) * Improve CircleCI frontend & backend build caches (Thibaud Colas) + * Add a 'remember me' checkbox to the admin sign in form, if unticked (default) the auth session will expire if the browser is closed (Michael Karamuth, Jake Howard) * Fix: Accessibility fixes for Windows high contrast mode; Dashboard icons colour and contrast (Sakshi Uppoor) * Fix: Rename additional 'spin' CSS animations to avoid clashes with other libraries (Kevin GutiƩrrez) * Fix: `default_app_config` deprecations for Django >= 3.2 (Tibor Leupold) diff --git a/docs/releases/2.16.md b/docs/releases/2.16.md index 01344588fb..a46a31eae5 100644 --- a/docs/releases/2.16.md +++ b/docs/releases/2.16.md @@ -24,6 +24,7 @@ * Add secondary actions menu in edit page headers (Tidjani Dia) * Add system check for missing core Page fields in `search_fields` (LB (Ben Johnston)) * Improve CircleCI frontend & backend build caches (Thibaud Colas) + * Add a 'remember me' checkbox to the admin sign in form, if unticked (default) the auth session will expire if the browser is closed (Michael Karamuth, Jake Howard) ### Bug fixes diff --git a/wagtail/admin/forms/auth.py b/wagtail/admin/forms/auth.py index 54c6acf1b0..59145d6e94 100644 --- a/wagtail/admin/forms/auth.py +++ b/wagtail/admin/forms/auth.py @@ -14,6 +14,8 @@ class LoginForm(AuthenticationForm): 'placeholder': gettext_lazy("Enter password"), })) + remember = forms.BooleanField(required=False) + def __init__(self, request=None, *args, **kwargs): super().__init__(request=request, *args, **kwargs) self.fields['username'].widget.attrs['placeholder'] = ( @@ -21,9 +23,9 @@ class LoginForm(AuthenticationForm): @property def extra_fields(self): - for field_name in self.fields.keys(): - if field_name not in ['username', 'password']: - yield field_name, self[field_name] + for field_name, field in self.fields.items(): + if field_name not in ['username', 'password', 'remember']: + yield field_name, field class PasswordResetForm(DjangoPasswordResetForm): diff --git a/wagtail/admin/templates/wagtailadmin/login.html b/wagtail/admin/templates/wagtailadmin/login.html index cba15eccd8..2b11bf1ca8 100644 --- a/wagtail/admin/templates/wagtailadmin/login.html +++ b/wagtail/admin/templates/wagtailadmin/login.html @@ -66,14 +66,11 @@ {% endfor %} {% endblock extra_fields %} - {% comment %} - Removed until functionality exists -
  • -
    - -
    -
  • - {% endcomment %} +
  • +
    + +
    +
  • {% endblock %}
  • diff --git a/wagtail/admin/tests/test_views.py b/wagtail/admin/tests/test_views.py index 927ba84c79..25fd1ed87c 100644 --- a/wagtail/admin/tests/test_views.py +++ b/wagtail/admin/tests/test_views.py @@ -65,3 +65,20 @@ class TestLoginView(TestCase, WagtailTestUtils): def test_login_page_renders_extra_fields(self): response = self.client.get(reverse('wagtailadmin_login')) self.assertContains(response, '') + + def test_session_expire_on_browser_close(self): + self.client.post(reverse('wagtailadmin_login'), { + 'username': 'test@email.com', + 'password': 'password', + }) + self.assertTrue(self.client.session.get_expire_at_browser_close()) + + @override_settings(SESSION_COOKIE_AGE=7) + def test_session_expiry_remember(self): + self.client.post(reverse('wagtailadmin_login'), { + 'username': 'test@email.com', + 'password': 'password', + 'remember': True + }) + self.assertFalse(self.client.session.get_expire_at_browser_close()) + self.assertEqual(self.client.session.get_expiry_age(), 7) diff --git a/wagtail/admin/views/account.py b/wagtail/admin/views/account.py index c6650ca0b0..b5af29ae86 100644 --- a/wagtail/admin/views/account.py +++ b/wagtail/admin/views/account.py @@ -312,6 +312,17 @@ class LoginView(auth_views.LoginView): def get_form_class(self): return get_user_login_form() + def form_valid(self, form): + response = super().form_valid(form) + + remember = form.cleaned_data.get('remember') + if remember: + self.request.session.set_expiry(settings.SESSION_COOKIE_AGE) + else: + self.request.session.set_expiry(0) + + return response + def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs)