groups: Update subgroup to be NamedUserGroup.

This commit is contained in:
Sahil Batra 2024-04-20 20:33:33 +05:30 committed by Tim Abbott
parent dfeb896107
commit 85b7dbddbc
4 changed files with 46 additions and 19 deletions

View File

@ -325,21 +325,25 @@ def get_recursive_subgroups(user_group: UserGroup) -> QuerySet[UserGroup]:
cte = With.recursive( cte = With.recursive(
lambda cte: UserGroup.objects.filter(id=user_group.id) lambda cte: UserGroup.objects.filter(id=user_group.id)
.values(group_id=F("id")) .values(group_id=F("id"))
.union(cte.join(UserGroup, direct_supergroups=cte.col.group_id).values(group_id=F("id"))) .union(
cte.join(NamedUserGroup, direct_supergroups=cte.col.group_id).values(group_id=F("id"))
)
) )
return cte.join(UserGroup, id=cte.col.group_id).with_cte(cte) return cte.join(UserGroup, id=cte.col.group_id).with_cte(cte)
def get_recursive_strict_subgroups(user_group: UserGroup) -> QuerySet[UserGroup]: def get_recursive_strict_subgroups(user_group: UserGroup) -> QuerySet[NamedUserGroup]:
# Same as get_recursive_subgroups but does not include the # Same as get_recursive_subgroups but does not include the
# user_group passed. # user_group passed.
direct_subgroup_ids = user_group.direct_subgroups.all().values("id") direct_subgroup_ids = user_group.direct_subgroups.all().values("id")
cte = With.recursive( cte = With.recursive(
lambda cte: UserGroup.objects.filter(id__in=direct_subgroup_ids) lambda cte: NamedUserGroup.objects.filter(id__in=direct_subgroup_ids)
.values(group_id=F("id")) .values(group_id=F("id"))
.union(cte.join(UserGroup, direct_supergroups=cte.col.group_id).values(group_id=F("id"))) .union(
cte.join(NamedUserGroup, direct_supergroups=cte.col.group_id).values(group_id=F("id"))
)
) )
return cte.join(UserGroup, id=cte.col.group_id).with_cte(cte) return cte.join(NamedUserGroup, id=cte.col.group_id).with_cte(cte)
def get_recursive_group_members(user_group: UserGroup) -> QuerySet[UserProfile]: def get_recursive_group_members(user_group: UserGroup) -> QuerySet[UserProfile]:

View File

@ -24,4 +24,22 @@ class Migration(migrations.Migration):
null=True, on_delete=django.db.models.deletion.CASCADE, to="zerver.namedusergroup" null=True, on_delete=django.db.models.deletion.CASCADE, to="zerver.namedusergroup"
), ),
), ),
migrations.AlterField(
model_name="groupgroupmembership",
name="subgroup",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="+",
to="zerver.namedusergroup",
),
),
migrations.AlterField(
model_name="usergroup",
name="direct_subgroups",
field=models.ManyToManyField(
related_name="direct_supergroups",
through="zerver.GroupGroupMembership",
to="zerver.namedusergroup",
),
),
] ]

View File

@ -27,7 +27,7 @@ class UserGroup(models.Model): # type: ignore[django-manager-missing] # django-
UserProfile, through="zerver.UserGroupMembership", related_name="direct_groups" UserProfile, through="zerver.UserGroupMembership", related_name="direct_groups"
) )
direct_subgroups = models.ManyToManyField( direct_subgroups = models.ManyToManyField(
"self", "zerver.NamedUserGroup",
symmetrical=False, symmetrical=False,
through="zerver.GroupGroupMembership", through="zerver.GroupGroupMembership",
through_fields=("supergroup", "subgroup"), through_fields=("supergroup", "subgroup"),
@ -123,7 +123,7 @@ class UserGroupMembership(models.Model):
class GroupGroupMembership(models.Model): class GroupGroupMembership(models.Model):
supergroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+") supergroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
subgroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+") subgroup = models.ForeignKey(NamedUserGroup, on_delete=CASCADE, related_name="+")
class Meta: class Meta:
constraints = [ constraints = [

View File

@ -33,7 +33,14 @@ from zerver.lib.user_groups import (
is_user_in_group, is_user_in_group,
user_groups_in_realm_serialized, user_groups_in_realm_serialized,
) )
from zerver.models import GroupGroupMembership, Realm, UserGroup, UserGroupMembership, UserProfile from zerver.models import (
GroupGroupMembership,
NamedUserGroup,
Realm,
UserGroup,
UserGroupMembership,
UserProfile,
)
from zerver.models.groups import SystemGroups from zerver.models.groups import SystemGroups
from zerver.models.realms import get_realm from zerver.models.realms import get_realm
@ -130,12 +137,10 @@ class UserGroupTestCase(ZulipTestCase):
) )
self.assertCountEqual(list(get_recursive_strict_subgroups(leadership_group)), []) self.assertCountEqual(list(get_recursive_strict_subgroups(leadership_group)), [])
self.assertCountEqual( self.assertCountEqual(list(get_recursive_strict_subgroups(staff_group)), [leadership_group])
list(get_recursive_strict_subgroups(staff_group)), [leadership_group.usergroup_ptr]
)
self.assertCountEqual( self.assertCountEqual(
list(get_recursive_strict_subgroups(everyone_group)), list(get_recursive_strict_subgroups(everyone_group)),
[leadership_group.usergroup_ptr, staff_group.usergroup_ptr], [leadership_group, staff_group],
) )
self.assertCountEqual(list(get_recursive_group_members(leadership_group)), [desdemona]) self.assertCountEqual(list(get_recursive_group_members(leadership_group)), [desdemona])
@ -155,25 +160,25 @@ class UserGroupTestCase(ZulipTestCase):
def test_subgroups_of_role_based_system_groups(self) -> None: def test_subgroups_of_role_based_system_groups(self) -> None:
realm = get_realm("zulip") realm = get_realm("zulip")
owners_group = UserGroup.objects.get( owners_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.OWNERS, is_system_group=True realm=realm, name=SystemGroups.OWNERS, is_system_group=True
) )
admins_group = UserGroup.objects.get( admins_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.ADMINISTRATORS, is_system_group=True realm=realm, name=SystemGroups.ADMINISTRATORS, is_system_group=True
) )
moderators_group = UserGroup.objects.get( moderators_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.MODERATORS, is_system_group=True realm=realm, name=SystemGroups.MODERATORS, is_system_group=True
) )
full_members_group = UserGroup.objects.get( full_members_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.FULL_MEMBERS, is_system_group=True realm=realm, name=SystemGroups.FULL_MEMBERS, is_system_group=True
) )
members_group = UserGroup.objects.get( members_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.MEMBERS, is_system_group=True realm=realm, name=SystemGroups.MEMBERS, is_system_group=True
) )
everyone_group = UserGroup.objects.get( everyone_group = NamedUserGroup.objects.get(
realm=realm, name=SystemGroups.EVERYONE, is_system_group=True realm=realm, name=SystemGroups.EVERYONE, is_system_group=True
) )
everyone_on_internet_group = UserGroup.objects.get( everyone_on_internet_group = NamedUserGroup.objects.get(
realm=realm, realm=realm,
name=SystemGroups.EVERYONE_ON_INTERNET, name=SystemGroups.EVERYONE_ON_INTERNET,
is_system_group=True, is_system_group=True,