mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 00:23:49 +00:00
events: Clean up logic for spectator events_register parameters.
Unfortunately, doing so requires forking common API documentation text, since we're not making any changes to other endpoints that don't allow unauthenticated requests at all. Follow-up on #21995.
This commit is contained in:
@@ -20,6 +20,13 @@ format used by the Zulip server that they are interacting with.
|
||||
|
||||
## Changes in Zulip 6.0
|
||||
|
||||
**Feature level 149**
|
||||
|
||||
* [`POST /register`](/api/register-queue): The `client_gravatar` and
|
||||
`include_subscribers` parameters now return an error for
|
||||
[unauthenticated requests](/help/public-access-option) if an
|
||||
unsupported value is requested by the client.
|
||||
|
||||
**Feature level 148**
|
||||
|
||||
* [`POST /users/me/status`](/api/update-status):
|
||||
|
||||
@@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
|
||||
# Changes should be accompanied by documentation explaining what the
|
||||
# new level means in templates/zerver/api/changelog.md, as well as
|
||||
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
||||
API_FEATURE_LEVEL = 148
|
||||
API_FEATURE_LEVEL = 149
|
||||
|
||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||
# only when going from an old version of the code to a newer version. Bump
|
||||
|
||||
@@ -1396,27 +1396,25 @@ def do_events_register(
|
||||
event_types_set = None
|
||||
|
||||
if user_profile is None:
|
||||
# TODO: Unify this with the below code path once if/when we
|
||||
# support requesting an event queue for spectators.
|
||||
#
|
||||
# Doing so likely has a prerequisite of making this function's
|
||||
# caller enforce client_gravatar=False,
|
||||
# include_subscribers=False and include_streams=False.
|
||||
# TODO: Unify the two fetch_initial_state_data code paths.
|
||||
assert client_gravatar is False
|
||||
assert include_subscribers is False
|
||||
assert include_streams is False
|
||||
ret = fetch_initial_state_data(
|
||||
user_profile,
|
||||
realm=realm,
|
||||
event_types=event_types_set,
|
||||
queue_id=None,
|
||||
# Force client_gravatar=False for security reasons.
|
||||
client_gravatar=False,
|
||||
client_gravatar=client_gravatar,
|
||||
user_avatar_url_field_optional=user_avatar_url_field_optional,
|
||||
user_settings_object=user_settings_object,
|
||||
# slim_presence is a noop, because presence is not included.
|
||||
slim_presence=True,
|
||||
# Force include_subscribers=False for security reasons.
|
||||
include_subscribers=False,
|
||||
include_subscribers=include_subscribers,
|
||||
# Force include_streams=False for security reasons.
|
||||
include_streams=False,
|
||||
include_streams=include_streams,
|
||||
spectator_requested_language=spectator_requested_language,
|
||||
)
|
||||
|
||||
|
||||
@@ -9551,7 +9551,50 @@ paths:
|
||||
type: boolean
|
||||
default: false
|
||||
example: true
|
||||
- $ref: "#/components/parameters/ClientGravatar"
|
||||
- name: client_gravatar
|
||||
in: query
|
||||
description: |
|
||||
Whether the client supports computing gravatars URLs. If
|
||||
enabled, `avatar_url` will be included in the response only
|
||||
if there is a Zulip avatar, and will be `null` for users who
|
||||
are using gravatar as their avatar. This option
|
||||
significantly reduces the compressed size of user data,
|
||||
since gravatar URLs are long, random strings and thus do not
|
||||
compress well. The `client_gravatar` field is set to `true` if
|
||||
clients can compute their own gravatars.
|
||||
|
||||
The default value is `true` for authenticated requests and
|
||||
`false` for [unauthenticated
|
||||
requests](/help/public-access-option). Passing `true` in
|
||||
an unauthenticated request is an error.
|
||||
|
||||
**Changes**: Before Zulip 6.0 (feature level 149), this
|
||||
parameter was silently ignored and processed as though it
|
||||
were `false` in unauthenticated requests.
|
||||
schema:
|
||||
type: boolean
|
||||
example: false
|
||||
- name: include_subscribers
|
||||
in: query
|
||||
description: |
|
||||
Whether each returned stream object should include a `subscribers`
|
||||
field containing a list of the user IDs of its subscribers.
|
||||
|
||||
(This may be significantly slower in organizations with
|
||||
thousands of users subscribed to many streams.)
|
||||
|
||||
Passing `true` in an [unauthenticated
|
||||
request](/help/public-access-option) is an error.
|
||||
|
||||
**Changes**: Before Zulip 6.0 (feature level 149), this
|
||||
parameter was silently ignored and processed as though it
|
||||
were `false` in unauthenticated requests.
|
||||
|
||||
New in Zulip 2.1.0.
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
example: true
|
||||
- name: slim_presence
|
||||
in: query
|
||||
description: |
|
||||
@@ -9565,7 +9608,6 @@ paths:
|
||||
example: true
|
||||
- $ref: "#/components/parameters/Event_types"
|
||||
- $ref: "#/components/parameters/AllPublicStreams"
|
||||
- $ref: "#/components/parameters/IncludeSubscribers"
|
||||
- name: client_capabilities
|
||||
in: query
|
||||
description: |
|
||||
|
||||
@@ -151,18 +151,38 @@ class EventsEndpointTest(ZulipTestCase):
|
||||
# Verify that POST /register works for spectators, but not for
|
||||
# normal users.
|
||||
with self.settings(WEB_PUBLIC_STREAMS_ENABLED=False):
|
||||
result = self.client_post("/json/register", dict())
|
||||
result = self.client_post("/json/register")
|
||||
self.assert_json_error(
|
||||
result,
|
||||
"Not logged in: API authentication or user session required",
|
||||
status_code=401,
|
||||
)
|
||||
|
||||
result = self.client_post("/json/register", dict())
|
||||
result = self.client_post("/json/register")
|
||||
result_dict = self.assert_json_success(result)
|
||||
self.assertEqual(result_dict["queue_id"], None)
|
||||
self.assertEqual(result_dict["realm_uri"], "http://zulip.testserver")
|
||||
|
||||
result = self.client_post("/json/register")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
result = self.client_post("/json/register", dict(client_gravatar="false"))
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
result = self.client_post("/json/register", dict(client_gravatar="true"))
|
||||
self.assert_json_error(
|
||||
result,
|
||||
"Invalid 'client_gravatar' parameter for anonymous request",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
result = self.client_post("/json/register", dict(include_subscribers="true"))
|
||||
self.assert_json_error(
|
||||
result,
|
||||
"Invalid 'include_subscribers' parameter for anonymous request",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
def test_events_register_endpoint_all_public_streams_access(self) -> None:
|
||||
guest_user = self.example_user("polonius")
|
||||
normal_user = self.example_user("hamlet")
|
||||
|
||||
@@ -40,7 +40,9 @@ def events_register_backend(
|
||||
request: HttpRequest,
|
||||
maybe_user_profile: Union[UserProfile, AnonymousUser],
|
||||
apply_markdown: bool = REQ(default=False, json_validator=check_bool),
|
||||
client_gravatar: bool = REQ(default=True, json_validator=check_bool),
|
||||
client_gravatar_raw: Optional[bool] = REQ(
|
||||
"client_gravatar", default=None, 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),
|
||||
@@ -74,11 +76,17 @@ def events_register_backend(
|
||||
),
|
||||
queue_lifespan_secs: int = REQ(json_validator=check_int, default=0, documentation_pending=True),
|
||||
) -> HttpResponse:
|
||||
if client_gravatar_raw is None:
|
||||
client_gravatar = maybe_user_profile.is_authenticated
|
||||
else:
|
||||
client_gravatar = client_gravatar_raw
|
||||
|
||||
if maybe_user_profile.is_authenticated:
|
||||
user_profile = maybe_user_profile
|
||||
spectator_requested_language = None
|
||||
assert isinstance(user_profile, UserProfile)
|
||||
realm = user_profile.realm
|
||||
include_streams = True
|
||||
|
||||
if all_public_streams and not user_profile.can_access_public_streams():
|
||||
raise JsonableError(_("User not authorized for this query"))
|
||||
@@ -88,15 +96,26 @@ def events_register_backend(
|
||||
else:
|
||||
user_profile = None
|
||||
realm = get_valid_realm_from_request(request)
|
||||
if not realm.allow_web_public_streams_access():
|
||||
raise MissingAuthenticationError()
|
||||
|
||||
# These parameters must be false for anonymous requests.
|
||||
if client_gravatar:
|
||||
raise JsonableError(
|
||||
_("Invalid '{}' parameter for anonymous request").format("client_gravatar")
|
||||
)
|
||||
if include_subscribers:
|
||||
raise JsonableError(
|
||||
_("Invalid '{}' parameter for anonymous request").format("include_subscribers")
|
||||
)
|
||||
|
||||
# Language set by spectator to be passed down to clients as user_settings.
|
||||
spectator_requested_language = request.COOKIES.get(
|
||||
settings.LANGUAGE_COOKIE_NAME, realm.default_language
|
||||
)
|
||||
|
||||
if not realm.allow_web_public_streams_access():
|
||||
raise MissingAuthenticationError()
|
||||
|
||||
all_public_streams = False
|
||||
include_streams = False
|
||||
|
||||
if client_capabilities is None:
|
||||
client_capabilities = {}
|
||||
@@ -116,6 +135,7 @@ def events_register_backend(
|
||||
all_public_streams,
|
||||
narrow=narrow,
|
||||
include_subscribers=include_subscribers,
|
||||
include_streams=include_streams,
|
||||
client_capabilities=client_capabilities,
|
||||
fetch_event_types=fetch_event_types,
|
||||
spectator_requested_language=spectator_requested_language,
|
||||
|
||||
Reference in New Issue
Block a user