mirror of
https://github.com/zulip/zulip.git
synced 2025-11-01 04:23:46 +00:00
user_groups: Add "Nobody" system user group.
This commit adds code to create a "Nobody" system user group to realms which will be used in settings to represent "Nobody" option. We also add a migration to add this group to existing realms.
This commit is contained in:
@@ -237,8 +237,15 @@ def create_system_user_groups_for_realm(realm: Realm) -> Dict[int, UserGroup]:
|
||||
realm=realm,
|
||||
is_system_group=True,
|
||||
)
|
||||
nobody_system_group = UserGroup(
|
||||
name=UserGroup.NOBODY_GROUP_NAME,
|
||||
description="Nobody",
|
||||
realm=realm,
|
||||
is_system_group=True,
|
||||
)
|
||||
# Order of this list here is important to create correct GroupGroupMembership objects
|
||||
system_user_groups_list = [
|
||||
nobody_system_group,
|
||||
role_system_groups_dict[UserProfile.ROLE_REALM_OWNER],
|
||||
role_system_groups_dict[UserProfile.ROLE_REALM_ADMINISTRATOR],
|
||||
role_system_groups_dict[UserProfile.ROLE_MODERATOR],
|
||||
@@ -251,7 +258,8 @@ def create_system_user_groups_for_realm(realm: Realm) -> Dict[int, UserGroup]:
|
||||
UserGroup.objects.bulk_create(system_user_groups_list)
|
||||
|
||||
subgroup_objects = []
|
||||
subgroup, remaining_groups = system_user_groups_list[0], system_user_groups_list[1:]
|
||||
# "Nobody" system group is not a subgroup of any user group, since it is already empty.
|
||||
subgroup, remaining_groups = system_user_groups_list[1], system_user_groups_list[2:]
|
||||
for supergroup in remaining_groups:
|
||||
subgroup_objects.append(GroupGroupMembership(subgroup=subgroup, supergroup=supergroup))
|
||||
subgroup = supergroup
|
||||
|
||||
50
zerver/migrations/0434_create_nobody_system_group.py
Normal file
50
zerver/migrations/0434_create_nobody_system_group.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# Generated by Django 4.1.7 on 2023-03-27 03:00
|
||||
|
||||
from django.db import migrations
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
from django.db.migrations.state import StateApps
|
||||
|
||||
|
||||
def create_nobody_system_user_group_for_existing_realms(
|
||||
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||
) -> None:
|
||||
Realm = apps.get_model("zerver", "Realm")
|
||||
UserGroup = apps.get_model("zerver", "UserGroup")
|
||||
NOBODY_GROUP_NAME = "@role:nobody"
|
||||
NOBODY_GROUP_DESCRIPTION = "Nobody"
|
||||
|
||||
groups_to_create = []
|
||||
for realm in Realm.objects.all():
|
||||
groups_to_create.append(
|
||||
UserGroup(
|
||||
name=NOBODY_GROUP_NAME,
|
||||
description=NOBODY_GROUP_DESCRIPTION,
|
||||
realm=realm,
|
||||
is_system_group=True,
|
||||
)
|
||||
)
|
||||
|
||||
UserGroup.objects.bulk_create(groups_to_create)
|
||||
|
||||
|
||||
def delete_nobody_system_user_groups(
|
||||
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
||||
) -> None:
|
||||
UserGroup = apps.get_model("zerver", "UserGroup")
|
||||
NOBODY_GROUP_NAME = "@role:nobody"
|
||||
|
||||
UserGroup.objects.filter(name=NOBODY_GROUP_NAME, is_system_group=True).delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("zerver", "0433_preregistrationrealm"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(
|
||||
create_nobody_system_user_group_for_existing_realms,
|
||||
reverse_code=delete_nobody_system_user_groups,
|
||||
elidable=True,
|
||||
),
|
||||
]
|
||||
@@ -2224,6 +2224,7 @@ class UserGroup(models.Model): # type: ignore[django-manager-missing] # django-
|
||||
MODERATORS_GROUP_NAME = "@role:moderators"
|
||||
MEMBERS_GROUP_NAME = "@role:members"
|
||||
EVERYONE_GROUP_NAME = "@role:everyone"
|
||||
NOBODY_GROUP_NAME = "@role:nobody"
|
||||
|
||||
# We do not have "Full members" and "Everyone on the internet"
|
||||
# group here since there isn't a separate role value for full
|
||||
|
||||
@@ -15293,7 +15293,7 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
example: [8, 9]
|
||||
example: [9, 10]
|
||||
required: false
|
||||
responses:
|
||||
"200":
|
||||
@@ -17605,7 +17605,7 @@ components:
|
||||
The ID of the target user group.
|
||||
schema:
|
||||
type: integer
|
||||
example: 29
|
||||
example: 33
|
||||
required: true
|
||||
QueueId:
|
||||
name: queue_id
|
||||
|
||||
@@ -435,10 +435,10 @@ class RealmImportExportTest(ExportFile):
|
||||
self.assertEqual(exported_realm_user_default[0]["default_language"], "de")
|
||||
|
||||
exported_usergroups = data["zerver_usergroup"]
|
||||
self.assert_length(exported_usergroups, 8)
|
||||
self.assertEqual(exported_usergroups[1]["name"], "@role:administrators")
|
||||
self.assertFalse("direct_members" in exported_usergroups[1])
|
||||
self.assertFalse("direct_subgroups" in exported_usergroups[1])
|
||||
self.assert_length(exported_usergroups, 9)
|
||||
self.assertEqual(exported_usergroups[2]["name"], "@role:administrators")
|
||||
self.assertFalse("direct_members" in exported_usergroups[2])
|
||||
self.assertFalse("direct_subgroups" in exported_usergroups[2])
|
||||
|
||||
data = read_json("messages-000001.json")
|
||||
um = UserMessage.objects.all()[0]
|
||||
|
||||
@@ -977,7 +977,7 @@ class RealmTest(ZulipTestCase):
|
||||
realm = do_create_realm("realm_string_id", "realm name")
|
||||
system_user_groups = UserGroup.objects.filter(realm=realm, is_system_group=True)
|
||||
|
||||
self.assert_length(system_user_groups, 7)
|
||||
self.assert_length(system_user_groups, 8)
|
||||
user_group_names = [group.name for group in system_user_groups]
|
||||
expected_system_group_names = [
|
||||
UserGroup.OWNERS_GROUP_NAME,
|
||||
@@ -987,6 +987,7 @@ class RealmTest(ZulipTestCase):
|
||||
UserGroup.MEMBERS_GROUP_NAME,
|
||||
UserGroup.EVERYONE_GROUP_NAME,
|
||||
UserGroup.EVERYONE_ON_INTERNET_GROUP_NAME,
|
||||
UserGroup.NOBODY_GROUP_NAME,
|
||||
]
|
||||
self.assertEqual(user_group_names.sort(), expected_system_group_names.sort())
|
||||
|
||||
|
||||
@@ -40,30 +40,37 @@ class UserGroupTestCase(ZulipTestCase):
|
||||
realm = get_realm("zulip")
|
||||
user_group = UserGroup.objects.filter(realm=realm).first()
|
||||
assert user_group is not None
|
||||
membership = UserGroupMembership.objects.filter(user_group=user_group).values_list(
|
||||
"user_profile_id", flat=True
|
||||
)
|
||||
empty_user_group = check_add_user_group(realm, "newgroup", [], acting_user=None)
|
||||
|
||||
user_groups = user_groups_in_realm_serialized(realm)
|
||||
self.assert_length(user_groups, 9)
|
||||
self.assert_length(user_groups, 10)
|
||||
self.assertEqual(user_groups[0]["id"], user_group.id)
|
||||
self.assertEqual(user_groups[0]["name"], UserGroup.OWNERS_GROUP_NAME)
|
||||
self.assertEqual(user_groups[0]["description"], "Owners of this organization")
|
||||
self.assertEqual(set(user_groups[0]["members"]), set(membership))
|
||||
self.assertEqual(user_groups[0]["name"], UserGroup.NOBODY_GROUP_NAME)
|
||||
self.assertEqual(user_groups[0]["description"], "Nobody")
|
||||
self.assertEqual(user_groups[0]["members"], [])
|
||||
self.assertEqual(user_groups[0]["direct_subgroup_ids"], [])
|
||||
|
||||
owners_system_group = UserGroup.objects.get(name=UserGroup.OWNERS_GROUP_NAME, realm=realm)
|
||||
membership = UserGroupMembership.objects.filter(user_group=owners_system_group).values_list(
|
||||
"user_profile_id", flat=True
|
||||
)
|
||||
self.assertEqual(user_groups[1]["id"], owners_system_group.id)
|
||||
self.assertEqual(user_groups[1]["name"], UserGroup.OWNERS_GROUP_NAME)
|
||||
self.assertEqual(user_groups[1]["description"], "Owners of this organization")
|
||||
self.assertEqual(set(user_groups[1]["members"]), set(membership))
|
||||
self.assertEqual(user_groups[1]["direct_subgroup_ids"], [])
|
||||
|
||||
admins_system_group = UserGroup.objects.get(
|
||||
name=UserGroup.ADMINISTRATORS_GROUP_NAME, realm=realm
|
||||
)
|
||||
self.assertEqual(user_groups[1]["id"], admins_system_group.id)
|
||||
self.assertEqual(user_groups[2]["id"], admins_system_group.id)
|
||||
# Check that owners system group is present in "direct_subgroup_ids"
|
||||
self.assertEqual(user_groups[1]["direct_subgroup_ids"], [user_group.id])
|
||||
self.assertEqual(user_groups[2]["direct_subgroup_ids"], [owners_system_group.id])
|
||||
|
||||
self.assertEqual(user_groups[8]["id"], empty_user_group.id)
|
||||
self.assertEqual(user_groups[8]["name"], "newgroup")
|
||||
self.assertEqual(user_groups[8]["description"], "")
|
||||
self.assertEqual(user_groups[8]["members"], [])
|
||||
self.assertEqual(user_groups[9]["id"], empty_user_group.id)
|
||||
self.assertEqual(user_groups[9]["name"], "newgroup")
|
||||
self.assertEqual(user_groups[9]["description"], "")
|
||||
self.assertEqual(user_groups[9]["members"], [])
|
||||
|
||||
def test_get_direct_user_groups(self) -> None:
|
||||
othello = self.example_user("othello")
|
||||
@@ -221,7 +228,7 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
}
|
||||
result = self.client_post("/json/user_groups/create", info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 9)
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 10)
|
||||
|
||||
# Test invalid member error
|
||||
params = {
|
||||
@@ -231,7 +238,7 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
}
|
||||
result = self.client_post("/json/user_groups/create", info=params)
|
||||
self.assert_json_error(result, "Invalid user ID: 1111")
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 9)
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 10)
|
||||
|
||||
# Test we cannot create group with same name again
|
||||
params = {
|
||||
@@ -241,7 +248,7 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
}
|
||||
result = self.client_post("/json/user_groups/create", info=params)
|
||||
self.assert_json_error(result, "User group 'support' already exists.")
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 9)
|
||||
self.assert_length(UserGroup.objects.filter(realm=hamlet.realm), 10)
|
||||
|
||||
def test_user_group_get(self) -> None:
|
||||
# Test success
|
||||
@@ -323,11 +330,11 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
self.client_post("/json/user_groups/create", info=params)
|
||||
user_group = UserGroup.objects.get(name="support")
|
||||
# Test success
|
||||
self.assertEqual(UserGroup.objects.filter(realm=hamlet.realm).count(), 9)
|
||||
self.assertEqual(UserGroup.objects.filter(realm=hamlet.realm).count(), 10)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 47)
|
||||
result = self.client_delete(f"/json/user_groups/{user_group.id}")
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroup.objects.filter(realm=hamlet.realm).count(), 8)
|
||||
self.assertEqual(UserGroup.objects.filter(realm=hamlet.realm).count(), 9)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 46)
|
||||
# Test when invalid user group is supplied
|
||||
result = self.client_delete("/json/user_groups/1111")
|
||||
@@ -456,7 +463,7 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
if error_msg is None:
|
||||
self.assert_json_success(result)
|
||||
# One group already exists in the test database.
|
||||
self.assert_length(UserGroup.objects.filter(realm=realm), 9)
|
||||
self.assert_length(UserGroup.objects.filter(realm=realm), 10)
|
||||
else:
|
||||
self.assert_json_error(result, error_msg)
|
||||
|
||||
@@ -466,7 +473,7 @@ class UserGroupAPITestCase(UserGroupTestCase):
|
||||
result = self.client_delete(f"/json/user_groups/{user_group.id}")
|
||||
if error_msg is None:
|
||||
self.assert_json_success(result)
|
||||
self.assert_length(UserGroup.objects.filter(realm=realm), 8)
|
||||
self.assert_length(UserGroup.objects.filter(realm=realm), 9)
|
||||
else:
|
||||
self.assert_json_error(result, error_msg)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user