From ef2b079d276a2e485383ce0e1a187d882ae5c1dc Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Tue, 4 Apr 2023 12:19:52 +0200 Subject: Manage expiration of passwords --- ishtar_common/context_processors.py | 36 +++++++++++++++---- .../migrations/0227_auto_20230404_1112.py | 29 +++++++++++++++ ishtar_common/models.py | 5 +++ ishtar_common/templates/base.html | 2 +- ishtar_common/urls_registration.py | 6 ++-- ishtar_common/views.py | 42 +++++++++++++++++++++- ishtar_common/wizards.py | 1 + 7 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 ishtar_common/migrations/0227_auto_20230404_1112.py (limited to 'ishtar_common') diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py index e1754e935..c1d1224ea 100644 --- a/ishtar_common/context_processors.py +++ b/ishtar_common/context_processors.py @@ -17,8 +17,13 @@ # See the file COPYING for details. +import datetime + from django.conf import settings +from django.core.cache import cache from django.contrib.sites.models import Site +from django.urls import reverse +from django.utils.translation import ugettext_lazy as _ from ishtar_common.version import __version__ from ishtar_common.models import get_current_profile @@ -41,13 +46,6 @@ def get_base_context(request): except Site.DoesNotExist: dct["APP_NAME"] = settings.APP_NAME dct["COUNTRY"] = settings.COUNTRY - """ - if 'MENU' not in request.session or \ - request.session['MENU'].user != request.user: - menu = Menu(request.user) - menu.init() - request.session['MENU'] = menu - """ # menu is now in cache - put it back in session later? current_action = None if "CURRENT_ACTION" in request.session: @@ -71,6 +69,30 @@ def get_base_context(request): menu.init() if hasattr(request.user, "ishtaruser") and request.user.ishtaruser: + + # check password expiration date + if settings.ISHTAR_PASSWORD_EXPIRATION_DAYS and \ + isinstance(settings.ISHTAR_PASSWORD_EXPIRATION_DAYS, int): + key = f"{settings.PROJECT_SLUG}-password_expired-{request.user.pk}" + password_expired = cache.get(key) + if password_expired is None: + password_expired = True + d = datetime.date.today() - request.user.ishtaruser.password_last_update + if d.days < settings.ISHTAR_PASSWORD_EXPIRATION_DAYS: + password_expired = False + cache.set(key, password_expired, settings.CACHE_TIMEOUT) + if password_expired and not request.path.endswith("password_change/"): + msg = str(_("Your password has expired. Please update it using this " + "form.")) + msg = msg.replace( + str(_("form")), + f'' + f' ' + f'{_("form")}' + ) + dct["MESSAGES"].append((msg, "warning")) + + # external sources if ( request.user.ishtaruser.current_profile and "EXTERNAL_SOURCES" not in request.session diff --git a/ishtar_common/migrations/0227_auto_20230404_1112.py b/ishtar_common/migrations/0227_auto_20230404_1112.py new file mode 100644 index 000000000..1ba74f292 --- /dev/null +++ b/ishtar_common/migrations/0227_auto_20230404_1112.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.24 on 2023-04-04 11:12 + +import datetime +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ishtar_common', '0226_auto_20230316_1115'), + ] + + operations = [ + migrations.AddField( + model_name='ishtaruser', + name='password_last_update', + field=models.DateField(default=datetime.date.today, verbose_name='Password last update'), + ), + migrations.AlterField( + model_name='customform', + name='header', + field=models.TextField(blank=True, default='', help_text='You can use markdown syntax.', verbose_name='Header text'), + ), + migrations.AlterField( + model_name='ishtarsiteprofile', + name='footer', + field=models.TextField(blank=True, default='', help_text='You can use markdown syntax.', verbose_name='Footer text'), + ), + ] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index c053f7c10..efa061431 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -3410,6 +3410,9 @@ class IshtarUser(FullSearch): related_name="ishtaruser", on_delete=models.CASCADE, ) + password_last_update = models.DateField( + _("Password last update"), default=datetime.date.today + ) advanced_shortcut_menu = models.BooleanField( _("Advanced shortcut menu"), default=False ) @@ -3491,6 +3494,8 @@ class IshtarUser(FullSearch): def import_set_password(self, context, value): self.user_ptr.set_password(value) self.user_ptr.save() + self.password_last_update = datetime.date.today() + self.save() @post_importer_action def import_create_profile(self, context, value): diff --git a/ishtar_common/templates/base.html b/ishtar_common/templates/base.html index 53ef4f35a..be7187ef1 100644 --- a/ishtar_common/templates/base.html +++ b/ishtar_common/templates/base.html @@ -209,7 +209,7 @@ {% if MESSAGES %}{% for message, message_type in MESSAGES %}