request: Rename validator parameter of REQ to json_validator.

This makes it much more clear that this feature does JSON encoding,
which previously was only indicated in the documentation.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-04-07 13:00:44 -07:00 committed by Tim Abbott
parent 93d2ae8092
commit f0e655f1d8
39 changed files with 291 additions and 259 deletions

View File

@ -123,13 +123,13 @@ def payment_method_string(stripe_customer: stripe.Customer) -> str:
def upgrade(
request: HttpRequest,
user: UserProfile,
billing_modality: str = REQ(validator=check_string),
schedule: str = REQ(validator=check_string),
license_management: Optional[str] = REQ(validator=check_string, default=None),
licenses: Optional[int] = REQ(validator=check_int, default=None),
stripe_token: Optional[str] = REQ(validator=check_string, default=None),
signed_seat_count: str = REQ(validator=check_string),
salt: str = REQ(validator=check_string),
billing_modality: str = REQ(json_validator=check_string),
schedule: str = REQ(json_validator=check_string),
license_management: Optional[str] = REQ(json_validator=check_string, default=None),
licenses: Optional[int] = REQ(json_validator=check_int, default=None),
stripe_token: Optional[str] = REQ(json_validator=check_string, default=None),
signed_seat_count: str = REQ(json_validator=check_string),
salt: str = REQ(json_validator=check_string),
) -> HttpResponse:
try:
seat_count = unsign_seat_count(signed_seat_count, salt)
@ -232,9 +232,9 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
def sponsorship(
request: HttpRequest,
user: UserProfile,
organization_type: str = REQ("organization-type", validator=check_string),
website: str = REQ("website", validator=check_string),
description: str = REQ("description", validator=check_string),
organization_type: str = REQ("organization-type", json_validator=check_string),
website: str = REQ("website", json_validator=check_string),
description: str = REQ("description", json_validator=check_string),
) -> HttpResponse:
realm = user.realm
@ -350,7 +350,7 @@ def billing_home(request: HttpRequest) -> HttpResponse:
@require_billing_access
@has_request_variables
def change_plan_status(
request: HttpRequest, user: UserProfile, status: int = REQ("status", validator=check_int)
request: HttpRequest, user: UserProfile, status: int = REQ("status", json_validator=check_int)
) -> HttpResponse:
assert status in [
CustomerPlan.ACTIVE,
@ -384,7 +384,7 @@ def change_plan_status(
def replace_payment_source(
request: HttpRequest,
user: UserProfile,
stripe_token: str = REQ("stripe_token", validator=check_string),
stripe_token: str = REQ("stripe_token", json_validator=check_string),
) -> HttpResponse:
try:
do_replace_payment_source(user, stripe_token, pay_invoices=True)

View File

@ -415,9 +415,9 @@ annotation).
def update_realm(
request: HttpRequest,
user_profile: UserProfile,
name: Optional[str] = REQ(validator=check_string, default=None),
name: Optional[str] = REQ(json_validator=check_string, default=None),
# ...
+ mandatory_topics: Optional[bool] = REQ(validator=check_bool, default=None),
+ mandatory_topics: Optional[bool] = REQ(json_validator=check_bool, default=None),
# ...
):
# ...

View File

@ -178,21 +178,21 @@ in
REQ also helps us with request variable validation. For example:
* `msg_ids = REQ(validator=check_list(check_int))` will check that the
`msg_ids` HTTP parameter is a list of integers, marshalled as JSON,
and pass it into the function as the `msg_ids` Python keyword
argument.
* `msg_ids = REQ(json_validator=check_list(check_int))` will check
that the `msg_ids` HTTP parameter is a list of integers, marshalled
as JSON, and pass it into the function as the `msg_ids` Python
keyword argument.
* `streams_raw = REQ("subscriptions",
validator=check_list(check_string))` will check that the
json_validator=check_list(check_string))` will check that the
"subscriptions" HTTP parameter is a list of strings, marshalled as
JSON, and pass it into the function with the Python keyword argument
`streams_raw`.
* `message_id=REQ(converter=to_non_negative_int)` will check that the
`message_id` HTTP parameter is a string containing a non-negative
integer (`converter` differs from `validator` in that it does not
automatically marshall the input from JSON).
integer (`converter` differs from `json_validator` in that it does
not automatically marshall the input from JSON).
See
[zerver/lib/validator.py](https://github.com/zulip/zulip/blob/master/zerver/lib/validator.py)
@ -261,7 +261,7 @@ For example, in [zerver/views/realm.py](https://github.com/zulip/zulip/blob/mast
@has_request_variables
def update_realm(
request: HttpRequest, user_profile: UserProfile,
name: Optional[str]=REQ(validator=check_string, default=None),
name: Optional[str]=REQ(json_validator=check_string, default=None),
# ...
):
realm = user_profile.realm

View File

@ -83,7 +83,7 @@ class _REQ(Generic[ResultT]):
*,
converter: Optional[Callable[[str], ResultT]] = None,
default: Union[_NotSpecified, ResultT, None] = NotSpecified,
validator: Optional[Validator[ResultT]] = None,
json_validator: Optional[Validator[ResultT]] = None,
str_validator: Optional[Validator[ResultT]] = None,
argument_type: Optional[str] = None,
intentionally_undocumented: bool = False,
@ -102,11 +102,12 @@ class _REQ(Generic[ResultT]):
default: a value to be used for the argument if the parameter
is missing in the request
validator: similar to converter, but takes an already parsed JSON
data structure. If specified, we will parse the JSON request
variable value before passing to the function
json_validator: similar to converter, but takes an already
parsed JSON data structure. If specified, we will parse the
JSON request variable value before passing to the function
str_validator: Like validator, but doesn't parse JSON first.
str_validator: Like json_validator, but doesn't parse JSON
first.
argument_type: pass 'body' to extract the parsed JSON
corresponding to the request body
@ -115,12 +116,13 @@ class _REQ(Generic[ResultT]):
path_only: Used for parameters included in the URL that we still want
to validate via REQ's hooks.
"""
self.post_var_name = whence
self.func_var_name: Optional[str] = None
self.converter = converter
self.validator = validator
self.json_validator = json_validator
self.str_validator = str_validator
self.default = default
self.argument_type = argument_type
@ -130,11 +132,11 @@ class _REQ(Generic[ResultT]):
self.path_only = path_only
assert converter is None or (
validator is None and str_validator is None
), "converter and validator are mutually exclusive"
json_validator is None and str_validator is None
), "converter and json_validator are mutually exclusive"
assert (
validator is None or str_validator is None
), "validator and str_validator are mutually exclusive"
json_validator is None or str_validator is None
), "json_validator and str_validator are mutually exclusive"
# This factory function ensures that mypy can correctly analyze REQ.
@ -163,13 +165,13 @@ def REQ(
...
# Overload 2: validator
# Overload 2: json_validator
@overload
def REQ(
whence: Optional[str] = ...,
*,
default: ResultT = ...,
validator: Validator[ResultT],
json_validator: Validator[ResultT],
intentionally_undocumented: bool = ...,
documentation_pending: bool = ...,
aliases: Sequence[str] = ...,
@ -178,7 +180,7 @@ def REQ(
...
# Overload 3: no converter/validator, default: str or unspecified, argument_type=None
# Overload 3: no converter/json_validator, default: str or unspecified, argument_type=None
@overload
def REQ(
whence: Optional[str] = ...,
@ -229,7 +231,7 @@ def REQ(
*,
converter: Optional[Callable[[str], ResultT]] = None,
default: Union[_REQ._NotSpecified, ResultT] = _REQ.NotSpecified,
validator: Optional[Validator[ResultT]] = None,
json_validator: Optional[Validator[ResultT]] = None,
str_validator: Optional[Validator[ResultT]] = None,
argument_type: Optional[str] = None,
intentionally_undocumented: bool = False,
@ -243,7 +245,7 @@ def REQ(
whence,
converter=converter,
default=default,
validator=validator,
json_validator=json_validator,
str_validator=str_validator,
argument_type=argument_type,
intentionally_undocumented=intentionally_undocumented,
@ -364,19 +366,19 @@ def has_request_variables(view_func: ViewFuncT) -> ViewFuncT:
except Exception:
raise RequestVariableConversionError(post_var_name, val)
# Validators are like converters, but they don't handle JSON parsing; we do.
if param.validator is not None and not default_assigned:
# json_validator is like converter, but doesn't handle JSON parsing; we do.
if param.json_validator is not None and not default_assigned:
try:
val = orjson.loads(val)
except orjson.JSONDecodeError:
raise JsonableError(_('Argument "{}" is not valid JSON.').format(post_var_name))
try:
val = param.validator(post_var_name, val)
val = param.json_validator(post_var_name, val)
except ValidationError as error:
raise JsonableError(error.message)
# str_validators is like validator, but for direct strings (no JSON parsing).
# str_validators is like json_validator, but for direct strings (no JSON parsing).
if param.str_validator is not None and not default_assigned:
try:
val = param.str_validator(post_var_name, val)

View File

@ -202,7 +202,7 @@ class DecoratorTestCase(ZulipTestCase):
def test_REQ_validator(self) -> None:
@has_request_variables
def get_total(
request: HttpRequest, numbers: Iterable[int] = REQ(validator=check_list(check_int))
request: HttpRequest, numbers: Iterable[int] = REQ(json_validator=check_list(check_int))
) -> int:
return sum(numbers)

View File

@ -43,7 +43,7 @@ def cleanup_event_queue(
@internal_notify_view(True)
@has_request_variables
def get_events_internal(
request: HttpRequest, user_profile_id: int = REQ(validator=check_int)
request: HttpRequest, user_profile_id: int = REQ(json_validator=check_int)
) -> HttpResponse:
user_profile = get_user_profile_by_id(user_profile_id)
request._requestor_for_logs = user_profile.format_requestor_for_logs()
@ -71,27 +71,31 @@ def get_events_backend(
# endpoint. This is a feature used primarily by get_events_internal
# and not expected to be used by third-party clients.
apply_markdown: bool = REQ(
default=False, validator=check_bool, intentionally_undocumented=True
default=False, json_validator=check_bool, intentionally_undocumented=True
),
client_gravatar: bool = REQ(
default=False, validator=check_bool, intentionally_undocumented=True
default=False, json_validator=check_bool, intentionally_undocumented=True
),
slim_presence: bool = REQ(
default=False, json_validator=check_bool, intentionally_undocumented=True
),
slim_presence: bool = REQ(default=False, validator=check_bool, intentionally_undocumented=True),
all_public_streams: bool = REQ(
default=False, validator=check_bool, intentionally_undocumented=True
default=False, json_validator=check_bool, intentionally_undocumented=True
),
event_types: Optional[Sequence[str]] = REQ(
default=None, validator=check_list(check_string), intentionally_undocumented=True
default=None, json_validator=check_list(check_string), intentionally_undocumented=True
),
dont_block: bool = REQ(default=False, validator=check_bool),
dont_block: bool = REQ(default=False, json_validator=check_bool),
narrow: Iterable[Sequence[str]] = REQ(
default=[], validator=check_list(check_list(check_string)), intentionally_undocumented=True
default=[],
json_validator=check_list(check_list(check_string)),
intentionally_undocumented=True,
),
lifespan_secs: int = REQ(
default=0, converter=to_non_negative_int, intentionally_undocumented=True
),
bulk_message_deletion: bool = REQ(
default=False, validator=check_bool, intentionally_undocumented=True
default=False, json_validator=check_bool, intentionally_undocumented=True
),
) -> HttpResponse:
# Extract the Tornado handler from the request

View File

@ -23,7 +23,7 @@ def clean_alert_words(alert_words: List[str]) -> List[str]:
def add_alert_words(
request: HttpRequest,
user_profile: UserProfile,
alert_words: List[str] = REQ(validator=check_list(check_capped_string(100))),
alert_words: List[str] = REQ(json_validator=check_list(check_capped_string(100))),
) -> HttpResponse:
do_add_alert_words(user_profile, clean_alert_words(alert_words))
return json_success({"alert_words": user_alert_words(user_profile)})
@ -33,7 +33,7 @@ def add_alert_words(
def remove_alert_words(
request: HttpRequest,
user_profile: UserProfile,
alert_words: List[str] = REQ(validator=check_list(check_string)),
alert_words: List[str] = REQ(json_validator=check_list(check_string)),
) -> HttpResponse:
do_remove_alert_words(user_profile, alert_words)
return json_success({"alert_words": user_alert_words(user_profile)})

View File

@ -102,7 +102,7 @@ def create_realm_custom_profile_field(
name: str = REQ(default="", converter=lambda x: x.strip()),
hint: str = REQ(default=""),
field_data: ProfileFieldData = REQ(default={}, converter=orjson.loads),
field_type: int = REQ(validator=check_int),
field_type: int = REQ(json_validator=check_int),
) -> HttpResponse:
validate_custom_profile_field(name, hint, field_type, field_data)
try:
@ -173,7 +173,7 @@ def update_realm_custom_profile_field(
def reorder_realm_custom_profile_fields(
request: HttpRequest,
user_profile: UserProfile,
order: List[int] = REQ(validator=check_list(check_int)),
order: List[int] = REQ(json_validator=check_list(check_int)),
) -> HttpResponse:
try_reorder_realm_custom_profile_fields(user_profile.realm, order)
return json_success()
@ -184,7 +184,7 @@ def reorder_realm_custom_profile_fields(
def remove_user_custom_profile_data(
request: HttpRequest,
user_profile: UserProfile,
data: List[int] = REQ(validator=check_list(check_int)),
data: List[int] = REQ(json_validator=check_list(check_int)),
) -> HttpResponse:
for field_id in data:
check_remove_custom_profile_field_value(user_profile, field_id)
@ -197,7 +197,7 @@ def update_user_custom_profile_data(
request: HttpRequest,
user_profile: UserProfile,
data: List[Dict[str, Union[int, str, List[int]]]] = REQ(
validator=check_list(
json_validator=check_list(
check_dict_only(
[
("id", check_int),

View File

@ -98,7 +98,7 @@ def check_send_webhook_fixture_message(
request: HttpRequest,
url: str = REQ(),
body: str = REQ(),
is_json: bool = REQ(validator=check_bool),
is_json: bool = REQ(json_validator=check_bool),
custom_headers: str = REQ(),
) -> HttpResponse:
try:

View File

@ -96,7 +96,9 @@ def fetch_drafts(request: HttpRequest, user_profile: UserProfile) -> HttpRespons
def create_drafts(
request: HttpRequest,
user_profile: UserProfile,
draft_dicts: List[Dict[str, Any]] = REQ("drafts", validator=check_list(draft_dict_validator)),
draft_dicts: List[Dict[str, Any]] = REQ(
"drafts", json_validator=check_list(draft_dict_validator)
),
) -> HttpResponse:
draft_objects = []
for draft_dict in draft_dicts:
@ -121,7 +123,7 @@ def edit_draft(
request: HttpRequest,
user_profile: UserProfile,
draft_id: int,
draft_dict: Dict[str, Any] = REQ("draft", validator=draft_dict_validator),
draft_dict: Dict[str, Any] = REQ("draft", json_validator=draft_dict_validator),
) -> HttpResponse:
try:
draft_object = Draft.objects.get(id=draft_id, user_profile=user_profile)

View File

@ -34,13 +34,13 @@ NarrowT = Iterable[Sequence[str]]
def events_register_backend(
request: HttpRequest,
user_profile: UserProfile,
apply_markdown: bool = REQ(default=False, validator=check_bool),
client_gravatar: bool = REQ(default=False, validator=check_bool),
slim_presence: bool = REQ(default=False, validator=check_bool),
all_public_streams: Optional[bool] = REQ(default=None, validator=check_bool),
include_subscribers: bool = REQ(default=False, validator=check_bool),
apply_markdown: bool = REQ(default=False, json_validator=check_bool),
client_gravatar: bool = REQ(default=False, json_validator=check_bool),
slim_presence: bool = REQ(default=False, json_validator=check_bool),
all_public_streams: Optional[bool] = REQ(default=None, json_validator=check_bool),
include_subscribers: bool = REQ(default=False, json_validator=check_bool),
client_capabilities: Optional[Dict[str, bool]] = REQ(
validator=check_dict(
json_validator=check_dict(
[
# This field was accidentally made required when it was added in v2.0.0-781;
# this was not realized until after the release of Zulip 2.1.2. (It remains
@ -56,11 +56,15 @@ def events_register_backend(
),
default=None,
),
event_types: Optional[Iterable[str]] = REQ(validator=check_list(check_string), default=None),
fetch_event_types: Optional[Iterable[str]] = REQ(
validator=check_list(check_string), default=None
event_types: Optional[Iterable[str]] = REQ(
json_validator=check_list(check_string), default=None
),
fetch_event_types: Optional[Iterable[str]] = REQ(
json_validator=check_list(check_string), default=None
),
narrow: NarrowT = REQ(
json_validator=check_list(check_list(check_string, length=2)), default=[]
),
narrow: NarrowT = REQ(validator=check_list(check_list(check_string, length=2)), default=[]),
queue_lifespan_secs: int = REQ(converter=int, default=0, documentation_pending=True),
) -> HttpResponse:
all_public_streams = _default_all_public_streams(user_profile, all_public_streams)

View File

@ -13,7 +13,7 @@ from zerver.models import UserProfile
@human_users_only
@has_request_variables
def mark_hotspot_as_read(
request: HttpRequest, user: UserProfile, hotspot: str = REQ(validator=check_string)
request: HttpRequest, user: UserProfile, hotspot: str = REQ(json_validator=check_string)
) -> HttpResponse:
if hotspot not in ALL_HOTSPOTS:
return json_error(_("Unknown hotspot: {}").format(hotspot))

View File

@ -35,8 +35,8 @@ def invite_users_backend(
request: HttpRequest,
user_profile: UserProfile,
invitee_emails_raw: str = REQ("invitee_emails"),
invite_as: int = REQ(validator=check_int, default=PreregistrationUser.INVITE_AS["MEMBER"]),
stream_ids: List[int] = REQ(validator=check_list(check_int)),
invite_as: int = REQ(json_validator=check_int, default=PreregistrationUser.INVITE_AS["MEMBER"]),
stream_ids: List[int] = REQ(json_validator=check_list(check_int)),
) -> HttpResponse:
if not user_profile.can_invite_others_to_realm():
@ -167,8 +167,8 @@ def resend_user_invite_email(
def generate_multiuse_invite_backend(
request: HttpRequest,
user_profile: UserProfile,
invite_as: int = REQ(validator=check_int, default=PreregistrationUser.INVITE_AS["MEMBER"]),
stream_ids: Sequence[int] = REQ(validator=check_list(check_int), default=[]),
invite_as: int = REQ(json_validator=check_int, default=PreregistrationUser.INVITE_AS["MEMBER"]),
stream_ids: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
) -> HttpResponse:
check_if_owner_required(invite_as, user_profile)

View File

@ -109,8 +109,8 @@ def update_message_backend(
propagate_mode: Optional[str] = REQ(
default="change_one", str_validator=check_string_in(PROPAGATE_MODE_VALUES)
),
send_notification_to_old_thread: bool = REQ(default=True, validator=check_bool),
send_notification_to_new_thread: bool = REQ(default=True, validator=check_bool),
send_notification_to_old_thread: bool = REQ(default=True, json_validator=check_bool),
send_notification_to_new_thread: bool = REQ(default=True, json_validator=check_bool),
content: Optional[str] = REQ(default=None),
) -> HttpResponse:
if not user_profile.realm.allow_message_editing:

View File

@ -927,10 +927,10 @@ def get_messages_backend(
num_after: int = REQ(converter=to_non_negative_int),
narrow: OptionalNarrowListT = REQ("narrow", converter=narrow_parameter, default=None),
use_first_unread_anchor_val: bool = REQ(
"use_first_unread_anchor", validator=check_bool, default=False
"use_first_unread_anchor", json_validator=check_bool, default=False
),
client_gravatar: bool = REQ(validator=check_bool, default=False),
apply_markdown: bool = REQ(validator=check_bool, default=True),
client_gravatar: bool = REQ(json_validator=check_bool, default=False),
apply_markdown: bool = REQ(json_validator=check_bool, default=True),
) -> HttpResponse:
anchor = parse_anchor_value(anchor_val, use_first_unread_anchor_val)
if num_before + num_after > MAX_MESSAGES_PER_FETCH:
@ -1300,7 +1300,7 @@ def post_process_limited_query(
def messages_in_narrow_backend(
request: HttpRequest,
user_profile: UserProfile,
msg_ids: List[int] = REQ(validator=check_list(check_int)),
msg_ids: List[int] = REQ(json_validator=check_list(check_int)),
narrow: OptionalNarrowListT = REQ(converter=narrow_parameter),
) -> HttpResponse:

View File

@ -31,7 +31,7 @@ def get_latest_update_message_flag_activity(user_profile: UserProfile) -> Option
def update_message_flags(
request: HttpRequest,
user_profile: UserProfile,
messages: List[int] = REQ(validator=check_list(check_int)),
messages: List[int] = REQ(json_validator=check_list(check_int)),
operation: str = REQ("op"),
flag: str = REQ(),
) -> HttpResponse:
@ -57,7 +57,7 @@ def mark_all_as_read(request: HttpRequest, user_profile: UserProfile) -> HttpRes
@has_request_variables
def mark_stream_as_read(
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(validator=check_int)
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(json_validator=check_int)
) -> HttpResponse:
stream, sub = access_stream_by_id(user_profile, stream_id)
count = do_mark_stream_messages_as_read(user_profile, stream.recipient_id)
@ -72,7 +72,7 @@ def mark_stream_as_read(
def mark_topic_as_read(
request: HttpRequest,
user_profile: UserProfile,
stream_id: int = REQ(validator=check_int),
stream_id: int = REQ(json_validator=check_int),
topic_name: str = REQ(),
) -> HttpResponse:
stream, sub = access_stream_by_id(user_profile, stream_id)

View File

@ -64,7 +64,7 @@ def unmute_topic(
def update_muted_topic(
request: HttpRequest,
user_profile: UserProfile,
stream_id: Optional[int] = REQ(validator=check_int, default=None),
stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
stream: Optional[str] = REQ(default=None),
topic: str = REQ(),
op: str = REQ(),

View File

@ -65,7 +65,7 @@ def get_presence_backend(
def update_user_status_backend(
request: HttpRequest,
user_profile: UserProfile,
away: Optional[bool] = REQ(validator=check_bool, default=None),
away: Optional[bool] = REQ(json_validator=check_bool, default=None),
status_text: Optional[str] = REQ(str_validator=check_capped_string(60), default=None),
) -> HttpResponse:
@ -91,9 +91,9 @@ def update_active_status_backend(
request: HttpRequest,
user_profile: UserProfile,
status: str = REQ(),
ping_only: bool = REQ(validator=check_bool, default=False),
new_user_input: bool = REQ(validator=check_bool, default=False),
slim_presence: bool = REQ(validator=check_bool, default=False),
ping_only: bool = REQ(json_validator=check_bool, default=False),
new_user_input: bool = REQ(json_validator=check_bool, default=False),
slim_presence: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
status_val = UserPresence.status_from_string(status)
if status_val is None:

View File

@ -41,70 +41,74 @@ from zerver.models import Realm, UserProfile
def update_realm(
request: HttpRequest,
user_profile: UserProfile,
name: Optional[str] = REQ(validator=check_string, default=None),
description: Optional[str] = REQ(validator=check_string, default=None),
emails_restricted_to_domains: Optional[bool] = REQ(validator=check_bool, default=None),
disallow_disposable_email_addresses: Optional[bool] = REQ(validator=check_bool, default=None),
invite_required: Optional[bool] = REQ(validator=check_bool, default=None),
invite_to_realm_policy: Optional[int] = REQ(
validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
name: Optional[str] = REQ(json_validator=check_string, default=None),
description: Optional[str] = REQ(json_validator=check_string, 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
),
name_changes_disabled: Optional[bool] = REQ(validator=check_bool, default=None),
email_changes_disabled: Optional[bool] = REQ(validator=check_bool, default=None),
avatar_changes_disabled: Optional[bool] = REQ(validator=check_bool, default=None),
inline_image_preview: Optional[bool] = REQ(validator=check_bool, default=None),
inline_url_embed_preview: Optional[bool] = REQ(validator=check_bool, default=None),
add_emoji_by_admins_only: Optional[bool] = REQ(validator=check_bool, default=None),
allow_message_deleting: Optional[bool] = REQ(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.COMMON_POLICY_TYPES), 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_emoji_by_admins_only: Optional[bool] = REQ(json_validator=check_bool, default=None),
allow_message_deleting: Optional[bool] = REQ(json_validator=check_bool, default=None),
message_content_delete_limit_seconds: Optional[int] = REQ(
converter=to_non_negative_int, default=None
),
allow_message_editing: Optional[bool] = REQ(validator=check_bool, default=None),
allow_community_topic_editing: Optional[bool] = REQ(validator=check_bool, default=None),
mandatory_topics: Optional[bool] = REQ(validator=check_bool, default=None),
allow_message_editing: Optional[bool] = REQ(json_validator=check_bool, default=None),
allow_community_topic_editing: Optional[bool] = REQ(json_validator=check_bool, default=None),
mandatory_topics: Optional[bool] = REQ(json_validator=check_bool, default=None),
message_content_edit_limit_seconds: Optional[int] = REQ(
converter=to_non_negative_int, default=None
),
allow_edit_history: Optional[bool] = REQ(validator=check_bool, default=None),
default_language: Optional[str] = REQ(validator=check_string, default=None),
allow_edit_history: Optional[bool] = REQ(json_validator=check_bool, default=None),
default_language: Optional[str] = REQ(json_validator=check_string, default=None),
waiting_period_threshold: Optional[int] = REQ(converter=to_non_negative_int, default=None),
authentication_methods: Optional[Dict[str, Any]] = REQ(validator=check_dict([]), default=None),
notifications_stream_id: Optional[int] = REQ(validator=check_int, default=None),
signup_notifications_stream_id: Optional[int] = REQ(validator=check_int, default=None),
message_retention_days_raw: Optional[Union[int, str]] = REQ(
"message_retention_days", validator=check_string_or_int, default=None
authentication_methods: Optional[Dict[str, Any]] = REQ(
json_validator=check_dict([]), default=None
),
send_welcome_emails: Optional[bool] = REQ(validator=check_bool, default=None),
digest_emails_enabled: Optional[bool] = REQ(validator=check_bool, default=None),
notifications_stream_id: Optional[int] = REQ(json_validator=check_int, default=None),
signup_notifications_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(
validator=check_bool, default=None
json_validator=check_bool, default=None
),
bot_creation_policy: Optional[int] = REQ(
validator=check_int_in(Realm.BOT_CREATION_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.BOT_CREATION_POLICY_TYPES), default=None
),
create_stream_policy: Optional[int] = REQ(
validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
),
invite_to_stream_policy: Optional[int] = REQ(
validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.COMMON_POLICY_TYPES), default=None
),
user_group_edit_policy: Optional[int] = REQ(
validator=check_int_in(Realm.USER_GROUP_EDIT_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.USER_GROUP_EDIT_POLICY_TYPES), default=None
),
private_message_policy: Optional[int] = REQ(
validator=check_int_in(Realm.PRIVATE_MESSAGE_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.PRIVATE_MESSAGE_POLICY_TYPES), default=None
),
wildcard_mention_policy: Optional[int] = REQ(
validator=check_int_in(Realm.WILDCARD_MENTION_POLICY_TYPES), default=None
json_validator=check_int_in(Realm.WILDCARD_MENTION_POLICY_TYPES), default=None
),
email_address_visibility: Optional[int] = REQ(
validator=check_int_in(Realm.EMAIL_ADDRESS_VISIBILITY_TYPES), default=None
json_validator=check_int_in(Realm.EMAIL_ADDRESS_VISIBILITY_TYPES), default=None
),
default_twenty_four_hour_time: Optional[bool] = REQ(validator=check_bool, default=None),
video_chat_provider: Optional[int] = REQ(validator=check_int, default=None),
default_code_block_language: Optional[str] = REQ(validator=check_string, default=None),
default_twenty_four_hour_time: Optional[bool] = REQ(json_validator=check_bool, default=None),
video_chat_provider: Optional[int] = REQ(json_validator=check_int, default=None),
default_code_block_language: Optional[str] = REQ(json_validator=check_string, default=None),
digest_weekday: Optional[int] = REQ(
validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None
json_validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None
),
) -> HttpResponse:
realm = user_profile.realm

View File

@ -21,8 +21,8 @@ def list_realm_domains(request: HttpRequest, user_profile: UserProfile) -> HttpR
def create_realm_domain(
request: HttpRequest,
user_profile: UserProfile,
domain: str = REQ(validator=check_string),
allow_subdomains: bool = REQ(validator=check_bool),
domain: str = REQ(json_validator=check_string),
allow_subdomains: bool = REQ(json_validator=check_bool),
) -> HttpResponse:
domain = domain.strip().lower()
try:
@ -43,7 +43,7 @@ def patch_realm_domain(
request: HttpRequest,
user_profile: UserProfile,
domain: str,
allow_subdomains: bool = REQ(validator=check_bool),
allow_subdomains: bool = REQ(json_validator=check_bool),
) -> HttpResponse:
try:
realm_domain = RealmDomain.objects.get(realm=user_profile.realm, domain=domain)

View File

@ -17,7 +17,7 @@ from zerver.models import UserProfile
@require_realm_admin
@has_request_variables
def upload_logo(
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(validator=check_bool)
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(json_validator=check_bool)
) -> HttpResponse:
user_profile.realm.ensure_not_on_limited_plan()
@ -40,7 +40,7 @@ def upload_logo(
@require_realm_admin
@has_request_variables
def delete_logo_backend(
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(validator=check_bool)
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(json_validator=check_bool)
) -> HttpResponse:
# We don't actually delete the logo because it might still
# be needed if the URL was cached and it is rewritten
@ -53,7 +53,7 @@ def delete_logo_backend(
@has_request_variables
def get_logo_backend(
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(validator=check_bool)
request: HttpRequest, user_profile: UserProfile, night: bool = REQ(json_validator=check_bool)
) -> HttpResponse:
url = get_realm_logo_url(user_profile.realm, night)

View File

@ -39,8 +39,8 @@ def add_realm_playground(
request: HttpRequest,
user_profile: UserProfile,
name: str = REQ(),
url_prefix: str = REQ(validator=check_url),
pygments_language: str = REQ(validator=check_pygments_language),
url_prefix: str = REQ(json_validator=check_url),
pygments_language: str = REQ(json_validator=check_pygments_language),
) -> HttpResponse:
try:
playground_id = do_add_realm_playground(

View File

@ -44,8 +44,8 @@ def report_send_times(
time: int = REQ(converter=to_non_negative_int),
received: int = REQ(converter=to_non_negative_int, default=-1),
displayed: int = REQ(converter=to_non_negative_int, default=-1),
locally_echoed: bool = REQ(validator=check_bool, default=False),
rendered_content_disparity: bool = REQ(validator=check_bool, default=False),
locally_echoed: bool = REQ(json_validator=check_bool, default=False),
rendered_content_disparity: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
received_str = "(unknown)"
if received > 0:
@ -109,11 +109,11 @@ def report_error(
user_profile: UserProfile,
message: str = REQ(),
stacktrace: str = REQ(),
ui_message: bool = REQ(validator=check_bool),
ui_message: bool = REQ(json_validator=check_bool),
user_agent: str = REQ(),
href: str = REQ(),
log: str = REQ(),
more_info: Mapping[str, Any] = REQ(validator=check_dict([]), default={}),
more_info: Mapping[str, Any] = REQ(json_validator=check_dict([]), default={}),
) -> HttpResponse:
"""Accepts an error report and stores in a queue for processing. The
actual error reports are later handled by do_report_error"""

View File

@ -19,7 +19,7 @@ from zerver.models import UserProfile
def update_storage(
request: HttpRequest,
user_profile: UserProfile,
storage: Dict[str, str] = REQ(validator=check_dict([], value_validator=check_string)),
storage: Dict[str, str] = REQ(json_validator=check_dict([], value_validator=check_string)),
) -> HttpResponse:
try:
set_bot_storage(user_profile, list(storage.items()))
@ -32,7 +32,7 @@ def update_storage(
def get_storage(
request: HttpRequest,
user_profile: UserProfile,
keys: Optional[List[str]] = REQ(validator=check_list(check_string), default=None),
keys: Optional[List[str]] = REQ(json_validator=check_list(check_string), default=None),
) -> HttpResponse:
keys = keys or get_keys_in_bot_storage(user_profile)
try:
@ -46,7 +46,7 @@ def get_storage(
def remove_storage(
request: HttpRequest,
user_profile: UserProfile,
keys: Optional[List[str]] = REQ(validator=check_list(check_string), default=None),
keys: Optional[List[str]] = REQ(json_validator=check_list(check_string), default=None),
) -> HttpResponse:
keys = keys or get_keys_in_bot_storage(user_profile)
try:

View File

@ -144,7 +144,7 @@ def deactivate_stream_backend(
@require_realm_admin
@has_request_variables
def add_default_stream(
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(validator=check_int)
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(json_validator=check_int)
) -> HttpResponse:
(stream, sub) = access_stream_by_id(user_profile, stream_id)
if stream.invite_only:
@ -160,7 +160,7 @@ def create_default_stream_group(
user_profile: UserProfile,
group_name: str = REQ(),
description: str = REQ(),
stream_names: List[str] = REQ(validator=check_list(check_string)),
stream_names: List[str] = REQ(json_validator=check_list(check_string)),
) -> None:
streams = []
for stream_name in stream_names:
@ -176,8 +176,8 @@ def update_default_stream_group_info(
request: HttpRequest,
user_profile: UserProfile,
group_id: int,
new_group_name: Optional[str] = REQ(validator=check_string, default=None),
new_description: Optional[str] = REQ(validator=check_string, default=None),
new_group_name: Optional[str] = REQ(json_validator=check_string, default=None),
new_description: Optional[str] = REQ(json_validator=check_string, default=None),
) -> None:
if not new_group_name and not new_description:
return json_error(_('You must pass "new_description" or "new_group_name".'))
@ -197,7 +197,7 @@ def update_default_stream_group_streams(
user_profile: UserProfile,
group_id: int,
op: str = REQ(),
stream_names: List[str] = REQ(validator=check_list(check_string)),
stream_names: List[str] = REQ(json_validator=check_list(check_string)),
) -> None:
group = access_default_stream_group_by_id(user_profile.realm, group_id)
streams = []
@ -227,7 +227,7 @@ def remove_default_stream_group(
@require_realm_admin
@has_request_variables
def remove_default_stream(
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(validator=check_int)
request: HttpRequest, user_profile: UserProfile, stream_id: int = REQ(json_validator=check_int)
) -> HttpResponse:
(stream, sub) = access_stream_by_id(
user_profile,
@ -244,17 +244,17 @@ def update_stream_backend(
user_profile: UserProfile,
stream_id: int,
description: Optional[str] = REQ(
validator=check_capped_string(Stream.MAX_DESCRIPTION_LENGTH), default=None
json_validator=check_capped_string(Stream.MAX_DESCRIPTION_LENGTH), default=None
),
is_private: Optional[bool] = REQ(validator=check_bool, default=None),
is_announcement_only: Optional[bool] = REQ(validator=check_bool, default=None),
is_private: Optional[bool] = REQ(json_validator=check_bool, default=None),
is_announcement_only: Optional[bool] = REQ(json_validator=check_bool, default=None),
stream_post_policy: Optional[int] = REQ(
validator=check_int_in(Stream.STREAM_POST_POLICY_TYPES), default=None
json_validator=check_int_in(Stream.STREAM_POST_POLICY_TYPES), default=None
),
history_public_to_subscribers: Optional[bool] = REQ(validator=check_bool, default=None),
new_name: Optional[str] = REQ(validator=check_string, default=None),
history_public_to_subscribers: Optional[bool] = REQ(json_validator=check_bool, default=None),
new_name: Optional[str] = REQ(json_validator=check_string, default=None),
message_retention_days: Optional[Union[int, str]] = REQ(
validator=check_string_or_int, default=None
json_validator=check_string_or_int, default=None
),
) -> HttpResponse:
# We allow realm administrators to to update the stream name and
@ -310,7 +310,7 @@ def update_stream_backend(
def list_subscriptions_backend(
request: HttpRequest,
user_profile: UserProfile,
include_subscribers: bool = REQ(validator=check_bool, default=False),
include_subscribers: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
subscribed, _ = gather_subscriptions(
user_profile,
@ -336,8 +336,8 @@ remove_subscriptions_schema = check_list(check_string)
def update_subscriptions_backend(
request: HttpRequest,
user_profile: UserProfile,
delete: Iterable[str] = REQ(validator=remove_subscriptions_schema, default=[]),
add: Iterable[Mapping[str, str]] = REQ(validator=add_subscriptions_schema, default=[]),
delete: Iterable[str] = REQ(json_validator=remove_subscriptions_schema, default=[]),
add: Iterable[Mapping[str, str]] = REQ(json_validator=add_subscriptions_schema, default=[]),
) -> HttpResponse:
if not add and not delete:
return json_error(_('Nothing to do. Specify at least one of "add" or "delete".'))
@ -380,9 +380,9 @@ check_principals: Validator[Union[List[str], List[int]]] = check_union(
def remove_subscriptions_backend(
request: HttpRequest,
user_profile: UserProfile,
streams_raw: Iterable[str] = REQ("subscriptions", validator=remove_subscriptions_schema),
streams_raw: Iterable[str] = REQ("subscriptions", json_validator=remove_subscriptions_schema),
principals: Optional[Union[List[str], List[int]]] = REQ(
validator=check_principals, default=None
json_validator=check_principals, default=None
),
) -> HttpResponse:
@ -447,23 +447,23 @@ def add_subscriptions_backend(
request: HttpRequest,
user_profile: UserProfile,
streams_raw: Iterable[Mapping[str, str]] = REQ(
"subscriptions", validator=add_subscriptions_schema
"subscriptions", json_validator=add_subscriptions_schema
),
invite_only: bool = REQ(validator=check_bool, default=False),
invite_only: bool = REQ(json_validator=check_bool, default=False),
stream_post_policy: int = REQ(
validator=check_int_in(Stream.STREAM_POST_POLICY_TYPES),
json_validator=check_int_in(Stream.STREAM_POST_POLICY_TYPES),
default=Stream.STREAM_POST_POLICY_EVERYONE,
),
history_public_to_subscribers: Optional[bool] = REQ(validator=check_bool, default=None),
history_public_to_subscribers: Optional[bool] = REQ(json_validator=check_bool, default=None),
message_retention_days: Union[str, int] = REQ(
validator=check_string_or_int, default=RETENTION_DEFAULT
json_validator=check_string_or_int, default=RETENTION_DEFAULT
),
announce: bool = REQ(validator=check_bool, default=False),
announce: bool = REQ(json_validator=check_bool, default=False),
principals: Union[Sequence[str], Sequence[int]] = REQ(
validator=check_principals,
json_validator=check_principals,
default=EMPTY_PRINCIPALS,
),
authorization_errors_fatal: bool = REQ(validator=check_bool, default=True),
authorization_errors_fatal: bool = REQ(json_validator=check_bool, default=True),
) -> HttpResponse:
realm = user_profile.realm
stream_dicts = []
@ -695,12 +695,12 @@ def get_subscribers_backend(
def get_streams_backend(
request: HttpRequest,
user_profile: UserProfile,
include_public: bool = REQ(validator=check_bool, default=True),
include_web_public: bool = REQ(validator=check_bool, default=False),
include_subscribed: bool = REQ(validator=check_bool, default=True),
include_all_active: bool = REQ(validator=check_bool, default=False),
include_default: bool = REQ(validator=check_bool, default=False),
include_owner_subscribed: bool = REQ(validator=check_bool, default=False),
include_public: bool = REQ(json_validator=check_bool, default=True),
include_web_public: bool = REQ(json_validator=check_bool, default=False),
include_subscribed: bool = REQ(json_validator=check_bool, default=True),
include_all_active: bool = REQ(json_validator=check_bool, default=False),
include_default: bool = REQ(json_validator=check_bool, default=False),
include_owner_subscribed: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
streams = do_get_streams(
@ -780,7 +780,7 @@ def json_stream_exists(
request: HttpRequest,
user_profile: UserProfile,
stream_name: str = REQ("stream"),
autosubscribe: bool = REQ(validator=check_bool, default=False),
autosubscribe: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
check_stream_name(stream_name)
@ -817,7 +817,7 @@ def json_get_stream_id(
def update_subscriptions_property(
request: HttpRequest,
user_profile: UserProfile,
stream_id: int = REQ(validator=check_int),
stream_id: int = REQ(json_validator=check_int),
property: str = REQ(),
value: str = REQ(),
) -> HttpResponse:
@ -832,7 +832,7 @@ def update_subscription_properties_backend(
request: HttpRequest,
user_profile: UserProfile,
subscription_data: List[Dict[str, Any]] = REQ(
validator=check_list(
json_validator=check_list(
check_dict(
[
("stream_id", check_int),

View File

@ -14,7 +14,7 @@ from zerver.models import UserProfile
def process_submessage(
request: HttpRequest,
user_profile: UserProfile,
message_id: int = REQ(validator=check_int),
message_id: int = REQ(json_validator=check_int),
msg_type: str = REQ(),
content: str = REQ(),
) -> HttpResponse:

View File

@ -10,7 +10,7 @@ from zerver.models import UserProfile
@human_users_only
@has_request_variables
def set_tutorial_status(
request: HttpRequest, user_profile: UserProfile, status: str = REQ(validator=check_string)
request: HttpRequest, user_profile: UserProfile, status: str = REQ(json_validator=check_string)
) -> HttpResponse:
if status == "started":
user_profile.tutorial_status = UserProfile.TUTORIAL_STARTED

View File

@ -21,7 +21,7 @@ def send_notification_backend(
"type", str_validator=check_string_in(VALID_MESSAGE_TYPES), default="private"
),
operator: str = REQ("op", str_validator=check_string_in(VALID_OPERATOR_TYPES)),
user_ids: List[int] = REQ("to", validator=check_list(check_int)),
user_ids: List[int] = REQ("to", json_validator=check_list(check_int)),
) -> HttpResponse:
if len(user_ids) == 0:
return json_error(_("Missing parameter: 'to' (recipient)"))

View File

@ -33,7 +33,7 @@ def add_user_group(
request: HttpRequest,
user_profile: UserProfile,
name: str = REQ(),
members: Sequence[int] = REQ(validator=check_list(check_int), default=[]),
members: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
description: str = REQ(),
) -> HttpResponse:
user_profiles = user_ids_to_users(members, user_profile.realm)
@ -53,7 +53,7 @@ def get_user_group(request: HttpRequest, user_profile: UserProfile) -> HttpRespo
def edit_user_group(
request: HttpRequest,
user_profile: UserProfile,
user_group_id: int = REQ(validator=check_int, path_only=True),
user_group_id: int = REQ(json_validator=check_int, path_only=True),
name: str = REQ(default=""),
description: str = REQ(default=""),
) -> HttpResponse:
@ -76,7 +76,7 @@ def edit_user_group(
def delete_user_group(
request: HttpRequest,
user_profile: UserProfile,
user_group_id: int = REQ(validator=check_int, path_only=True),
user_group_id: int = REQ(json_validator=check_int, path_only=True),
) -> HttpResponse:
check_delete_user_group(user_group_id, user_profile)
@ -88,9 +88,9 @@ def delete_user_group(
def update_user_group_backend(
request: HttpRequest,
user_profile: UserProfile,
user_group_id: int = REQ(validator=check_int, path_only=True),
delete: Sequence[int] = REQ(validator=check_list(check_int), default=[]),
add: Sequence[int] = REQ(validator=check_list(check_int), default=[]),
user_group_id: int = REQ(json_validator=check_int, path_only=True),
delete: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
add: Sequence[int] = REQ(json_validator=check_list(check_int), default=[]),
) -> HttpResponse:
if not add and not delete:
return json_error(_('Nothing to do. Specify at least one of "add" or "delete".'))

View File

@ -188,25 +188,27 @@ default_view_options = ["recent_topics", "all_messages"]
def update_display_settings_backend(
request: HttpRequest,
user_profile: UserProfile,
twenty_four_hour_time: Optional[bool] = REQ(validator=check_bool, default=None),
dense_mode: Optional[bool] = REQ(validator=check_bool, default=None),
starred_message_counts: Optional[bool] = REQ(validator=check_bool, default=None),
fluid_layout_width: Optional[bool] = REQ(validator=check_bool, default=None),
high_contrast_mode: Optional[bool] = REQ(validator=check_bool, default=None),
twenty_four_hour_time: Optional[bool] = REQ(json_validator=check_bool, default=None),
dense_mode: Optional[bool] = REQ(json_validator=check_bool, default=None),
starred_message_counts: Optional[bool] = REQ(json_validator=check_bool, default=None),
fluid_layout_width: Optional[bool] = REQ(json_validator=check_bool, default=None),
high_contrast_mode: Optional[bool] = REQ(json_validator=check_bool, default=None),
color_scheme: Optional[int] = REQ(
validator=check_int_in(UserProfile.COLOR_SCHEME_CHOICES), default=None
json_validator=check_int_in(UserProfile.COLOR_SCHEME_CHOICES), default=None
),
translate_emoticons: Optional[bool] = REQ(validator=check_bool, default=None),
default_language: Optional[str] = REQ(validator=check_string, default=None),
translate_emoticons: Optional[bool] = REQ(json_validator=check_bool, default=None),
default_language: Optional[str] = REQ(json_validator=check_string, default=None),
default_view: Optional[str] = REQ(
validator=check_string_in(default_view_options), default=None
json_validator=check_string_in(default_view_options), default=None
),
left_side_userlist: Optional[bool] = REQ(validator=check_bool, default=None),
emojiset: Optional[str] = REQ(validator=check_string_in(emojiset_choices), default=None),
left_side_userlist: Optional[bool] = REQ(json_validator=check_bool, default=None),
emojiset: Optional[str] = REQ(json_validator=check_string_in(emojiset_choices), default=None),
demote_inactive_streams: Optional[int] = REQ(
validator=check_int_in(UserProfile.DEMOTE_STREAMS_CHOICES), default=None
json_validator=check_int_in(UserProfile.DEMOTE_STREAMS_CHOICES), default=None
),
timezone: Optional[str] = REQ(
json_validator=check_string_in(pytz.all_timezones_set), default=None
),
timezone: Optional[str] = REQ(validator=check_string_in(pytz.all_timezones_set), default=None),
) -> HttpResponse:
# We can't use REQ for this widget because
@ -230,26 +232,38 @@ def update_display_settings_backend(
def json_change_notify_settings(
request: HttpRequest,
user_profile: UserProfile,
enable_stream_desktop_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_stream_email_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_stream_push_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_stream_audible_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
wildcard_mentions_notify: Optional[bool] = REQ(validator=check_bool, default=None),
notification_sound: Optional[str] = REQ(validator=check_string, default=None),
enable_desktop_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_sounds: Optional[bool] = REQ(validator=check_bool, default=None),
enable_offline_email_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_offline_push_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_online_push_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
enable_digest_emails: Optional[bool] = REQ(validator=check_bool, default=None),
enable_login_emails: Optional[bool] = REQ(validator=check_bool, default=None),
message_content_in_email_notifications: Optional[bool] = REQ(
validator=check_bool, default=None
enable_stream_desktop_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
pm_content_in_desktop_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
desktop_icon_count_display: Optional[int] = REQ(validator=check_int, default=None),
realm_name_in_notifications: Optional[bool] = REQ(validator=check_bool, default=None),
presence_enabled: Optional[bool] = REQ(validator=check_bool, default=None),
enable_stream_email_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
enable_stream_push_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
enable_stream_audible_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
wildcard_mentions_notify: Optional[bool] = REQ(json_validator=check_bool, default=None),
notification_sound: Optional[str] = REQ(json_validator=check_string, default=None),
enable_desktop_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
enable_sounds: Optional[bool] = REQ(json_validator=check_bool, default=None),
enable_offline_email_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
enable_offline_push_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
enable_online_push_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
enable_digest_emails: Optional[bool] = REQ(json_validator=check_bool, default=None),
enable_login_emails: Optional[bool] = REQ(json_validator=check_bool, default=None),
message_content_in_email_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
pm_content_in_desktop_notifications: Optional[bool] = REQ(
json_validator=check_bool, default=None
),
desktop_icon_count_display: Optional[int] = REQ(json_validator=check_int, default=None),
realm_name_in_notifications: Optional[bool] = REQ(json_validator=check_bool, default=None),
presence_enabled: Optional[bool] = REQ(json_validator=check_bool, default=None),
) -> HttpResponse:
result = {}
@ -326,7 +340,9 @@ def regenerate_api_key(request: HttpRequest, user_profile: UserProfile) -> HttpR
@human_users_only
@has_request_variables
def change_enter_sends(
request: HttpRequest, user_profile: UserProfile, enter_sends: bool = REQ(validator=check_bool)
request: HttpRequest,
user_profile: UserProfile,
enter_sends: bool = REQ(json_validator=check_bool),
) -> HttpResponse:
do_change_enter_sends(user_profile, enter_sends)
return json_success()

View File

@ -157,16 +157,16 @@ def update_user_backend(
request: HttpRequest,
user_profile: UserProfile,
user_id: int,
full_name: Optional[str] = REQ(default=None, validator=check_string),
full_name: Optional[str] = REQ(default=None, json_validator=check_string),
role: Optional[int] = REQ(
default=None,
validator=check_int_in(
json_validator=check_int_in(
UserProfile.ROLE_TYPES,
),
),
profile_data: Optional[List[Dict[str, Optional[Union[int, str, List[int]]]]]] = REQ(
default=None,
validator=check_profile_data,
json_validator=check_profile_data,
),
) -> HttpResponse:
target = access_user_by_id(
@ -260,15 +260,15 @@ def patch_bot_backend(
user_profile: UserProfile,
bot_id: int,
full_name: Optional[str] = REQ(default=None),
bot_owner_id: Optional[int] = REQ(validator=check_int, default=None),
bot_owner_id: Optional[int] = REQ(json_validator=check_int, default=None),
config_data: Optional[Dict[str, str]] = REQ(
default=None, validator=check_dict(value_validator=check_string)
default=None, json_validator=check_dict(value_validator=check_string)
),
service_payload_url: Optional[str] = REQ(validator=check_url, default=None),
service_interface: int = REQ(validator=check_int, default=1),
service_payload_url: Optional[str] = REQ(json_validator=check_url, default=None),
service_interface: int = REQ(json_validator=check_int, default=1),
default_sending_stream: Optional[str] = REQ(default=None),
default_events_register_stream: Optional[str] = REQ(default=None),
default_all_public_streams: Optional[bool] = REQ(default=None, validator=check_bool),
default_all_public_streams: Optional[bool] = REQ(default=None, json_validator=check_bool),
) -> HttpResponse:
bot = access_bot_by_id(user_profile, bot_id)
@ -363,18 +363,18 @@ def add_bot_backend(
user_profile: UserProfile,
full_name_raw: str = REQ("full_name"),
short_name_raw: str = REQ("short_name"),
bot_type: int = REQ(validator=check_int, default=UserProfile.DEFAULT_BOT),
payload_url: str = REQ(validator=check_url, default=""),
bot_type: int = REQ(json_validator=check_int, default=UserProfile.DEFAULT_BOT),
payload_url: str = REQ(json_validator=check_url, default=""),
service_name: Optional[str] = REQ(default=None),
config_data: Dict[str, str] = REQ(
default={}, validator=check_dict(value_validator=check_string)
default={}, json_validator=check_dict(value_validator=check_string)
),
interface_type: int = REQ(validator=check_int, default=Service.GENERIC),
interface_type: int = REQ(json_validator=check_int, default=Service.GENERIC),
default_sending_stream_name: Optional[str] = REQ("default_sending_stream", default=None),
default_events_register_stream_name: Optional[str] = REQ(
"default_events_register_stream", default=None
),
default_all_public_streams: Optional[bool] = REQ(validator=check_bool, default=None),
default_all_public_streams: Optional[bool] = REQ(json_validator=check_bool, default=None),
) -> HttpResponse:
short_name = check_short_name(short_name_raw)
if bot_type != UserProfile.INCOMING_WEBHOOK_BOT:
@ -522,8 +522,8 @@ def get_members_backend(
request: HttpRequest,
user_profile: UserProfile,
user_id: Optional[int] = None,
include_custom_profile_fields: bool = REQ(validator=check_bool, default=False),
client_gravatar: bool = REQ(validator=check_bool, default=False),
include_custom_profile_fields: bool = REQ(json_validator=check_bool, default=False),
client_gravatar: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
"""
The client_gravatar field here is set to True if clients can compute
@ -629,8 +629,8 @@ def get_profile_backend(request: HttpRequest, user_profile: UserProfile) -> Http
def get_subscription_backend(
request: HttpRequest,
user_profile: UserProfile,
user_id: int = REQ(validator=check_int, path_only=True),
stream_id: int = REQ(validator=check_int, path_only=True),
user_id: int = REQ(json_validator=check_int, path_only=True),
stream_id: int = REQ(json_validator=check_int, path_only=True),
) -> HttpResponse:
target_user = access_user_by_id(user_profile, user_id, for_admin=False)
(stream, sub) = access_stream_by_id(user_profile, stream_id)
@ -645,8 +645,8 @@ def get_user_by_email(
request: HttpRequest,
user_profile: UserProfile,
email: str,
include_custom_profile_fields: bool = REQ(validator=check_bool, default=False),
client_gravatar: bool = REQ(validator=check_bool, default=False),
include_custom_profile_fields: bool = REQ(json_validator=check_bool, default=False),
client_gravatar: bool = REQ(json_validator=check_bool, default=False),
) -> HttpResponse:
realm = user_profile.realm

View File

@ -91,7 +91,7 @@ def register_zoom_user(request: HttpRequest) -> HttpResponse:
def complete_zoom_user(
request: HttpRequest,
state: Dict[str, str] = REQ(
validator=check_dict([("realm", check_string)], value_validator=check_string)
json_validator=check_dict([("realm", check_string)], value_validator=check_string)
),
) -> HttpResponse:
if get_subdomain(request) != state["realm"]:
@ -105,7 +105,7 @@ def complete_zoom_user_in_realm(
request: HttpRequest,
code: str = REQ(),
state: Dict[str, str] = REQ(
validator=check_dict([("sid", check_string)], value_validator=check_string)
json_validator=check_dict([("sid", check_string)], value_validator=check_string)
),
) -> HttpResponse:
if not constant_time_compare(state["sid"], get_zoom_sid(request)):
@ -207,9 +207,9 @@ def get_bigbluebutton_url(request: HttpRequest, user_profile: UserProfile) -> Ht
@has_request_variables
def join_bigbluebutton(
request: HttpRequest,
meeting_id: str = REQ(validator=check_string),
password: str = REQ(validator=check_string),
checksum: str = REQ(validator=check_string),
meeting_id: str = REQ(json_validator=check_string),
password: str = REQ(json_validator=check_string),
checksum: str = REQ(json_validator=check_string),
) -> HttpResponse:
if settings.BIG_BLUE_BUTTON_URL is None or settings.BIG_BLUE_BUTTON_SECRET is None:
return json_error(_("Big Blue Button is not configured."))

View File

@ -79,7 +79,7 @@ def beanstalk_decoder(view_func: ViewFuncT) -> ViewFuncT:
def api_beanstalk_webhook(
request: HttpRequest,
user_profile: UserProfile,
payload: Dict[str, Any] = REQ(validator=check_dict([])),
payload: Dict[str, Any] = REQ(json_validator=check_dict([])),
branches: Optional[str] = REQ(default=None),
) -> HttpResponse:
# Beanstalk supports both SVN and Git repositories

View File

@ -16,7 +16,7 @@ from zerver.models import UserProfile
def api_bitbucket_webhook(
request: HttpRequest,
user_profile: UserProfile,
payload: Mapping[str, Any] = REQ(validator=check_dict([])),
payload: Mapping[str, Any] = REQ(json_validator=check_dict([])),
branches: Optional[str] = REQ(default=None),
) -> HttpResponse:
repository = payload["repository"]

View File

@ -398,7 +398,7 @@ def api_gitlab_webhook(
user_profile: UserProfile,
payload: Dict[str, Any] = REQ(argument_type="body"),
branches: Optional[str] = REQ(default=None),
use_merge_request_title: bool = REQ(default=True, validator=check_bool),
use_merge_request_title: bool = REQ(default=True, json_validator=check_bool),
user_specified_topic: Optional[str] = REQ("topic", default=None),
) -> HttpResponse:
event = get_event(request, payload, branches)

View File

@ -24,7 +24,7 @@ def api_papertrail_webhook(
request: HttpRequest,
user_profile: UserProfile,
payload: Dict[str, Any] = REQ(
validator=check_dict(
json_validator=check_dict(
[
("events", check_list(check_dict([]))),
(

View File

@ -20,8 +20,8 @@ def api_transifex_webhook(
project: str = REQ(),
resource: str = REQ(),
language: str = REQ(),
translated: Optional[int] = REQ(validator=check_int, default=None),
reviewed: Optional[int] = REQ(validator=check_int, default=None),
translated: Optional[int] = REQ(json_validator=check_int, default=None),
reviewed: Optional[int] = REQ(json_validator=check_int, default=None),
) -> HttpResponse:
subject = f"{project} in {language}"
if translated:

View File

@ -25,10 +25,10 @@ Details: [changes]({}), [build log]({})"""
def api_travis_webhook(
request: HttpRequest,
user_profile: UserProfile,
ignore_pull_requests: bool = REQ(validator=check_bool, default=True),
ignore_pull_requests: bool = REQ(json_validator=check_bool, default=True),
message: Dict[str, object] = REQ(
"payload",
validator=check_dict(
json_validator=check_dict(
[
("author_name", check_string),
("status_message", check_string),

View File

@ -109,9 +109,9 @@ def register_remote_server(
def register_remote_push_device(
request: HttpRequest,
entity: Union[UserProfile, RemoteZulipServer],
user_id: int = REQ(validator=check_int),
user_id: int = REQ(json_validator=check_int),
token: str = REQ(),
token_kind: int = REQ(validator=check_int),
token_kind: int = REQ(json_validator=check_int),
ios_app_id: Optional[str] = None,
) -> HttpResponse:
server = validate_bouncer_token_request(entity, token, token_kind)
@ -138,8 +138,8 @@ def unregister_remote_push_device(
request: HttpRequest,
entity: Union[UserProfile, RemoteZulipServer],
token: str = REQ(),
token_kind: int = REQ(validator=check_int),
user_id: int = REQ(validator=check_int),
token_kind: int = REQ(json_validator=check_int),
user_id: int = REQ(json_validator=check_int),
ios_app_id: Optional[str] = None,
) -> HttpResponse:
server = validate_bouncer_token_request(entity, token, token_kind)
@ -156,7 +156,7 @@ def unregister_remote_push_device(
def unregister_all_remote_push_devices(
request: HttpRequest,
entity: Union[UserProfile, RemoteZulipServer],
user_id: int = REQ(validator=check_int),
user_id: int = REQ(json_validator=check_int),
) -> HttpResponse:
server = validate_entity(entity)
RemotePushDeviceToken.objects.filter(user_id=user_id, server=server).delete()
@ -236,7 +236,7 @@ def remote_server_post_analytics(
request: HttpRequest,
entity: Union[UserProfile, RemoteZulipServer],
realm_counts: List[Dict[str, Any]] = REQ(
validator=check_list(
json_validator=check_list(
check_dict_only(
[
("property", check_string),
@ -250,7 +250,7 @@ def remote_server_post_analytics(
)
),
installation_counts: List[Dict[str, Any]] = REQ(
validator=check_list(
json_validator=check_list(
check_dict_only(
[
("property", check_string),
@ -263,7 +263,7 @@ def remote_server_post_analytics(
)
),
realmauditlog_rows: Optional[List[Dict[str, Any]]] = REQ(
validator=check_list(
json_validator=check_list(
check_dict_only(
[
("id", check_int),