user_groups: Audit UserGroup creation.

We also create RealmAuditLog entries for the initial memberships that
get added along with the creation of a UserGroup. System user groups are
not created with members so no audit logs are populated for that.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
Zixuan James Li 2022-11-20 20:43:03 -08:00 committed by Tim Abbott
parent 71de14ab43
commit 63f5936207
4 changed files with 104 additions and 1 deletions

View File

@ -15,6 +15,7 @@ from zerver.lib.user_groups import (
from zerver.models import (
GroupGroupMembership,
Realm,
RealmAuditLog,
UserGroup,
UserGroupMembership,
UserProfile,
@ -56,6 +57,28 @@ def create_user_group_in_database(
UserGroupMembership.objects.bulk_create(
UserGroupMembership(user_profile=member, user_group=user_group) for member in members
)
creation_time = timezone_now()
audit_log_entries = [
RealmAuditLog(
realm=realm,
acting_user=acting_user,
event_type=RealmAuditLog.USER_GROUP_CREATED,
event_time=creation_time,
modified_user_group=user_group,
)
] + [
RealmAuditLog(
realm=realm,
acting_user=acting_user,
event_type=RealmAuditLog.USER_GROUP_DIRECT_USER_MEMBERSHIP_ADDED,
event_time=creation_time,
modified_user=member,
modified_user_group=user_group,
)
for member in members
]
RealmAuditLog.objects.bulk_create(audit_log_entries)
return user_group

View File

@ -2,12 +2,20 @@ from typing import Dict, Iterable, List, Mapping, Sequence, TypedDict
from django.db import transaction
from django.db.models import F, QuerySet
from django.utils.timezone import now as timezone_now
from django.utils.translation import gettext as _
from django_cte import With
from django_stubs_ext import ValuesQuerySet
from zerver.lib.exceptions import JsonableError
from zerver.models import GroupGroupMembership, Realm, UserGroup, UserGroupMembership, UserProfile
from zerver.models import (
GroupGroupMembership,
Realm,
RealmAuditLog,
UserGroup,
UserGroupMembership,
UserProfile,
)
class UserGroupDict(TypedDict):
@ -316,7 +324,18 @@ def create_system_user_groups_for_realm(realm: Realm) -> Dict[int, UserGroup]:
everyone_on_internet_system_group,
]
creation_time = timezone_now()
UserGroup.objects.bulk_create(system_user_groups_list)
RealmAuditLog.objects.bulk_create(
RealmAuditLog(
realm=realm,
acting_user=None,
event_type=RealmAuditLog.USER_GROUP_CREATED,
event_time=creation_time,
modified_user_group=user_group,
)
for user_group in system_user_groups_list
)
groups_with_updated_settings = []
system_groups_name_dict = get_role_based_system_groups_dict(realm)

View File

@ -45,6 +45,7 @@ from zerver.actions.streams import (
do_deactivate_stream,
do_rename_stream,
)
from zerver.actions.user_groups import check_add_user_group
from zerver.actions.user_settings import (
do_change_avatar_fields,
do_change_password,
@ -61,6 +62,7 @@ from zerver.lib.streams import create_stream_if_needed
from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.test_helpers import get_test_image_file
from zerver.lib.types import LinkifierDict, RealmPlaygroundDict
from zerver.lib.user_groups import create_system_user_groups_for_realm
from zerver.lib.utils import assert_is_not_none
from zerver.models import (
EmojiInfo,
@ -71,6 +73,7 @@ from zerver.models import (
RealmPlayground,
Recipient,
Subscription,
UserGroup,
UserProfile,
get_realm,
get_realm_domains,
@ -985,3 +988,60 @@ class TestRealmAuditLog(ZulipTestCase):
).count(),
1,
)
def test_system_user_groups_creation(self) -> None:
realm = Realm.objects.create(string_id="test", name="foo")
now = timezone_now()
create_system_user_groups_for_realm(realm)
# The expected number of system user group is the total number of roles
# from UserGroup.SYSTEM_USER_GROUP_ROLE_MAP in addition to
# full_members_system_group, everyone_on_internet_system_group and
# nobody_system_group.
expected_system_user_group_count = len(UserGroup.SYSTEM_USER_GROUP_ROLE_MAP) + 3
system_user_group_ids = sorted(
UserGroup.objects.filter(
realm=realm,
is_system_group=True,
).values_list("id", flat=True)
)
self.assert_length(system_user_group_ids, expected_system_user_group_count)
logged_system_group_ids = sorted(
RealmAuditLog.objects.filter(
realm=realm,
event_type=RealmAuditLog.USER_GROUP_CREATED,
event_time__gte=now,
acting_user=None,
).values_list("modified_user_group_id", flat=True)
)
self.assertListEqual(logged_system_group_ids, system_user_group_ids)
def test_user_group_creation(self) -> None:
hamlet = self.example_user("hamlet")
cordelia = self.example_user("cordelia")
now = timezone_now()
user_group = check_add_user_group(
hamlet.realm, "empty", [hamlet, cordelia], acting_user=hamlet, description="lorem"
)
audit_log_entries = RealmAuditLog.objects.filter(
acting_user=hamlet,
realm=hamlet.realm,
event_time__gte=now,
event_type=RealmAuditLog.USER_GROUP_CREATED,
)
self.assert_length(audit_log_entries, 1)
self.assertIsNone(audit_log_entries[0].modified_user)
self.assertEqual(audit_log_entries[0].modified_user_group, user_group)
audit_log_entries = RealmAuditLog.objects.filter(
acting_user=hamlet,
realm=hamlet.realm,
event_time__gte=now,
event_type=RealmAuditLog.USER_GROUP_DIRECT_USER_MEMBERSHIP_ADDED,
)
self.assert_length(audit_log_entries, 2)
self.assertEqual(audit_log_entries[0].modified_user, hamlet)
self.assertEqual(audit_log_entries[1].modified_user, cordelia)

View File

@ -1334,6 +1334,7 @@ class SlackImporter(ZulipTestCase):
RealmAuditLog.SUBSCRIPTION_CREATED,
RealmAuditLog.REALM_PLAN_TYPE_CHANGED,
RealmAuditLog.REALM_CREATED,
RealmAuditLog.USER_GROUP_CREATED,
},
)