From b33f13db301da068635b48b5e02597f7a5b75e87 Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Thu, 26 Sep 2024 13:29:36 +0200 Subject: [PATCH] feat(accounts): Add a mechanism to automatically change the local username when creating or deleting translations --- src/dgsi/models.py | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/dgsi/models.py b/src/dgsi/models.py index 32e706d..a851d3e 100644 --- a/src/dgsi/models.py +++ b/src/dgsi/models.py @@ -2,9 +2,12 @@ from dataclasses import dataclass from functools import cached_property from typing import Optional, Self +from allauth.socialaccount.models import SocialAccount from asgiref.sync import async_to_sync from django.contrib.auth.models import AbstractUser from django.db import models +from django.db.models.signals import pre_delete +from django.dispatch import receiver from django.http import HttpRequest from django.utils.translation import gettext_lazy as _ from kanidm.exceptions import NoMatchingEntries @@ -84,17 +87,47 @@ class Translation(models.Model): def __str__(self) -> str: return f"{self.cas_login} → {self.username}" - def save(self, **kwargs) -> None: # pyright: ignore + def save(self, *args, **kwargs) -> None: # INFO: Only update the model if it does not already exist # This will prevent a lot of pain if self.pk is None: - return super().save(**kwargs) + try: + # Find out if a user exists with the cas_login to update + account = SocialAccount.objects.get( + provider="ens_cas", uid=self.cas_login + ) + account.user.username = self.username + account.user.save() + + # TODO: Update the distant kanidm data + except SocialAccount.DoesNotExist: + # No user has registered with this cas_login yet + pass + return super().save(*args, **kwargs) class Meta: # pyright: ignore verbose_name = _("Correspondance de login") verbose_name_plural = _("Correspondances de login") +# INFO: We need to use a signal receiver here, as the delete method is not called +# when deleteing objects from the admin interface +@receiver(pre_delete, sender=Translation) +def restore_username(**kwargs): + """ + Restore the username to the cas_login + """ + + cas_login = kwargs["instance"].cas_login + try: + account = SocialAccount.objects.get(provider="ens_cas", uid=cas_login) + account.user.username = cas_login + account.user.save() + except SocialAccount.DoesNotExist: + # No user has registered with this cas_login yet + pass + + @dataclass class KanidmProfile: person: Person