2022-01-12 12:56:22 +01:00
|
|
|
"""
|
|
|
|
Author: Michel Peltriaux
|
|
|
|
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
|
|
|
|
Contact: michel.peltriaux@sgdnord.rlp.de
|
|
|
|
Created on: 15.11.21
|
|
|
|
|
|
|
|
"""
|
|
|
|
from django.contrib.auth.models import AbstractUser
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
|
2024-04-30 14:56:48 +02:00
|
|
|
from api.models import APIUserToken, OAuthToken
|
2022-01-25 09:29:14 +01:00
|
|
|
from konova.settings import ZB_GROUP, DEFAULT_GROUP, ETS_GROUP
|
2022-01-12 12:56:22 +01:00
|
|
|
from konova.utils.mailer import Mailer
|
2022-01-12 14:51:50 +01:00
|
|
|
from user.enums import UserNotificationEnum
|
2022-01-12 12:56:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
class User(AbstractUser):
|
|
|
|
notifications = models.ManyToManyField("user.UserNotification", related_name="+", blank=True)
|
2022-01-21 15:26:08 +01:00
|
|
|
api_token = models.OneToOneField(
|
|
|
|
"api.APIUserToken",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
help_text="The user's API token",
|
|
|
|
on_delete=models.SET_NULL
|
|
|
|
)
|
2024-04-30 14:56:48 +02:00
|
|
|
oauth_token = models.ForeignKey(
|
|
|
|
"api.OAuthToken",
|
|
|
|
blank=True,
|
|
|
|
null=True,
|
|
|
|
on_delete=models.SET_NULL,
|
|
|
|
db_comment="OAuth token for the user",
|
|
|
|
related_name="+"
|
|
|
|
)
|
2022-01-12 12:56:22 +01:00
|
|
|
|
2022-01-12 14:51:50 +01:00
|
|
|
def is_notification_setting_set(self, notification_enum: UserNotificationEnum):
|
|
|
|
return self.notifications.filter(
|
|
|
|
id=notification_enum.value
|
|
|
|
).exists()
|
|
|
|
|
2022-01-25 09:29:14 +01:00
|
|
|
def is_zb_user(self):
|
|
|
|
""" Shortcut for checking whether a user is of a special group or not
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
bool
|
|
|
|
"""
|
|
|
|
return self.groups.filter(
|
|
|
|
name=ZB_GROUP
|
|
|
|
).exists()
|
|
|
|
|
|
|
|
def is_default_user(self):
|
|
|
|
""" Shortcut for checking whether a user is of a special group or not
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
bool
|
|
|
|
"""
|
|
|
|
return self.groups.filter(
|
|
|
|
name=DEFAULT_GROUP
|
|
|
|
).exists()
|
|
|
|
|
|
|
|
def is_ets_user(self):
|
|
|
|
""" Shortcut for checking whether a user is of a special group or not
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
bool
|
|
|
|
"""
|
|
|
|
return self.groups.filter(
|
|
|
|
name=ETS_GROUP
|
|
|
|
).exists()
|
|
|
|
|
2023-09-13 09:49:40 +02:00
|
|
|
def is_default_group_only(self) -> bool:
|
|
|
|
""" Checks if the user is only part of the default group
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
bool
|
|
|
|
"""
|
|
|
|
return not self.in_group(ZB_GROUP) and not self.in_group(ETS_GROUP)
|
|
|
|
|
|
|
|
def in_group(self, group: str) -> bool:
|
|
|
|
""" Checks if the user is part of a group
|
|
|
|
|
|
|
|
Args:
|
|
|
|
group (str): The group's name
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
bool
|
|
|
|
"""
|
|
|
|
return self.groups.filter(
|
|
|
|
name=group
|
|
|
|
)
|
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_access_removed(self, obj, municipals_names):
|
2022-01-12 12:56:22 +01:00
|
|
|
""" Sends a mail to the user in case of removed shared access
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj ():
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names ():
|
2022-01-12 12:56:22 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
2022-01-12 14:51:50 +01:00
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_REMOVED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_access_removed(obj, self, municipals_names)
|
2022-01-12 14:51:50 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_access_given(self, obj, municipals_names):
|
2022-01-12 15:09:52 +01:00
|
|
|
""" Sends a mail to the user in case of given shared access
|
2022-01-12 14:51:50 +01:00
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The entry
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names (iterable): List of municipals for this entry
|
2022-01-12 14:51:50 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_GAINED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_access_given(obj, self, municipals_names)
|
2022-01-12 15:09:52 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_data_recorded(self, obj, municipals_names):
|
2022-01-12 15:09:52 +01:00
|
|
|
""" Sends a mail to the user in case of shared data has been recorded
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The entry
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names (iterable): List of municipals for this entry
|
2022-01-12 15:09:52 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_data_recorded(obj, self, municipals_names)
|
2022-01-12 15:09:52 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_data_unrecorded(self, obj, municipals_names):
|
2022-01-12 15:09:52 +01:00
|
|
|
""" Sends a mail to the user in case of shared data has been unrecorded
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The entry
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names (iterable): List of municipals for this entry
|
2022-01-12 15:09:52 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_data_unrecorded(obj, self, municipals_names)
|
2022-01-12 15:31:25 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_data_deleted(self, obj, municipals_names):
|
2022-01-12 15:31:25 +01:00
|
|
|
""" Sends a mail to the user in case of shared data has been deleted
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The entry
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names (iterable): List of municipals for this entry
|
2022-01-12 15:31:25 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_DELETED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_data_deleted(obj, self, municipals_names)
|
2022-01-12 15:48:47 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_shared_data_checked(self, obj, municipals_names):
|
2022-01-12 15:48:47 +01:00
|
|
|
""" Sends a mail to the user in case of shared data has been deleted
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The entry
|
2023-02-23 10:17:45 +01:00
|
|
|
municipals_names (iterable): List of municipals for this entry
|
2022-01-12 15:48:47 +01:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_CHECKED)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_shared_data_checked(obj, self, municipals_names)
|
2022-01-27 11:37:38 +01:00
|
|
|
|
2023-12-11 12:06:33 +01:00
|
|
|
def send_mail_deduction_changed(self, obj, data_changes):
|
2022-08-10 08:59:24 +02:00
|
|
|
""" Sends a mail to the user in case of a changed deduction
|
|
|
|
|
|
|
|
Args:
|
2023-12-11 12:06:33 +01:00
|
|
|
obj (): The object
|
2022-08-10 08:59:24 +02:00
|
|
|
data_changes (dict): Contains the old|new changes of the deduction changes
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_DEDUCTION_CHANGES)
|
|
|
|
if notification_set:
|
|
|
|
mailer = Mailer()
|
2023-12-11 12:06:33 +01:00
|
|
|
mailer.send_mail_deduction_changed(obj, self, data_changes)
|
2022-08-10 08:59:24 +02:00
|
|
|
|
2022-01-27 11:37:38 +01:00
|
|
|
def get_API_token(self):
|
|
|
|
""" Getter for an API token
|
|
|
|
|
|
|
|
Creates a new one if none exists, yet.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
token (APIUserToken)
|
|
|
|
"""
|
|
|
|
if self.api_token is None:
|
|
|
|
token = APIUserToken.objects.create()
|
|
|
|
self.api_token = token
|
|
|
|
self.save()
|
|
|
|
else:
|
|
|
|
token = self.api_token
|
|
|
|
return token
|
2022-05-30 15:38:16 +02:00
|
|
|
|
|
|
|
@property
|
|
|
|
def shared_teams(self):
|
|
|
|
""" Wrapper for fetching active teams of this user
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
|
|
"""
|
|
|
|
shared_teams = self.teams.filter(
|
|
|
|
deleted__isnull=True
|
|
|
|
)
|
2024-04-29 12:07:06 +02:00
|
|
|
return shared_teams
|
|
|
|
|
|
|
|
@staticmethod
|
2024-04-30 14:56:48 +02:00
|
|
|
def oauth_update_user(user_data: dict):
|
|
|
|
"""
|
|
|
|
Get or create a user depending on given user_data.
|
|
|
|
If the user record already exists, it's data will be updated using user_data.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
user_data (dict): User data from OAuth SSO component
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
user (User): The resolved user
|
|
|
|
"""
|
2024-04-29 12:07:06 +02:00
|
|
|
username = user_data.get("username")
|
|
|
|
user, is_created = User.objects.get_or_create(
|
|
|
|
username=username
|
|
|
|
)
|
2024-04-30 14:56:48 +02:00
|
|
|
|
2024-04-29 12:07:06 +02:00
|
|
|
if is_created:
|
|
|
|
user.set_unusable_password()
|
|
|
|
|
|
|
|
user.first_name = user_data.get("first_name")
|
|
|
|
user.last_name = user_data.get("last_name")
|
|
|
|
user.email = user_data.get("email")
|
|
|
|
|
|
|
|
return user
|
|
|
|
|
2024-04-30 14:56:48 +02:00
|
|
|
def oauth_replace_token(self, token: OAuthToken):
|
|
|
|
"""
|
|
|
|
Drops old token (if existing) and stores given token.
|
2024-04-29 12:07:06 +02:00
|
|
|
|
2024-04-30 14:56:48 +02:00
|
|
|
Args:
|
|
|
|
token (OAuthToken): New token
|
2024-04-29 12:07:06 +02:00
|
|
|
|
2024-04-30 14:56:48 +02:00
|
|
|
Returns:
|
|
|
|
user (User)
|
|
|
|
"""
|
|
|
|
if self.oauth_token:
|
|
|
|
self.oauth_token.delete()
|
|
|
|
self.oauth_token = token
|
|
|
|
self.save()
|
|
|
|
return self
|