models: Extract zerver.models.groups.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2023-12-14 16:55:59 -08:00 committed by Tim Abbott
parent 45bb8d2580
commit 7001a0dfc0
25 changed files with 129 additions and 120 deletions

View File

@ -32,10 +32,10 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
class Command(BaseCommand): class Command(BaseCommand):

View File

@ -74,12 +74,12 @@ from zerver.models import (
RealmAuditLog, RealmAuditLog,
Recipient, Recipient,
Stream, Stream,
SystemGroups,
UserActivityInterval, UserActivityInterval,
UserGroup, UserGroup,
UserProfile, UserProfile,
get_client, get_client,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_user, is_cross_realm_bot_email from zerver.models.users import get_user, is_cross_realm_bot_email
from zilencer.models import ( from zilencer.models import (
RemoteInstallationCount, RemoteInstallationCount,

View File

@ -44,12 +44,12 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserMessage, UserMessage,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import active_user_ids, bot_owner_user_ids, get_system_bot from zerver.models.users import active_user_ids, bot_owner_user_ids, get_system_bot
from zerver.tornado.django_api import send_event_on_commit from zerver.tornado.django_api import send_event_on_commit

View File

@ -98,7 +98,6 @@ from zerver.models import (
Realm, Realm,
Recipient, Recipient,
Stream, Stream,
SystemGroups,
UserMessage, UserMessage,
UserPresence, UserPresence,
UserProfile, UserProfile,
@ -109,6 +108,7 @@ from zerver.models import (
get_stream_by_id_in_realm, get_stream_by_id_in_realm,
query_for_ids, query_for_ids,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user_by_delivery_email, is_cross_realm_bot_email from zerver.models.users import get_system_bot, get_user_by_delivery_email, is_cross_realm_bot_email
from zerver.tornado.django_api import send_event from zerver.tornado.django_api import send_event

View File

@ -31,11 +31,11 @@ from zerver.models import (
ScheduledEmail, ScheduledEmail,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserProfile, UserProfile,
get_realm, get_realm,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import active_user_ids from zerver.models.users import active_user_ids
from zerver.tornado.django_api import send_event, send_event_on_commit from zerver.tornado.django_api import send_event, send_event_on_commit

View File

@ -64,10 +64,10 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import active_non_guest_user_ids, active_user_ids, get_system_bot from zerver.models.users import active_non_guest_user_ids, active_user_ids, get_system_bot
from zerver.tornado.django_api import send_event, send_event_on_commit from zerver.tornado.django_api import send_event, send_event_on_commit

View File

@ -15,11 +15,11 @@ from zerver.models import (
GroupGroupMembership, GroupGroupMembership,
Realm, Realm,
RealmAuditLog, RealmAuditLog,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import active_user_ids from zerver.models.users import active_user_ids
from zerver.tornado.django_api import send_event, send_event_on_commit from zerver.tornado.django_api import send_event, send_event_on_commit

View File

@ -13,11 +13,11 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
def bulk_create_users( def bulk_create_users(

View File

@ -67,7 +67,6 @@ from zerver.models import (
Service, Service,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserActivity, UserActivity,
UserActivityInterval, UserActivityInterval,
UserGroup, UserGroup,
@ -80,6 +79,7 @@ from zerver.models import (
get_huddle_hash, get_huddle_hash,
get_realm, get_realm,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user_profile_by_id from zerver.models.users import get_system_bot, get_user_profile_by_id
realm_tables = [ realm_tables = [

View File

@ -28,7 +28,6 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserProfile, UserProfile,
bulk_get_streams, bulk_get_streams,
@ -36,6 +35,7 @@ from zerver.models import (
get_stream, get_stream,
get_stream_by_id_in_realm, get_stream_by_id_in_realm,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import active_non_guest_user_ids, active_user_ids, is_cross_realm_bot_email from zerver.models.users import active_non_guest_user_ids, active_user_ids, is_cross_realm_bot_email
from zerver.tornado.django_api import send_event from zerver.tornado.django_api import send_event

View File

@ -102,7 +102,6 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserMessage, UserMessage,
@ -113,6 +112,7 @@ from zerver.models import (
get_realm_stream, get_realm_stream,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user, get_user_by_delivery_email from zerver.models.users import get_system_bot, get_user, get_user_by_delivery_email
from zerver.openapi.openapi import validate_against_openapi_schema, validate_request from zerver.openapi.openapi import validate_against_openapi_schema, validate_request
from zerver.tornado.event_queue import clear_client_event_queues_for_testing from zerver.tornado.event_queue import clear_client_event_queues_for_testing

View File

@ -16,11 +16,11 @@ from zerver.models import (
Realm, Realm,
RealmAuditLog, RealmAuditLog,
Stream, Stream,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserProfile, UserProfile,
) )
from zerver.models.groups import SystemGroups
class UserGroupDict(TypedDict): class UserGroupDict(TypedDict):

View File

@ -34,11 +34,11 @@ from zerver.models import (
Recipient, Recipient,
Service, Service,
Subscription, Subscription,
SystemGroups,
UserMessage, UserMessage,
UserProfile, UserProfile,
get_fake_email_domain, get_fake_email_domain,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import ( from zerver.models.users import (
active_non_guest_user_ids, active_non_guest_user_ids,
active_user_ids, active_user_ids,

View File

@ -47,7 +47,6 @@ from django.db.models.sql.compiler import SQLCompiler
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy from django.utils.translation import gettext_lazy
from django_cte import CTEManager
from django_stubs_ext import StrPromise, ValuesQuerySet from django_stubs_ext import StrPromise, ValuesQuerySet
from typing_extensions import override from typing_extensions import override
@ -101,6 +100,10 @@ from zerver.lib.validator import (
validate_select_field, validate_select_field,
) )
from zerver.models.constants import MAX_LANGUAGE_ID_LENGTH, MAX_TOPIC_NAME_LENGTH from zerver.models.constants import MAX_LANGUAGE_ID_LENGTH, MAX_TOPIC_NAME_LENGTH
from zerver.models.groups import GroupGroupMembership as GroupGroupMembership
from zerver.models.groups import SystemGroups
from zerver.models.groups import UserGroup as UserGroup
from zerver.models.groups import UserGroupMembership as UserGroupMembership
from zerver.models.users import RealmUserDefault as RealmUserDefault from zerver.models.users import RealmUserDefault as RealmUserDefault
from zerver.models.users import UserBaseSettings as UserBaseSettings from zerver.models.users import UserBaseSettings as UserBaseSettings
from zerver.models.users import UserProfile as UserProfile from zerver.models.users import UserProfile as UserProfile
@ -245,17 +248,6 @@ def clear_supported_auth_backends_cache() -> None:
supported_backends = None supported_backends = None
class SystemGroups:
FULL_MEMBERS = "role:fullmembers"
EVERYONE_ON_INTERNET = "role:internet"
OWNERS = "role:owners"
ADMINISTRATORS = "role:administrators"
MODERATORS = "role:moderators"
MEMBERS = "role:members"
EVERYONE = "role:everyone"
NOBODY = "role:nobody"
class RealmAuthenticationMethod(models.Model): class RealmAuthenticationMethod(models.Model):
""" """
Tracks which authentication backends are enabled for a realm. Tracks which authentication backends are enabled for a realm.
@ -1563,91 +1555,6 @@ class Recipient(models.Model):
return self._type_names[self.type] return self._type_names[self.type]
class UserGroup(models.Model): # type: ignore[django-manager-missing] # django-stubs cannot resolve the custom CTEManager yet https://github.com/typeddjango/django-stubs/issues/1023
MAX_NAME_LENGTH = 100
INVALID_NAME_PREFIXES = ["@", "role:", "user:", "stream:", "channel:"]
objects: CTEManager = CTEManager()
name = models.CharField(max_length=MAX_NAME_LENGTH)
direct_members = models.ManyToManyField(
UserProfile, through="zerver.UserGroupMembership", related_name="direct_groups"
)
direct_subgroups = models.ManyToManyField(
"self",
symmetrical=False,
through="zerver.GroupGroupMembership",
through_fields=("supergroup", "subgroup"),
related_name="direct_supergroups",
)
realm = models.ForeignKey(Realm, on_delete=CASCADE)
description = models.TextField(default="")
is_system_group = models.BooleanField(default=False)
can_mention_group = models.ForeignKey("self", on_delete=models.RESTRICT)
# We do not have "Full members" and "Everyone on the internet"
# group here since there isn't a separate role value for full
# members and spectators.
SYSTEM_USER_GROUP_ROLE_MAP = {
UserProfile.ROLE_REALM_OWNER: {
"name": SystemGroups.OWNERS,
"description": "Owners of this organization",
},
UserProfile.ROLE_REALM_ADMINISTRATOR: {
"name": SystemGroups.ADMINISTRATORS,
"description": "Administrators of this organization, including owners",
},
UserProfile.ROLE_MODERATOR: {
"name": SystemGroups.MODERATORS,
"description": "Moderators of this organization, including administrators",
},
UserProfile.ROLE_MEMBER: {
"name": SystemGroups.MEMBERS,
"description": "Members of this organization, not including guests",
},
UserProfile.ROLE_GUEST: {
"name": SystemGroups.EVERYONE,
"description": "Everyone in this organization, including guests",
},
}
GROUP_PERMISSION_SETTINGS = {
"can_mention_group": GroupPermissionSetting(
require_system_group=False,
allow_internet_group=False,
allow_owners_group=False,
allow_nobody_group=True,
allow_everyone_group=True,
default_group_name=SystemGroups.EVERYONE,
default_for_system_groups=SystemGroups.NOBODY,
id_field_name="can_mention_group_id",
),
}
class Meta:
unique_together = (("realm", "name"),)
class UserGroupMembership(models.Model):
user_group = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
user_profile = models.ForeignKey(UserProfile, on_delete=CASCADE, related_name="+")
class Meta:
unique_together = (("user_group", "user_profile"),)
class GroupGroupMembership(models.Model):
supergroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
subgroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
class Meta:
constraints = [
models.UniqueConstraint(
fields=["supergroup", "subgroup"], name="zerver_groupgroupmembership_uniq"
)
]
class PreregistrationRealm(models.Model): class PreregistrationRealm(models.Model):
"""Data on a partially created realm entered by a user who has """Data on a partially created realm entered by a user who has
completed the "new organization" form. Used to transfer the user's completed the "new organization" form. Used to transfer the user's

102
zerver/models/groups.py Normal file
View File

@ -0,0 +1,102 @@
from django.db import models
from django.db.models import CASCADE
from django_cte import CTEManager
from zerver.lib.types import GroupPermissionSetting
from zerver.models.users import UserProfile
class SystemGroups:
FULL_MEMBERS = "role:fullmembers"
EVERYONE_ON_INTERNET = "role:internet"
OWNERS = "role:owners"
ADMINISTRATORS = "role:administrators"
MODERATORS = "role:moderators"
MEMBERS = "role:members"
EVERYONE = "role:everyone"
NOBODY = "role:nobody"
class UserGroup(models.Model): # type: ignore[django-manager-missing] # django-stubs cannot resolve the custom CTEManager yet https://github.com/typeddjango/django-stubs/issues/1023
MAX_NAME_LENGTH = 100
INVALID_NAME_PREFIXES = ["@", "role:", "user:", "stream:", "channel:"]
objects: CTEManager = CTEManager()
name = models.CharField(max_length=MAX_NAME_LENGTH)
direct_members = models.ManyToManyField(
UserProfile, through="zerver.UserGroupMembership", related_name="direct_groups"
)
direct_subgroups = models.ManyToManyField(
"self",
symmetrical=False,
through="zerver.GroupGroupMembership",
through_fields=("supergroup", "subgroup"),
related_name="direct_supergroups",
)
realm = models.ForeignKey("zerver.Realm", on_delete=CASCADE)
description = models.TextField(default="")
is_system_group = models.BooleanField(default=False)
can_mention_group = models.ForeignKey("self", on_delete=models.RESTRICT)
# We do not have "Full members" and "Everyone on the internet"
# group here since there isn't a separate role value for full
# members and spectators.
SYSTEM_USER_GROUP_ROLE_MAP = {
UserProfile.ROLE_REALM_OWNER: {
"name": SystemGroups.OWNERS,
"description": "Owners of this organization",
},
UserProfile.ROLE_REALM_ADMINISTRATOR: {
"name": SystemGroups.ADMINISTRATORS,
"description": "Administrators of this organization, including owners",
},
UserProfile.ROLE_MODERATOR: {
"name": SystemGroups.MODERATORS,
"description": "Moderators of this organization, including administrators",
},
UserProfile.ROLE_MEMBER: {
"name": SystemGroups.MEMBERS,
"description": "Members of this organization, not including guests",
},
UserProfile.ROLE_GUEST: {
"name": SystemGroups.EVERYONE,
"description": "Everyone in this organization, including guests",
},
}
GROUP_PERMISSION_SETTINGS = {
"can_mention_group": GroupPermissionSetting(
require_system_group=False,
allow_internet_group=False,
allow_owners_group=False,
allow_nobody_group=True,
allow_everyone_group=True,
default_group_name=SystemGroups.EVERYONE,
default_for_system_groups=SystemGroups.NOBODY,
id_field_name="can_mention_group_id",
),
}
class Meta:
unique_together = (("realm", "name"),)
class UserGroupMembership(models.Model):
user_group = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
user_profile = models.ForeignKey(UserProfile, on_delete=CASCADE, related_name="+")
class Meta:
unique_together = (("user_group", "user_profile"),)
class GroupGroupMembership(models.Model):
supergroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
subgroup = models.ForeignKey(UserGroup, on_delete=CASCADE, related_name="+")
class Meta:
constraints = [
models.UniqueConstraint(
fields=["supergroup", "subgroup"], name="zerver_groupgroupmembership_uniq"
)
]

View File

@ -81,7 +81,6 @@ from zerver.models import (
RealmPlayground, RealmPlayground,
Recipient, Recipient,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserProfile, UserProfile,
get_all_custom_emoji_for_realm, get_all_custom_emoji_for_realm,
@ -91,6 +90,7 @@ from zerver.models import (
get_stream, get_stream,
linkifiers_for_realm, linkifiers_for_realm,
) )
from zerver.models.groups import SystemGroups
class TestRealmAuditLog(ZulipTestCase): class TestRealmAuditLog(ZulipTestCase):

View File

@ -234,7 +234,6 @@ from zerver.models import (
RealmUserDefault, RealmUserDefault,
Service, Service,
Stream, Stream,
SystemGroups,
UserGroup, UserGroup,
UserMessage, UserMessage,
UserPresence, UserPresence,
@ -244,6 +243,7 @@ from zerver.models import (
get_client, get_client,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_user_by_delivery_email from zerver.models.users import get_user_by_delivery_email
from zerver.openapi.openapi import validate_against_openapi_schema from zerver.openapi.openapi import validate_against_openapi_schema
from zerver.tornado.django_api import send_event from zerver.tornado.django_api import send_event

View File

@ -76,7 +76,6 @@ from zerver.models import (
ScheduledMessage, ScheduledMessage,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserMessage, UserMessage,
@ -90,6 +89,7 @@ from zerver.models import (
get_realm, get_realm,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user_by_delivery_email from zerver.models.users import get_system_bot, get_user_by_delivery_email

View File

@ -60,13 +60,13 @@ from zerver.models import (
Realm, Realm,
ScheduledEmail, ScheduledEmail,
Stream, Stream,
SystemGroups,
UserGroup, UserGroup,
UserMessage, UserMessage,
UserProfile, UserProfile,
get_realm, get_realm,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_user_by_delivery_email from zerver.models.users import get_user_by_delivery_email
from zerver.views.invite import INVITATION_LINK_VALIDITY_MINUTES, get_invitee_emails_set from zerver.views.invite import INVITATION_LINK_VALIDITY_MINUTES, get_invitee_emails_set
from zerver.views.registration import accounts_home from zerver.views.registration import accounts_home

View File

@ -64,7 +64,6 @@ from zerver.models import (
Message, Message,
RealmEmoji, RealmEmoji,
RealmFilter, RealmFilter,
SystemGroups,
UserGroup, UserGroup,
UserMessage, UserMessage,
UserProfile, UserProfile,
@ -73,6 +72,7 @@ from zerver.models import (
get_stream, get_stream,
linkifiers_for_realm, linkifiers_for_realm,
) )
from zerver.models.groups import SystemGroups
class SimulatedFencedBlockPreprocessor(FencedBlockPreprocessor): class SimulatedFencedBlockPreprocessor(FencedBlockPreprocessor):

View File

@ -34,7 +34,6 @@ from zerver.models import (
Message, Message,
Realm, Realm,
Stream, Stream,
SystemGroups,
UserGroup, UserGroup,
UserMessage, UserMessage,
UserProfile, UserProfile,
@ -43,6 +42,7 @@ from zerver.models import (
get_stream, get_stream,
) )
from zerver.models.constants import MAX_TOPIC_NAME_LENGTH from zerver.models.constants import MAX_TOPIC_NAME_LENGTH
from zerver.models.groups import SystemGroups
if TYPE_CHECKING: if TYPE_CHECKING:
from django.test.client import _MonkeyPatchedWSGIResponse as TestHttpResponse from django.test.client import _MonkeyPatchedWSGIResponse as TestHttpResponse

View File

@ -53,7 +53,6 @@ from zerver.models import (
Recipient, Recipient,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroup, UserGroup,
UserMessage, UserMessage,
UserProfile, UserProfile,
@ -62,6 +61,7 @@ from zerver.models import (
get_stream, get_stream,
) )
from zerver.models.constants import MAX_TOPIC_NAME_LENGTH from zerver.models.constants import MAX_TOPIC_NAME_LENGTH
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user from zerver.models.users import get_system_bot, get_user
from zerver.views.message_send import InvalidMirrorInputError from zerver.views.message_send import InvalidMirrorInputError

View File

@ -49,7 +49,6 @@ from zerver.models import (
RealmUserDefault, RealmUserDefault,
ScheduledEmail, ScheduledEmail,
Stream, Stream,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserMessage, UserMessage,
@ -57,6 +56,7 @@ from zerver.models import (
get_realm, get_realm,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import get_system_bot, get_user_profile_by_id from zerver.models.users import get_system_bot, get_user_profile_by_id

View File

@ -35,12 +35,12 @@ from zerver.lib.user_groups import (
from zerver.models import ( from zerver.models import (
GroupGroupMembership, GroupGroupMembership,
Realm, Realm,
SystemGroups,
UserGroup, UserGroup,
UserGroupMembership, UserGroupMembership,
UserProfile, UserProfile,
get_realm, get_realm,
) )
from zerver.models.groups import SystemGroups
class UserGroupTestCase(ZulipTestCase): class UserGroupTestCase(ZulipTestCase):

View File

@ -70,7 +70,6 @@ from zerver.models import (
ScheduledEmail, ScheduledEmail,
Stream, Stream,
Subscription, Subscription,
SystemGroups,
UserGroupMembership, UserGroupMembership,
UserProfile, UserProfile,
UserTopic, UserTopic,
@ -81,6 +80,7 @@ from zerver.models import (
get_realm, get_realm,
get_stream, get_stream,
) )
from zerver.models.groups import SystemGroups
from zerver.models.users import ( from zerver.models.users import (
get_source_profile, get_source_profile,
get_system_bot, get_system_bot,