From f9397b6dd09fc62ebc154420fa35ea7d562f227d Mon Sep 17 00:00:00 2001 From: Tom Teichler <tom.teichler@teckids.org> Date: Sat, 28 Mar 2020 20:26:11 +0000 Subject: [PATCH] Auto-select primary group if pattern is configured --- aleksis/core/apps.py | 10 ++++++++++ aleksis/core/models.py | 20 ++++++++++++++++++-- aleksis/core/util/apps.py | 22 ++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/aleksis/core/apps.py b/aleksis/core/apps.py index b373367ef..13e3b3ddc 100644 --- a/aleksis/core/apps.py +++ b/aleksis/core/apps.py @@ -1,9 +1,12 @@ from typing import Any, List, Optional, Tuple import django.apps +from django.contrib.auth.signals import user_logged_in +from django.http import HttpRequest from .signals import clean_scss from .util.apps import AppConfig +from .util.core_helpers import has_person class CoreConfig(AppConfig): @@ -29,3 +32,10 @@ class CoreConfig(AppConfig): apps.get_model("otp_yubikey", "ValidationService").objects.using(using).update_or_create( name="default", defaults={"use_ssl": True, "param_sl": "", "param_timeout": ""} ) + + def user_logged_in( + self, sender: type, request: Optional[HttpRequest], user: "User", **kwargs + ) -> None: + if has_person(user): + # Save the associated person to pick up defaults + user.person.save() diff --git a/aleksis/core/models.py b/aleksis/core/models.py index 490d79775..ffb60ae67 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -176,8 +176,6 @@ class Person(ExtensibleModel): return f"{self.first_name} {self.last_name}" def save(self, *args, **kwargs): - super().save(*args, **kwargs) - # Synchronise user fields to linked User object to keep it up to date if self.user: self.user.first_name = self.first_name @@ -185,6 +183,9 @@ class Person(ExtensibleModel): self.user.email = self.email self.user.save() + self.auto_select_primary_group() + super().save(*args, **kwargs) + def __str__(self) -> str: return self.full_name @@ -204,6 +205,21 @@ class Person(ExtensibleModel): person = Person(user=admin) person.save() + def auto_select_primary_group(self, pattern: Optional[str] = None, force: bool = False) -> None: + """ Auto-select the primary group among the groups the person is member of + + Uses either the pattern passed as argument, or the pattern configured system-wide. + + Does not do anything if either no pattern is defined or the user already has + a primary group, unless force is True. + """ + + pattern = pattern or config.PRIMARY_GROUP_PATTERN + + if pattern: + if force or not self.primary_group: + self.primary_group = self.member_of.filter(name__regex=pattern).first() + class Group(ExtensibleModel): """Any kind of group of persons in a school, including, but not limited diff --git a/aleksis/core/util/apps.py b/aleksis/core/util/apps.py index 2e4ab1d0a..7eef538ae 100644 --- a/aleksis/core/util/apps.py +++ b/aleksis/core/util/apps.py @@ -2,7 +2,9 @@ from importlib import import_module from typing import Any, List, Optional, Tuple import django.apps +from django.contrib.auth.signals import user_logged_in, user_logged_out from django.db.models.signals import post_migrate, pre_migrate +from django.http import HttpRequest from constance.signals import config_updated @@ -26,6 +28,8 @@ class AppConfig(django.apps.AppConfig): pre_migrate.connect(self.pre_migrate, sender=self) post_migrate.connect(self.post_migrate, sender=self) config_updated.connect(self.config_updated) + user_logged_in.connect(self.user_logged_in) + user_logged_out.connect(self.user_logged_out) # Getting an app ready means it should look at its config once self.config_updated() @@ -82,6 +86,24 @@ class AppConfig(django.apps.AppConfig): """ self._maintain_default_data() + def user_logged_in( + self, sender: type, request: Optional[HttpRequest], user: "User", **kwargs + ) -> None: + """ Called after a user logged in + + By default, it does nothing. + """ + pass + + def user_logged_out( + self, sender: type, request: Optional[HttpRequest], user: "User", **kwargs + ) -> None: + """ Called after a user logged out + + By default, it does nothing. + """ + pass + def _maintain_default_data(self): if not self.models_module: # This app does not have any models, so bail out early -- GitLab