diff --git a/corporate/views.py b/corporate/views.py index 69ef140315..6dcd12bc2f 100644 --- a/corporate/views.py +++ b/corporate/views.py @@ -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) diff --git a/docs/tutorials/new-feature-tutorial.md b/docs/tutorials/new-feature-tutorial.md index a8023e0ba1..ecc032fcbb 100644 --- a/docs/tutorials/new-feature-tutorial.md +++ b/docs/tutorials/new-feature-tutorial.md @@ -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), # ... ): # ... diff --git a/docs/tutorials/writing-views.md b/docs/tutorials/writing-views.md index ce047987e0..2c99efbcba 100644 --- a/docs/tutorials/writing-views.md +++ b/docs/tutorials/writing-views.md @@ -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 diff --git a/zerver/lib/request.py b/zerver/lib/request.py index 23eda89623..a37878bdee 100644 --- a/zerver/lib/request.py +++ b/zerver/lib/request.py @@ -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) diff --git a/zerver/tests/test_decorators.py b/zerver/tests/test_decorators.py index 8788a3e043..a724674e42 100644 --- a/zerver/tests/test_decorators.py +++ b/zerver/tests/test_decorators.py @@ -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) diff --git a/zerver/tornado/views.py b/zerver/tornado/views.py index 9047686429..63ee24b7ad 100644 --- a/zerver/tornado/views.py +++ b/zerver/tornado/views.py @@ -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 diff --git a/zerver/views/alert_words.py b/zerver/views/alert_words.py index 21e7e74f4a..4a0f707e13 100644 --- a/zerver/views/alert_words.py +++ b/zerver/views/alert_words.py @@ -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)}) diff --git a/zerver/views/custom_profile_fields.py b/zerver/views/custom_profile_fields.py index 4d90e48385..006156ad7c 100644 --- a/zerver/views/custom_profile_fields.py +++ b/zerver/views/custom_profile_fields.py @@ -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), diff --git a/zerver/views/development/integrations.py b/zerver/views/development/integrations.py index a44e0bb7fb..4c18d6d24a 100644 --- a/zerver/views/development/integrations.py +++ b/zerver/views/development/integrations.py @@ -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: diff --git a/zerver/views/drafts.py b/zerver/views/drafts.py index 2f1fcaf1ed..189b8c9b20 100644 --- a/zerver/views/drafts.py +++ b/zerver/views/drafts.py @@ -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) diff --git a/zerver/views/events_register.py b/zerver/views/events_register.py index fef1d3ac88..716b86c1ea 100644 --- a/zerver/views/events_register.py +++ b/zerver/views/events_register.py @@ -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) diff --git a/zerver/views/hotspots.py b/zerver/views/hotspots.py index 17045dbb66..a622a13880 100644 --- a/zerver/views/hotspots.py +++ b/zerver/views/hotspots.py @@ -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)) diff --git a/zerver/views/invite.py b/zerver/views/invite.py index 010f8ccf70..01bc7a5c03 100644 --- a/zerver/views/invite.py +++ b/zerver/views/invite.py @@ -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) diff --git a/zerver/views/message_edit.py b/zerver/views/message_edit.py index 406a8c299c..e99e1c1fcd 100644 --- a/zerver/views/message_edit.py +++ b/zerver/views/message_edit.py @@ -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: diff --git a/zerver/views/message_fetch.py b/zerver/views/message_fetch.py index a185bfd423..f50f446591 100644 --- a/zerver/views/message_fetch.py +++ b/zerver/views/message_fetch.py @@ -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: diff --git a/zerver/views/message_flags.py b/zerver/views/message_flags.py index fc88c783e4..f80d974b2a 100644 --- a/zerver/views/message_flags.py +++ b/zerver/views/message_flags.py @@ -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) diff --git a/zerver/views/muting.py b/zerver/views/muting.py index 0c62b3591e..bc35cfe767 100644 --- a/zerver/views/muting.py +++ b/zerver/views/muting.py @@ -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(), diff --git a/zerver/views/presence.py b/zerver/views/presence.py index bd373cb2a8..906318f949 100644 --- a/zerver/views/presence.py +++ b/zerver/views/presence.py @@ -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: diff --git a/zerver/views/realm.py b/zerver/views/realm.py index e0ef063642..41fdf712cb 100644 --- a/zerver/views/realm.py +++ b/zerver/views/realm.py @@ -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 diff --git a/zerver/views/realm_domains.py b/zerver/views/realm_domains.py index 212b143de7..e09acee1ac 100644 --- a/zerver/views/realm_domains.py +++ b/zerver/views/realm_domains.py @@ -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) diff --git a/zerver/views/realm_logo.py b/zerver/views/realm_logo.py index d03a441cdb..b73fd5abee 100644 --- a/zerver/views/realm_logo.py +++ b/zerver/views/realm_logo.py @@ -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) diff --git a/zerver/views/realm_playgrounds.py b/zerver/views/realm_playgrounds.py index ccfdb787ec..6e22442e1c 100644 --- a/zerver/views/realm_playgrounds.py +++ b/zerver/views/realm_playgrounds.py @@ -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( diff --git a/zerver/views/report.py b/zerver/views/report.py index 43609fb393..833ecc262a 100644 --- a/zerver/views/report.py +++ b/zerver/views/report.py @@ -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""" diff --git a/zerver/views/storage.py b/zerver/views/storage.py index 8bf6f2f0e3..fbbf6c5a8c 100644 --- a/zerver/views/storage.py +++ b/zerver/views/storage.py @@ -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: diff --git a/zerver/views/streams.py b/zerver/views/streams.py index d16567032b..37d06fdd17 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -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), diff --git a/zerver/views/submessage.py b/zerver/views/submessage.py index e5c66d4dd5..f58f8c4653 100644 --- a/zerver/views/submessage.py +++ b/zerver/views/submessage.py @@ -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: diff --git a/zerver/views/tutorial.py b/zerver/views/tutorial.py index bf6bfda35d..d772f99b73 100644 --- a/zerver/views/tutorial.py +++ b/zerver/views/tutorial.py @@ -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 diff --git a/zerver/views/typing.py b/zerver/views/typing.py index 33ac880c61..bd4d03384d 100644 --- a/zerver/views/typing.py +++ b/zerver/views/typing.py @@ -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)")) diff --git a/zerver/views/user_groups.py b/zerver/views/user_groups.py index dc4f34e665..aac204d347 100644 --- a/zerver/views/user_groups.py +++ b/zerver/views/user_groups.py @@ -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".')) diff --git a/zerver/views/user_settings.py b/zerver/views/user_settings.py index ae15e90de7..5bdc1f7dab 100644 --- a/zerver/views/user_settings.py +++ b/zerver/views/user_settings.py @@ -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() diff --git a/zerver/views/users.py b/zerver/views/users.py index 8a468dc34f..cb2ee265fb 100644 --- a/zerver/views/users.py +++ b/zerver/views/users.py @@ -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 diff --git a/zerver/views/video_calls.py b/zerver/views/video_calls.py index f2a7bf91b3..fcd91ab7e8 100644 --- a/zerver/views/video_calls.py +++ b/zerver/views/video_calls.py @@ -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.")) diff --git a/zerver/webhooks/beanstalk/view.py b/zerver/webhooks/beanstalk/view.py index 60232478f7..802f5adbdf 100644 --- a/zerver/webhooks/beanstalk/view.py +++ b/zerver/webhooks/beanstalk/view.py @@ -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 diff --git a/zerver/webhooks/bitbucket/view.py b/zerver/webhooks/bitbucket/view.py index af5527583c..e1f784a21c 100644 --- a/zerver/webhooks/bitbucket/view.py +++ b/zerver/webhooks/bitbucket/view.py @@ -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"] diff --git a/zerver/webhooks/gitlab/view.py b/zerver/webhooks/gitlab/view.py index 8fab7bedb3..9e48d03182 100644 --- a/zerver/webhooks/gitlab/view.py +++ b/zerver/webhooks/gitlab/view.py @@ -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) diff --git a/zerver/webhooks/papertrail/view.py b/zerver/webhooks/papertrail/view.py index 957e33df42..80b2f5bbe9 100644 --- a/zerver/webhooks/papertrail/view.py +++ b/zerver/webhooks/papertrail/view.py @@ -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([]))), ( diff --git a/zerver/webhooks/transifex/view.py b/zerver/webhooks/transifex/view.py index 575700d2e8..873328b271 100644 --- a/zerver/webhooks/transifex/view.py +++ b/zerver/webhooks/transifex/view.py @@ -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: diff --git a/zerver/webhooks/travis/view.py b/zerver/webhooks/travis/view.py index 803b0e15ab..492ebe0377 100644 --- a/zerver/webhooks/travis/view.py +++ b/zerver/webhooks/travis/view.py @@ -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), diff --git a/zilencer/views.py b/zilencer/views.py index b2f2a67736..a3a69d0bd2 100644 --- a/zilencer/views.py +++ b/zilencer/views.py @@ -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),