diff options
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r-- | ishtar_common/models.py | 113 |
1 files changed, 106 insertions, 7 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 1569c97c9..045bab1cc 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -54,7 +54,7 @@ from xml.etree import ElementTree as ET # nosec from django.apps import apps from django.conf import settings -from django.contrib.auth.models import User, Group +from django.contrib.auth.models import User, Group, Permission from django.contrib.contenttypes.models import ContentType from django.contrib.gis.db import models from django.contrib.gis.db.models.aggregates import Union @@ -73,7 +73,7 @@ from django.core.files.base import ContentFile from django.core.files.uploadedfile import SimpleUploadedFile from django.db import connection, transaction from django.db.models import Q, Max, Count -from django.db.models.signals import post_save, post_delete, m2m_changed +from django.db.models.signals import post_save, post_delete, pre_delete, m2m_changed from django.db.utils import DatabaseError from django.template import Context, Template from django.template.defaultfilters import slugify @@ -3453,11 +3453,65 @@ class ProfileType(GeneralType): ordering = ("label",) ADMIN_SECTION = _("Account") + def clean_groups(self): + """ + Remove "own" groups if generic group is associated + """ + owns, full = {}, [] + # get all permissions + for group in self.groups.all(): + permissions = [] + own, gen = False, False + q = group.permissions + if not q.count(): + continue + for permission in q.all(): + if "_own_" in permission.codename: + own = True + else: + gen = True + parts = permission.codename.split("_") + permissions.append(f"{parts[0]}_{parts[-1]}") + if own and gen: + # group has "own" and "generic" permissions: do nothing + continue + permissions = tuple(sorted(permissions)) + if own: + owns[permissions] = group + else: + full.append(permissions) + # clean + for permissions in owns.keys(): + if len(permissions) == 1: + for full_permissions in full: + for full_permission in full_permissions: + if full_permission == permissions[0]: + self.groups.remove(owns[permissions]) + break + else: + if permissions in full: + self.groups.remove(owns[permissions]) + post_save.connect(post_save_cache, sender=ProfileType) post_delete.connect(post_save_cache, sender=ProfileType) +def permission_requests_changed(sender, **kwargs): + instance = kwargs.get("instance", None) + if not instance: + return + IshtarUser.objects.filter( + person__profiles__profile_type_id=instance.id + ).update(need_permission_update=True) + + +m2m_changed.connect(permission_requests_changed, + sender=ProfileType.permission_requests.through) +m2m_changed.connect(permission_requests_changed, + sender=ProfileType.groups.through) + + class ProfileTypeSummary(ProfileType): class Meta: proxy = True @@ -3567,12 +3621,14 @@ class UserProfile(models.Model): item_ids += list( Find.objects.filter(**{k: ishtar_user}).values_list("pk", flat=True) ) - print("ishtar_common/models.py - 3561", item_ids, ishtar_user, content_type, permission_type) + # DEBUG + # print("ishtar_common/models.py - 3578", item_ids, ishtar_user, content_type, permission_type) if permission_request.include_upstream_items: item_ids += model_class.get_ids_from_upper_permissions( ishtar_user.user_ptr.pk, permissions ) - print("ishtar_common/models.py - 3566", item_ids, ishtar_user, content_type, permission_type) + # DEBUG + # print("ishtar_common/models.py - 3584", item_ids, ishtar_user, content_type, permission_type) if permission_request.request or permission_request.limit_to_attached_areas: _get_item = get_item( content_type.model_class(), @@ -3606,7 +3662,8 @@ class UserProfile(models.Model): else: result = result_limit item_ids += result - print("ishtar_common/models.py - 3600", item_ids, ishtar_user, content_type, permission_type) + # DEBUG + # print("ishtar_common/models.py - 3619", item_ids, ishtar_user, content_type, permission_type) return item_ids def generate_permission(self, content_type, permission_type, @@ -3643,8 +3700,9 @@ class UserProfile(models.Model): item_ids = [] if not q_req.count(): # TODO v5: delete old behaviour - print(f"WARNING: no permission request for content {content_type.name} and profile {self}") - print("Using old behaviour") + # DEBUG + # print(f"WARNING: no permission request for content {content_type.name} and profile {self}") + # print("Using old behaviour") model_class = content_type.model_class() query = model_class.get_owns(user=ishtar_user, query=True, no_auth_check=True) if query: @@ -3711,6 +3769,9 @@ def post_save_userprofile(sender, **kwargs): if not kwargs.get("instance"): return instance = kwargs.get("instance") + IshtarUser.objects.filter( + person__profiles__pk=instance.id + ).update(need_permission_update=True) try: instance.person.ishtaruser.show_field_number(update=True) except IshtarUser.DoesNotExist: @@ -3720,6 +3781,18 @@ def post_save_userprofile(sender, **kwargs): post_save.connect(post_save_userprofile, sender=UserProfile) +def pre_delete_user_profile(sender, **kwargs): + instance = kwargs.get("instance", None) + if not instance: + return + IshtarUser.objects.filter( + person__profiles__pk=instance.id + ).update(need_permission_update=True) + + +pre_delete.connect(pre_delete_user_profile, sender=UserProfile) + + TASK_STATE = ( ("S", _("Scheduled")), ("P", _("In progress")), @@ -3837,6 +3910,9 @@ class IshtarUser(FullSearch): blank=True, max_length=20) display_news = models.BooleanField(_("Display news"), default=True) display_forum_entries = models.BooleanField(_("Display forum entries"), default=True) + # permissions update + need_permission_update = models.BooleanField(_("Need permission update"), + default=True) class Meta: verbose_name = _("Ishtar user") @@ -3929,6 +4005,26 @@ class IshtarUser(FullSearch): return self.user_ptr.has_perm(permission, obj) return self.user_ptr.has_perm(permission) + def need_permission_refresh(self): + if self.need_permission_update: + return True + q = UserProfile.objects.filter( + person_id=self.person_id, + expiration_date__lt=datetime.date.today() + ) + if q.count(): + self.need_permission_update = True + self.save() + return True + q = Permission.objects.filter( + group__profile_types__user_profiles__person__ishtaruser__pk=self.pk, + codename__contains="_own_", + ) + if q.count(): + self.need_permission_update = True + self.save() + return bool(q.count()) + def generate_permission(self): # models to treat first in this order to manage cascade permissions model_names = [ @@ -3971,6 +4067,9 @@ class IshtarUser(FullSearch): for permission_type in ("view", "change", "delete"): profile.generate_permission(ct, permission_type) + self.need_permission_update = False + self.save() + def has_permission_dict(self): """ Get permission dict with permission codename as key and True or False as result. |