mirror of
https://github.com/zulip/zulip.git
synced 2026-06-30 21:11:04 +08:00
Some checks failed
Code scanning / CodeQL (push) Has been cancelled
Zulip production suite / Ubuntu 22.04 production build (push) Has been cancelled
Zulip CI / ${{ matrix.name }} (zulip/ci:bookworm, true, false, Debian 12 (Python 3.11, backend + documentation), bookworm) (push) Has been cancelled
Zulip CI / ${{ matrix.name }} (zulip/ci:jammy, false, true, Ubuntu 22.04 (Python 3.10, backend + frontend), jammy) (push) Has been cancelled
Zulip CI / ${{ matrix.name }} (zulip/ci:noble, false, false, Ubuntu 24.04 (Python 3.12, backend), noble) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm, --test-custom-db, Debian 12 production install with custom db name and user, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy, , Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga, jammy) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:noble, , Ubuntu 24.04 production install, noble) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm-7.0, 7.0 Version Upgrade, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:bookworm-8.0, 8.0 Version Upgrade, bookworm) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:jammy-6.0, 6.0 Version Upgrade, jammy) (push) Has been cancelled
Zulip production suite / ${{ matrix.name }} (zulip/ci:noble-9.0, 9.0 Version Upgrade, noble) (push) Has been cancelled
This commit introduced 'creator' and 'date_created' fields in user groups, allowing users to view who created the groups and when. Both fields can be null for groups without creator data.
141 lines
5.5 KiB
Python
141 lines
5.5 KiB
Python
from django.db import models
|
|
from django.db.models import CASCADE
|
|
from django.utils.timezone import now as timezone_now
|
|
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
|
|
objects: CTEManager = CTEManager()
|
|
direct_members = models.ManyToManyField(
|
|
UserProfile, through="zerver.UserGroupMembership", related_name="direct_groups"
|
|
)
|
|
direct_subgroups = models.ManyToManyField(
|
|
"zerver.NamedUserGroup",
|
|
symmetrical=False,
|
|
through="zerver.GroupGroupMembership",
|
|
through_fields=("supergroup", "subgroup"),
|
|
related_name="direct_supergroups",
|
|
)
|
|
realm = models.ForeignKey("zerver.Realm", on_delete=CASCADE)
|
|
|
|
|
|
class NamedUserGroup(UserGroup): # 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:"]
|
|
|
|
# This field is automatically created by django, but we still need
|
|
# to add this here to keep mypy happy when accessing usergroup_ptr.
|
|
usergroup_ptr = models.OneToOneField(
|
|
auto_created=True,
|
|
on_delete=CASCADE,
|
|
parent_link=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
to=UserGroup,
|
|
# We are not using the auto-generated name here to avoid
|
|
# duplicate backward relation name because "can_mention_group"
|
|
# setting also points to a UserGroup object.
|
|
related_name="named_user_group",
|
|
)
|
|
name = models.CharField(max_length=MAX_NAME_LENGTH, db_column="name")
|
|
description = models.TextField(default="", db_column="description")
|
|
date_created = models.DateTimeField(default=timezone_now, null=True)
|
|
creator = models.ForeignKey(
|
|
UserProfile, null=True, on_delete=models.SET_NULL, related_name="+", db_column="creator_id"
|
|
)
|
|
is_system_group = models.BooleanField(default=False, db_column="is_system_group")
|
|
|
|
can_manage_group = models.ForeignKey(UserGroup, on_delete=models.RESTRICT, related_name="+")
|
|
can_mention_group = models.ForeignKey(
|
|
UserGroup, on_delete=models.RESTRICT, db_column="can_mention_group_id"
|
|
)
|
|
|
|
realm_for_sharding = models.ForeignKey("zerver.Realm", on_delete=CASCADE, db_column="realm_id")
|
|
deactivated = models.BooleanField(default=False, db_default=False)
|
|
|
|
# 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_manage_group": GroupPermissionSetting(
|
|
require_system_group=False,
|
|
allow_internet_group=False,
|
|
allow_owners_group=True,
|
|
allow_nobody_group=True,
|
|
allow_everyone_group=False,
|
|
default_group_name=SystemGroups.NOBODY,
|
|
default_for_system_groups=SystemGroups.NOBODY,
|
|
id_field_name="can_manage_group_id",
|
|
),
|
|
"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_for_sharding", "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(NamedUserGroup, on_delete=CASCADE, related_name="+")
|
|
|
|
class Meta:
|
|
constraints = [
|
|
models.UniqueConstraint(
|
|
fields=["supergroup", "subgroup"], name="zerver_groupgroupmembership_uniq"
|
|
)
|
|
]
|