mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	models: Add can_access_all_users_group setting.
This commit adds new setting for controlling who can access all users in the realm which would have "Everyone" and "Members only" option. Fixes part of #10970.
This commit is contained in:
		@@ -20,6 +20,17 @@ format used by the Zulip server that they are interacting with.
 | 
			
		||||
 | 
			
		||||
## Changes in Zulip 8.0
 | 
			
		||||
 | 
			
		||||
**Feature level 225**
 | 
			
		||||
 | 
			
		||||
* `PATCH /realm`, [`POST /register`](/api/register-queue),
 | 
			
		||||
  [`GET /events`](/api/get-events): Added `can_access_all_users_group_id`
 | 
			
		||||
  realm setting, which is the ID of the user group whose members can
 | 
			
		||||
  access all the users in the oragnization.
 | 
			
		||||
 | 
			
		||||
* [`POST /register`](/api/register-queue): Added `allowed_system_groups`
 | 
			
		||||
  field to configuration data object of permission settings passed in
 | 
			
		||||
  `server_supported_permission_settings`.
 | 
			
		||||
 | 
			
		||||
**Feature level 224**
 | 
			
		||||
 | 
			
		||||
* [`GET /events`](/api/get-events), [`GET /messages`](/api/get-messages),
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
 | 
			
		||||
# Changes should be accompanied by documentation explaining what the
 | 
			
		||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
 | 
			
		||||
# entries in the endpoint's documentation in `zulip.yaml`.
 | 
			
		||||
API_FEATURE_LEVEL = 224
 | 
			
		||||
API_FEATURE_LEVEL = 225
 | 
			
		||||
 | 
			
		||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
 | 
			
		||||
# only when going from an old version of the code to a newer version. Bump
 | 
			
		||||
 
 | 
			
		||||
@@ -991,7 +991,8 @@ night_logo_data = DictType(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
group_setting_update_data_type = DictType(
 | 
			
		||||
    required_keys=[], optional_keys=[("create_multiuse_invite_group", int)]
 | 
			
		||||
    required_keys=[],
 | 
			
		||||
    optional_keys=[("create_multiuse_invite_group", int), ("can_access_all_users_group", int)],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
update_dict_data = UnionType(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import datetime
 | 
			
		||||
from dataclasses import dataclass
 | 
			
		||||
from dataclasses import dataclass, field
 | 
			
		||||
from typing import Any, Callable, Dict, List, Optional, Tuple, TypedDict, TypeVar, Union
 | 
			
		||||
 | 
			
		||||
from django_stubs_ext import StrPromise
 | 
			
		||||
@@ -291,6 +291,7 @@ class GroupPermissionSetting:
 | 
			
		||||
    default_group_name: str
 | 
			
		||||
    id_field_name: str
 | 
			
		||||
    default_for_system_groups: Optional[str] = None
 | 
			
		||||
    allowed_system_groups: List[str] = field(default_factory=list)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@dataclass
 | 
			
		||||
 
 | 
			
		||||
@@ -215,6 +215,16 @@ def access_user_group_for_setting(
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
        permission_configuration.allowed_system_groups
 | 
			
		||||
        and user_group.name not in permission_configuration.allowed_system_groups
 | 
			
		||||
    ):
 | 
			
		||||
        raise JsonableError(
 | 
			
		||||
            _("'{setting_name}' setting cannot be set to '{group_name}' group.").format(
 | 
			
		||||
                setting_name=setting_name, group_name=user_group.name
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    return user_group
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								zerver/migrations/0487_realm_can_access_all_users_group.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								zerver/migrations/0487_realm_can_access_all_users_group.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
# Generated by Django 4.1.7 on 2023-03-23 14:40
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("zerver", "0486_clear_old_data_for_unused_usermessage_flags"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="realm",
 | 
			
		||||
            name="can_access_all_users_group",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.RESTRICT,
 | 
			
		||||
                related_name="+",
 | 
			
		||||
                to="zerver.usergroup",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
# Generated by Django 4.2.5 on 2023-09-21 14:00
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
 | 
			
		||||
from django.db.migrations.state import StateApps
 | 
			
		||||
from django.db.models import OuterRef
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def set_default_value_for_can_access_all_users_group(
 | 
			
		||||
    apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
 | 
			
		||||
) -> None:
 | 
			
		||||
    Realm = apps.get_model("zerver", "Realm")
 | 
			
		||||
    UserGroup = apps.get_model("zerver", "UserGroup")
 | 
			
		||||
 | 
			
		||||
    EVERYONE_GROUP_NAME = "role:everyone"
 | 
			
		||||
 | 
			
		||||
    Realm.objects.filter(can_access_all_users_group=None).update(
 | 
			
		||||
        can_access_all_users_group=UserGroup.objects.filter(
 | 
			
		||||
            name=EVERYONE_GROUP_NAME, realm=OuterRef("id"), is_system_group=True
 | 
			
		||||
        ).values("pk")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("zerver", "0487_realm_can_access_all_users_group"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RunPython(
 | 
			
		||||
            set_default_value_for_can_access_all_users_group,
 | 
			
		||||
            elidable=True,
 | 
			
		||||
            reverse_code=migrations.RunPython.noop,
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
# Generated by Django 4.2.5 on 2023-09-21 14:07
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("zerver", "0488_set_default_value_for_can_access_all_users_group"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="realm",
 | 
			
		||||
            name="can_access_all_users_group",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                on_delete=django.db.models.deletion.RESTRICT,
 | 
			
		||||
                related_name="+",
 | 
			
		||||
                to="zerver.usergroup",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@@ -445,6 +445,14 @@ class Realm(models.Model):  # type: ignore[django-manager-missing] # django-stub
 | 
			
		||||
        "UserGroup", on_delete=models.RESTRICT, related_name="+"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # on_delete field here is set to RESTRICT because we don't want to allow
 | 
			
		||||
    # deleting a user group in case it is referenced by this setting.
 | 
			
		||||
    # We are not using PROTECT since we want to allow deletion of user groups
 | 
			
		||||
    # when realm itself is deleted.
 | 
			
		||||
    can_access_all_users_group = models.ForeignKey(
 | 
			
		||||
        "UserGroup", on_delete=models.RESTRICT, related_name="+"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Who in the organization is allowed to invite other users to streams.
 | 
			
		||||
    invite_to_stream_policy = models.PositiveSmallIntegerField(default=POLICY_MEMBERS_ONLY)
 | 
			
		||||
 | 
			
		||||
@@ -814,6 +822,16 @@ class Realm(models.Model):  # type: ignore[django-manager-missing] # django-stub
 | 
			
		||||
            default_group_name=SystemGroups.ADMINISTRATORS,
 | 
			
		||||
            id_field_name="create_multiuse_invite_group_id",
 | 
			
		||||
        ),
 | 
			
		||||
        can_access_all_users_group=GroupPermissionSetting(
 | 
			
		||||
            require_system_group=True,
 | 
			
		||||
            allow_internet_group=False,
 | 
			
		||||
            allow_owners_group=False,
 | 
			
		||||
            allow_nobody_group=False,
 | 
			
		||||
            allow_everyone_group=True,
 | 
			
		||||
            default_group_name=SystemGroups.EVERYONE,
 | 
			
		||||
            id_field_name="can_access_all_users_group_id",
 | 
			
		||||
            allowed_system_groups=[SystemGroups.EVERYONE],
 | 
			
		||||
        ),
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    DIGEST_WEEKDAY_VALUES = [0, 1, 2, 3, 4, 5, 6]
 | 
			
		||||
 
 | 
			
		||||
@@ -4543,6 +4543,16 @@ paths:
 | 
			
		||||
                                        guest users to prominently highlight their status.
 | 
			
		||||
 | 
			
		||||
                                        **Changes**: New in Zulip 8.0 (feature level 216).
 | 
			
		||||
                                    can_access_all_users_group:
 | 
			
		||||
                                      type: integer
 | 
			
		||||
                                      description: |
 | 
			
		||||
                                        The ID of the [user group](/api/get-user-groups) whose members
 | 
			
		||||
                                        are allowed to access all users in the organization.
 | 
			
		||||
 | 
			
		||||
                                        This setting can currently only be set to `"role:everyone"`
 | 
			
		||||
                                        system group.
 | 
			
		||||
 | 
			
		||||
                                        **Changes**: New in Zulip 8.0 (feature level 225).
 | 
			
		||||
                                  additionalProperties: false
 | 
			
		||||
                              example:
 | 
			
		||||
                                {
 | 
			
		||||
@@ -14356,6 +14366,16 @@ paths:
 | 
			
		||||
                          guest users to prominently highlight their status.
 | 
			
		||||
 | 
			
		||||
                          **Changes**: New in Zulip 8.0 (feature level 216).
 | 
			
		||||
                      realm_can_access_all_users_group:
 | 
			
		||||
                        type: integer
 | 
			
		||||
                        description: |
 | 
			
		||||
                          The ID of the [user group](/api/get-user-groups) whose members
 | 
			
		||||
                          are allowed to access all users in the organization.
 | 
			
		||||
 | 
			
		||||
                          This setting can currently only be set to `"role:members"`
 | 
			
		||||
                          and `"role:everyone"` system groups.
 | 
			
		||||
 | 
			
		||||
                          **Changes**: New in Zulip 8.0 (feature level 225).
 | 
			
		||||
                      zulip_plan_is_not_limited:
 | 
			
		||||
                        type: boolean
 | 
			
		||||
                        description: |
 | 
			
		||||
@@ -19422,6 +19442,18 @@ components:
 | 
			
		||||
            Name of the default group for the setting for system groups.
 | 
			
		||||
 | 
			
		||||
            This is non-null only for group-level settings.
 | 
			
		||||
        allowed_system_groups:
 | 
			
		||||
          type: array
 | 
			
		||||
          description: |
 | 
			
		||||
            An array of names of system groups to which the setting can
 | 
			
		||||
            be set to.
 | 
			
		||||
 | 
			
		||||
            If the list is empty, the setting can be set to system groups
 | 
			
		||||
            based on the other boolean fields.
 | 
			
		||||
 | 
			
		||||
            **Changes**: New in Zulip 8.0 (feature level 225).
 | 
			
		||||
          items:
 | 
			
		||||
            type: string
 | 
			
		||||
    User:
 | 
			
		||||
      allOf:
 | 
			
		||||
        - $ref: "#/components/schemas/UserBase"
 | 
			
		||||
 
 | 
			
		||||
@@ -115,6 +115,7 @@ class HomeTest(ZulipTestCase):
 | 
			
		||||
        "realm_bot_creation_policy",
 | 
			
		||||
        "realm_bot_domain",
 | 
			
		||||
        "realm_bots",
 | 
			
		||||
        "realm_can_access_all_users_group",
 | 
			
		||||
        "realm_create_multiuse_invite_group",
 | 
			
		||||
        "realm_create_private_stream_policy",
 | 
			
		||||
        "realm_create_public_stream_policy",
 | 
			
		||||
 
 | 
			
		||||
@@ -1286,6 +1286,11 @@ class RealmAPITest(ZulipTestCase):
 | 
			
		||||
                    user_group.name == SystemGroups.OWNERS
 | 
			
		||||
                    and not setting_permission_configuration.allow_owners_group
 | 
			
		||||
                )
 | 
			
		||||
                or (
 | 
			
		||||
                    setting_permission_configuration.allowed_system_groups
 | 
			
		||||
                    and user_group.name
 | 
			
		||||
                    not in setting_permission_configuration.allowed_system_groups
 | 
			
		||||
                )
 | 
			
		||||
            ):
 | 
			
		||||
                value = orjson.dumps(user_group.id).decode()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,6 +175,9 @@ def update_realm(
 | 
			
		||||
        default=None,
 | 
			
		||||
    ),
 | 
			
		||||
    enable_guest_user_indicator: Optional[bool] = REQ(json_validator=check_bool, default=None),
 | 
			
		||||
    can_access_all_users_group_id: Optional[int] = REQ(
 | 
			
		||||
        "can_access_all_users_group", json_validator=check_int, default=None
 | 
			
		||||
    ),
 | 
			
		||||
) -> HttpResponse:
 | 
			
		||||
    realm = user_profile.realm
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user