Skip to content

Commit 9435b23

Browse files
committed
feat(permission groups): added automatic assigning of is_staff flag
1 parent 62a756e commit 9435b23

File tree

4 files changed

+84
-16
lines changed

4 files changed

+84
-16
lines changed

symfexit/adminsite/management/commands/create_permission_groups.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ def handle(self, *args, **options):
1111
code=WellKnownPermissionGroup.WellKnownPermissionGroups.VIEW_ALL
1212
)
1313
group_ref.update_permissions()
14+
group_ref = WellKnownPermissionGroup.get_or_create(
15+
code=WellKnownPermissionGroup.WellKnownPermissionGroups.CONTACT_PERSON
16+
)
17+
group_ref.update_permissions()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 5.2.7 on 2025-11-09 23:34
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('adminsite', '0003_groupflags'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='wellknownpermissiongroup',
15+
name='code',
16+
field=models.CharField(choices=[('view_all', 'View all'), ('contact_person', 'Contact person')], max_length=255, unique=True),
17+
),
18+
]

symfexit/adminsite/models.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from django.contrib.auth.models import Group, Permission
2-
from django.db import IntegrityError, models
2+
from django.db import IntegrityError, models, transaction
3+
from django.db.models.signals import post_delete, post_save
4+
from django.dispatch import receiver
35

46

57
class WellKnownPermissionGroup(models.Model):
68
class WellKnownPermissionGroups(models.TextChoices):
79
VIEW_ALL = "view_all", "View all"
10+
CONTACT_PERSON = "contact_person", "Contact person"
811

912
code = models.CharField(
1013
unique=True,
@@ -50,6 +53,25 @@ def update_permissions(self):
5053
Permission.objects.get(codename="view_membershipapplication"),
5154
]
5255
)
56+
try:
57+
flags = self.group.flags
58+
except GroupFlags.DoesNotExist:
59+
flags = GroupFlags(group=self.group)
60+
flags.members_become_staff = True
61+
62+
case WellKnownPermissionGroup.WellKnownPermissionGroups.CONTACT_PERSON:
63+
self.group.permissions.set(
64+
[
65+
Permission.objects.get(codename="view_membership"),
66+
Permission.objects.get(codename="view_member"),
67+
Permission.objects.get(codename="change_member"),
68+
]
69+
)
70+
try:
71+
flags = self.group.flags
72+
except GroupFlags.DoesNotExist:
73+
flags = GroupFlags(group=self.group)
74+
flags.members_become_staff = True
5375

5476

5577
class GroupFlags(models.Model):
@@ -64,3 +86,15 @@ class GroupFlags(models.Model):
6486

6587
def __str__(self):
6688
return f"Flags for group {self.group}"
89+
90+
91+
def reset_user_staff(group: Group):
92+
for user in group.user_set.all():
93+
user.set_staff_rights()
94+
user.save()
95+
96+
97+
@receiver(post_save, sender=GroupFlags)
98+
@receiver(post_delete, sender=GroupFlags)
99+
def on_group_change(sender, instance: GroupFlags, **kwargs):
100+
transaction.on_commit(lambda: reset_user_staff(instance.group))

symfexit/members/models.py

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from django.utils import timezone
99
from django.utils.translation import gettext_lazy as _
1010

11+
from symfexit.adminsite.models import GroupFlags, WellKnownPermissionGroup
12+
1113

1214
def generate_member_number():
1315
largest_member_number = User.objects.all().order_by("-member_identifier").first()
@@ -133,18 +135,26 @@ def email_user(self, subject, message, from_email=None, **kwargs):
133135
send_mail(subject, message, from_email, [self.email], **kwargs)
134136

135137
def set_staff_rights(self) -> bool:
136-
if self.is_superuser:
137-
# This should already be set to True
138-
self.is_staff = True
139-
return True
140-
141-
# Staff via group permission
142-
staff_via_group = self.groups.filter(flags__members_become_staff=True).exists()
143-
144-
# Staff via being contact person
145-
staff_via_localgroup = self.contact_person_for_groups.count() >= 1
146-
147-
self.is_staff = staff_via_group or staff_via_localgroup
138+
# Add/remove user to contact person permission group
139+
contact_person_group = WellKnownPermissionGroup.get_or_create(
140+
WellKnownPermissionGroup.WellKnownPermissionGroups.CONTACT_PERSON
141+
)
142+
is_contact_person = self.contact_person_for_groups.count() >= 1
143+
if is_contact_person:
144+
contact_person_group.group.user_set.add(self)
145+
else:
146+
contact_person_group.group.user_set.remove(self)
147+
148+
# set user as staff, if any group requires it
149+
for group in self.groups.all():
150+
try:
151+
if group.flags.members_become_staff:
152+
self.is_staff = True
153+
break
154+
except GroupFlags.DoesNotExist:
155+
pass
156+
else:
157+
self.is_staff = False
148158
return self.is_staff
149159

150160

@@ -170,7 +180,7 @@ def __str__(self):
170180
# START Signals for is_staff updating
171181

172182

173-
def update_user_staff_rights(users):
183+
def update_user_staff_rights(users: list[User]):
174184
for user in users:
175185
user.set_staff_rights()
176186
User.objects.bulk_update(users, ["is_staff"])
@@ -181,8 +191,10 @@ def user_groups_changed(sender, instance, action, pk_set, **kwargs):
181191
if action not in ["post_add", "post_remove", "post_clear"]:
182192
return
183193

184-
# instance is the user being modified
185-
update_user_staff_rights([instance])
194+
# Ensure instance is a User object and not a group
195+
if isinstance(instance, User):
196+
# Call your function to update user rights
197+
update_user_staff_rights([instance])
186198

187199

188200
@receiver(m2m_changed, sender=LocalGroup.contact_people.through)

0 commit comments

Comments
 (0)