mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 04:53:36 +00:00
realm: Migrate "PATCH /realm" endpoint to typed_endpoint.
This commit is contained in:
@@ -316,10 +316,12 @@ ERROR_TEMPLATES = {
|
||||
"datetime_parsing": _("{var_name} is not a date"),
|
||||
"datetime_type": _("{var_name} is not a date"),
|
||||
"dict_type": _("{var_name} is not a dict"),
|
||||
"enum": _("Invalid {var_name}"),
|
||||
"extra_forbidden": _('Argument "{argument}" at {var_name} is unexpected'),
|
||||
"float_parsing": _("{var_name} is not a float"),
|
||||
"float_type": _("{var_name} is not a float"),
|
||||
"greater_than": _("{var_name} is too small"),
|
||||
"greater_than_equal": _("{var_name} is too small"),
|
||||
"int_parsing": _("{var_name} is not an integer"),
|
||||
"int_type": _("{var_name} is not an integer"),
|
||||
"json_invalid": _("{var_name} is not valid JSON"),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from email.headerregistry import Address
|
||||
from enum import Enum, IntEnum
|
||||
from enum import IntEnum
|
||||
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, TypedDict, Union
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -76,7 +76,7 @@ def generate_realm_uuid_owner_secret() -> str:
|
||||
return f"zuliprealm_{token}"
|
||||
|
||||
|
||||
class OrgTypeEnum(Enum):
|
||||
class OrgTypeEnum(IntEnum):
|
||||
Unspecified = 0
|
||||
Business = 10
|
||||
OpenSource = 20
|
||||
|
||||
@@ -779,6 +779,7 @@ class RealmTest(ZulipTestCase):
|
||||
f"Bad value for '{val_name}'",
|
||||
f"Bad value for '{val_name}': {invalid_val}",
|
||||
f"Invalid {val_name} {invalid_val}",
|
||||
f"{val_name} is too small",
|
||||
}
|
||||
|
||||
req = {val_name: invalid_val}
|
||||
@@ -1114,7 +1115,7 @@ class RealmTest(ZulipTestCase):
|
||||
|
||||
req = dict(jitsi_server_url=orjson.dumps(12).decode())
|
||||
result = self.client_patch("/json/realm", req)
|
||||
self.assert_json_error(result, "jitsi_server_url is not an allowed_type")
|
||||
self.assert_json_error(result, "jitsi_server_url is not a string")
|
||||
|
||||
url_string = "".join(random.choices(string.ascii_lowercase, k=180))
|
||||
long_url = "https://jitsi.example.com/" + url_string
|
||||
|
||||
@@ -5,6 +5,9 @@ from django.http import HttpRequest, HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.utils.translation import gettext as _
|
||||
from django.views.decorators.http import require_safe
|
||||
from pydantic import Json, NonNegativeInt, StringConstraints
|
||||
from pydantic.functional_validators import AfterValidator
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from confirmation.models import Confirmation, ConfirmationKeyError, get_object_from_key
|
||||
from zerver.actions.create_realm import do_change_realm_subdomain
|
||||
@@ -31,20 +34,30 @@ from zerver.lib.request import REQ, has_request_variables
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.lib.retention import parse_message_retention_days
|
||||
from zerver.lib.streams import access_stream_by_id
|
||||
from zerver.lib.typed_endpoint import ApiParamConfig, typed_endpoint
|
||||
from zerver.lib.user_groups import access_user_group_for_setting
|
||||
from zerver.lib.validator import (
|
||||
check_bool,
|
||||
check_capped_string,
|
||||
check_capped_url,
|
||||
check_dict,
|
||||
check_int,
|
||||
check_int_in,
|
||||
check_string,
|
||||
check_string_in,
|
||||
check_string_or_int,
|
||||
check_union,
|
||||
to_non_negative_int,
|
||||
)
|
||||
from zerver.models import Realm, RealmReactivationStatus, RealmUserDefault, UserProfile
|
||||
from zerver.models.realms import (
|
||||
BotCreationPolicyEnum,
|
||||
CommonMessagePolicyEnum,
|
||||
CommonPolicyEnum,
|
||||
CreateWebPublicStreamPolicyEnum,
|
||||
DigestWeekdayEnum,
|
||||
EditTopicPolicyEnum,
|
||||
InviteToRealmPolicyEnum,
|
||||
MoveMessagesBetweenStreamsPolicyEnum,
|
||||
OrgTypeEnum,
|
||||
PrivateMessagePolicyEnum,
|
||||
WildcardMentionPolicyEnum,
|
||||
)
|
||||
from zerver.views.user_settings import check_settings_values
|
||||
|
||||
|
||||
@@ -60,139 +73,111 @@ def parse_jitsi_server_url(
|
||||
JITSI_SERVER_URL_MAX_LENGTH = 200
|
||||
|
||||
|
||||
def check_jitsi_url(value: str) -> str:
|
||||
var_name = "jitsi_server_url"
|
||||
value = check_string(var_name, value)
|
||||
|
||||
if value in list(Realm.JITSI_SERVER_SPECIAL_VALUES_MAP.keys()):
|
||||
return value
|
||||
|
||||
validator = check_capped_url(JITSI_SERVER_URL_MAX_LENGTH)
|
||||
try:
|
||||
return validator(var_name, value)
|
||||
except ValidationError:
|
||||
raise JsonableError(_("{var_name} is not an allowed_type").format(var_name=var_name))
|
||||
|
||||
|
||||
@require_realm_admin
|
||||
@has_request_variables
|
||||
@typed_endpoint
|
||||
def update_realm(
|
||||
request: HttpRequest,
|
||||
user_profile: UserProfile,
|
||||
name: Optional[str] = REQ(
|
||||
str_validator=check_capped_string(Realm.MAX_REALM_NAME_LENGTH), default=None
|
||||
),
|
||||
description: Optional[str] = REQ(
|
||||
str_validator=check_capped_string(Realm.MAX_REALM_DESCRIPTION_LENGTH), default=None
|
||||
),
|
||||
emails_restricted_to_domains: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
disallow_disposable_email_addresses: Optional[bool] = REQ(
|
||||
json_validator=check_bool, default=None
|
||||
),
|
||||
invite_required: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
invite_to_realm_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.INVITE_TO_REALM_POLICY_TYPES), default=None
|
||||
),
|
||||
create_multiuse_invite_group_id: Optional[int] = REQ(
|
||||
"create_multiuse_invite_group", json_validator=check_int, default=None
|
||||
),
|
||||
require_unique_names: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
name_changes_disabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
email_changes_disabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
avatar_changes_disabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
inline_image_preview: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
inline_url_embed_preview: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
add_custom_emoji_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
|
||||
),
|
||||
delete_own_message_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_MESSAGE_POLICY_TYPES), default=None
|
||||
),
|
||||
message_content_delete_limit_seconds_raw: Optional[Union[int, str]] = REQ(
|
||||
"message_content_delete_limit_seconds", json_validator=check_string_or_int, default=None
|
||||
),
|
||||
allow_message_editing: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
edit_topic_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.EDIT_TOPIC_POLICY_TYPES), default=None
|
||||
),
|
||||
mandatory_topics: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
message_content_edit_limit_seconds_raw: Optional[Union[int, str]] = REQ(
|
||||
"message_content_edit_limit_seconds", json_validator=check_string_or_int, default=None
|
||||
),
|
||||
allow_edit_history: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
default_language: Optional[str] = REQ(default=None),
|
||||
waiting_period_threshold: Optional[int] = REQ(converter=to_non_negative_int, default=None),
|
||||
authentication_methods: Optional[Dict[str, Any]] = REQ(
|
||||
json_validator=check_dict([]), default=None
|
||||
),
|
||||
*,
|
||||
name: Annotated[
|
||||
Optional[str], StringConstraints(max_length=Realm.MAX_REALM_NAME_LENGTH)
|
||||
] = None,
|
||||
description: Annotated[
|
||||
Optional[str], StringConstraints(max_length=Realm.MAX_REALM_DESCRIPTION_LENGTH)
|
||||
] = None,
|
||||
emails_restricted_to_domains: Optional[Json[bool]] = None,
|
||||
disallow_disposable_email_addresses: Optional[Json[bool]] = None,
|
||||
invite_required: Optional[Json[bool]] = None,
|
||||
invite_to_realm_policy: Optional[Json[InviteToRealmPolicyEnum]] = None,
|
||||
create_multiuse_invite_group_id: Annotated[
|
||||
Optional[Json[int]], ApiParamConfig(whence="create_multiuse_invite_group")
|
||||
] = None,
|
||||
require_unique_names: Optional[Json[bool]] = None,
|
||||
name_changes_disabled: Optional[Json[bool]] = None,
|
||||
email_changes_disabled: Optional[Json[bool]] = None,
|
||||
avatar_changes_disabled: Optional[Json[bool]] = None,
|
||||
inline_image_preview: Optional[Json[bool]] = None,
|
||||
inline_url_embed_preview: Optional[Json[bool]] = None,
|
||||
add_custom_emoji_policy: Optional[Json[CommonPolicyEnum]] = None,
|
||||
delete_own_message_policy: Optional[Json[CommonMessagePolicyEnum]] = None,
|
||||
message_content_delete_limit_seconds_raw: Annotated[
|
||||
Optional[Json[Union[int, str]]],
|
||||
ApiParamConfig("message_content_delete_limit_seconds"),
|
||||
] = None,
|
||||
allow_message_editing: Optional[Json[bool]] = None,
|
||||
edit_topic_policy: Optional[Json[EditTopicPolicyEnum]] = None,
|
||||
mandatory_topics: Optional[Json[bool]] = None,
|
||||
message_content_edit_limit_seconds_raw: Annotated[
|
||||
Optional[Json[Union[int, str]]], ApiParamConfig("message_content_edit_limit_seconds")
|
||||
] = None,
|
||||
allow_edit_history: Optional[Json[bool]] = None,
|
||||
default_language: Optional[str] = None,
|
||||
waiting_period_threshold: Optional[Json[NonNegativeInt]] = None,
|
||||
authentication_methods: Optional[Json[Dict[str, Any]]] = None,
|
||||
# Note: push_notifications_enabled and push_notifications_enabled_end_timestamp
|
||||
# are not offered here as it is maintained by the server, not via the API.
|
||||
new_stream_announcements_stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
|
||||
signup_announcements_stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
|
||||
zulip_update_announcements_stream_id: Optional[int] = REQ(
|
||||
json_validator=check_int, default=None
|
||||
),
|
||||
message_retention_days_raw: Optional[Union[int, str]] = REQ(
|
||||
"message_retention_days", json_validator=check_string_or_int, default=None
|
||||
),
|
||||
send_welcome_emails: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
digest_emails_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
message_content_allowed_in_email_notifications: Optional[bool] = REQ(
|
||||
json_validator=check_bool, default=None
|
||||
),
|
||||
bot_creation_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.BOT_CREATION_POLICY_TYPES), default=None
|
||||
),
|
||||
create_public_stream_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
|
||||
),
|
||||
create_private_stream_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
|
||||
),
|
||||
create_web_public_stream_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.CREATE_WEB_PUBLIC_STREAM_POLICY_TYPES), default=None
|
||||
),
|
||||
invite_to_stream_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
|
||||
),
|
||||
move_messages_between_streams_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.MOVE_MESSAGES_BETWEEN_STREAMS_POLICY_TYPES), default=None
|
||||
),
|
||||
user_group_edit_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
|
||||
),
|
||||
private_message_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.PRIVATE_MESSAGE_POLICY_TYPES), default=None
|
||||
),
|
||||
wildcard_mention_policy: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.WILDCARD_MENTION_POLICY_TYPES), default=None
|
||||
),
|
||||
video_chat_provider: Optional[int] = REQ(json_validator=check_int, default=None),
|
||||
jitsi_server_url_raw: Optional[str] = REQ(
|
||||
"jitsi_server_url",
|
||||
json_validator=check_union(
|
||||
[
|
||||
check_string_in(list(Realm.JITSI_SERVER_SPECIAL_VALUES_MAP.keys())),
|
||||
check_capped_url(JITSI_SERVER_URL_MAX_LENGTH),
|
||||
]
|
||||
),
|
||||
default=None,
|
||||
),
|
||||
giphy_rating: Optional[int] = REQ(json_validator=check_int, default=None),
|
||||
default_code_block_language: Optional[str] = REQ(default=None),
|
||||
digest_weekday: Optional[int] = REQ(
|
||||
json_validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None
|
||||
),
|
||||
string_id: Optional[str] = REQ(
|
||||
str_validator=check_capped_string(Realm.MAX_REALM_SUBDOMAIN_LENGTH),
|
||||
default=None,
|
||||
),
|
||||
org_type: Optional[int] = REQ(json_validator=check_int_in(Realm.ORG_TYPE_IDS), default=None),
|
||||
enable_spectator_access: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
want_advertise_in_communities_directory: Optional[bool] = REQ(
|
||||
json_validator=check_bool, default=None
|
||||
),
|
||||
enable_read_receipts: Optional[bool] = REQ(json_validator=check_bool, default=None),
|
||||
move_messages_within_stream_limit_seconds_raw: Optional[Union[int, str]] = REQ(
|
||||
"move_messages_within_stream_limit_seconds",
|
||||
json_validator=check_string_or_int,
|
||||
default=None,
|
||||
),
|
||||
move_messages_between_streams_limit_seconds_raw: Optional[Union[int, str]] = REQ(
|
||||
"move_messages_between_streams_limit_seconds",
|
||||
json_validator=check_string_or_int,
|
||||
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
|
||||
),
|
||||
new_stream_announcements_stream_id: Optional[Json[int]] = None,
|
||||
signup_announcements_stream_id: Optional[Json[int]] = None,
|
||||
zulip_update_announcements_stream_id: Optional[Json[int]] = None,
|
||||
message_retention_days_raw: Annotated[
|
||||
Optional[Json[Union[int, str]]], ApiParamConfig("message_retention_days")
|
||||
] = None,
|
||||
send_welcome_emails: Optional[Json[bool]] = None,
|
||||
digest_emails_enabled: Optional[Json[bool]] = None,
|
||||
message_content_allowed_in_email_notifications: Optional[Json[bool]] = None,
|
||||
bot_creation_policy: Optional[Json[BotCreationPolicyEnum]] = None,
|
||||
create_public_stream_policy: Optional[Json[CommonPolicyEnum]] = None,
|
||||
create_private_stream_policy: Optional[Json[CommonPolicyEnum]] = None,
|
||||
create_web_public_stream_policy: Optional[Json[CreateWebPublicStreamPolicyEnum]] = None,
|
||||
invite_to_stream_policy: Optional[Json[CommonPolicyEnum]] = None,
|
||||
move_messages_between_streams_policy: Optional[
|
||||
Json[MoveMessagesBetweenStreamsPolicyEnum]
|
||||
] = None,
|
||||
user_group_edit_policy: Optional[Json[CommonPolicyEnum]] = None,
|
||||
private_message_policy: Optional[Json[PrivateMessagePolicyEnum]] = None,
|
||||
wildcard_mention_policy: Optional[Json[WildcardMentionPolicyEnum]] = None,
|
||||
video_chat_provider: Optional[Json[int]] = None,
|
||||
jitsi_server_url_raw: Annotated[
|
||||
Optional[Json[str]],
|
||||
AfterValidator(lambda val: check_jitsi_url(val)),
|
||||
ApiParamConfig("jitsi_server_url"),
|
||||
] = None,
|
||||
giphy_rating: Optional[Json[int]] = None,
|
||||
default_code_block_language: Optional[str] = None,
|
||||
digest_weekday: Optional[Json[DigestWeekdayEnum]] = None,
|
||||
string_id: Annotated[
|
||||
Optional[str], StringConstraints(max_length=Realm.MAX_REALM_SUBDOMAIN_LENGTH)
|
||||
] = None,
|
||||
org_type: Optional[Json[OrgTypeEnum]] = None,
|
||||
enable_spectator_access: Optional[Json[bool]] = None,
|
||||
want_advertise_in_communities_directory: Optional[Json[bool]] = None,
|
||||
enable_read_receipts: Optional[Json[bool]] = None,
|
||||
move_messages_within_stream_limit_seconds_raw: Annotated[
|
||||
Optional[Json[Union[int, str]]],
|
||||
ApiParamConfig("move_messages_within_stream_limit_seconds"),
|
||||
] = None,
|
||||
move_messages_between_streams_limit_seconds_raw: Annotated[
|
||||
Optional[Json[Union[int, str]]],
|
||||
ApiParamConfig("move_messages_between_streams_limit_seconds"),
|
||||
] = None,
|
||||
enable_guest_user_indicator: Optional[Json[bool]] = None,
|
||||
can_access_all_users_group_id: Annotated[
|
||||
Optional[Json[int]], ApiParamConfig("can_access_all_users_group")
|
||||
] = None,
|
||||
) -> HttpResponse:
|
||||
realm = user_profile.realm
|
||||
|
||||
|
||||
Reference in New Issue
Block a user