mirror of https://github.com/zulip/zulip.git
events: Add support for spectator access to /register.
This is necessary for the mobile/terminal clients to build spectator support down the line. We'll also be using it for the web application, in an upcoming commit.
This commit is contained in:
parent
53518e8a24
commit
2e86ea6540
|
@ -1316,7 +1316,7 @@ def apply_event(
|
||||||
|
|
||||||
|
|
||||||
def do_events_register(
|
def do_events_register(
|
||||||
user_profile: UserProfile,
|
user_profile: Optional[UserProfile],
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
user_client: Client,
|
user_client: Client,
|
||||||
apply_markdown: bool = True,
|
apply_markdown: bool = True,
|
||||||
|
@ -1356,6 +1356,33 @@ def do_events_register(
|
||||||
else:
|
else:
|
||||||
event_types_set = None
|
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.
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
# Force include_streams=False for security reasons.
|
||||||
|
include_streams=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
post_process_state(user_profile, ret, notification_settings_null=False)
|
||||||
|
return ret
|
||||||
|
|
||||||
# Fill up the UserMessage rows if a soft-deactivated user has returned
|
# Fill up the UserMessage rows if a soft-deactivated user has returned
|
||||||
reactivate_user_if_soft_deactivated(user_profile)
|
reactivate_user_if_soft_deactivated(user_profile)
|
||||||
|
|
||||||
|
|
|
@ -9207,8 +9207,12 @@ paths:
|
||||||
msg: {}
|
msg: {}
|
||||||
queue_id:
|
queue_id:
|
||||||
type: string
|
type: string
|
||||||
|
nullable: true
|
||||||
description: |
|
description: |
|
||||||
The ID of the queue that has been allocated for your client.
|
The ID of the queue that has been allocated for your client.
|
||||||
|
|
||||||
|
Will be None only for unauthenticated access in realms that have
|
||||||
|
enabled the [public access option](/help/public-access-option).
|
||||||
last_event_id:
|
last_event_id:
|
||||||
type: integer
|
type: integer
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -143,6 +143,23 @@ class EventsEndpointTest(ZulipTestCase):
|
||||||
self.assertEqual(result_dict["realm_emoji"], [])
|
self.assertEqual(result_dict["realm_emoji"], [])
|
||||||
self.assertEqual(result_dict["queue_id"], "15:13")
|
self.assertEqual(result_dict["queue_id"], "15:13")
|
||||||
|
|
||||||
|
def test_events_register_spectators(self) -> None:
|
||||||
|
# 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())
|
||||||
|
self.assert_json_error(
|
||||||
|
result,
|
||||||
|
"Not logged in: API authentication or user session required",
|
||||||
|
status_code=401,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.client_post("/json/register", dict())
|
||||||
|
self.assert_json_success(result)
|
||||||
|
result_dict = result.json()
|
||||||
|
self.assertEqual(result_dict["queue_id"], None)
|
||||||
|
self.assertEqual(result_dict["realm_uri"], "http://zulip.testserver")
|
||||||
|
|
||||||
def test_events_register_endpoint_all_public_streams_access(self) -> None:
|
def test_events_register_endpoint_all_public_streams_access(self) -> None:
|
||||||
guest_user = self.example_user("polonius")
|
guest_user = self.example_user("polonius")
|
||||||
normal_user = self.example_user("hamlet")
|
normal_user = self.example_user("hamlet")
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from typing import Dict, Optional, Sequence
|
from typing import Dict, Optional, Sequence, Union
|
||||||
|
|
||||||
|
from django.contrib.auth.models import AnonymousUser
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
from zerver.context_processors import get_valid_realm_from_request
|
||||||
from zerver.lib.events import do_events_register
|
from zerver.lib.events import do_events_register
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError, MissingAuthenticationError
|
||||||
from zerver.lib.request import REQ, RequestNotes, has_request_variables
|
from zerver.lib.request import REQ, RequestNotes, has_request_variables
|
||||||
from zerver.lib.response import json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.validator import check_bool, check_dict, check_int, check_list, check_string
|
from zerver.lib.validator import check_bool, check_dict, check_int, check_list, check_string
|
||||||
|
@ -35,7 +37,7 @@ NarrowT = Sequence[Sequence[str]]
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def events_register_backend(
|
def events_register_backend(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
user_profile: UserProfile,
|
maybe_user_profile: Union[UserProfile, AnonymousUser],
|
||||||
apply_markdown: bool = REQ(default=False, json_validator=check_bool),
|
apply_markdown: bool = REQ(default=False, json_validator=check_bool),
|
||||||
client_gravatar: bool = REQ(default=True, json_validator=check_bool),
|
client_gravatar: bool = REQ(default=True, json_validator=check_bool),
|
||||||
slim_presence: bool = REQ(default=False, json_validator=check_bool),
|
slim_presence: bool = REQ(default=False, json_validator=check_bool),
|
||||||
|
@ -71,11 +73,24 @@ def events_register_backend(
|
||||||
),
|
),
|
||||||
queue_lifespan_secs: int = REQ(json_validator=check_int, default=0, documentation_pending=True),
|
queue_lifespan_secs: int = REQ(json_validator=check_int, default=0, documentation_pending=True),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
if all_public_streams and not user_profile.can_access_public_streams():
|
if maybe_user_profile.is_authenticated:
|
||||||
raise JsonableError(_("User not authorized for this query"))
|
user_profile = maybe_user_profile
|
||||||
|
assert isinstance(user_profile, UserProfile)
|
||||||
|
realm = user_profile.realm
|
||||||
|
|
||||||
all_public_streams = _default_all_public_streams(user_profile, all_public_streams)
|
if all_public_streams and not user_profile.can_access_public_streams():
|
||||||
narrow = _default_narrow(user_profile, narrow)
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
|
all_public_streams = _default_all_public_streams(user_profile, all_public_streams)
|
||||||
|
narrow = _default_narrow(user_profile, narrow)
|
||||||
|
else:
|
||||||
|
user_profile = None
|
||||||
|
realm = get_valid_realm_from_request(request)
|
||||||
|
|
||||||
|
if not realm.allow_web_public_streams_access():
|
||||||
|
raise MissingAuthenticationError()
|
||||||
|
|
||||||
|
all_public_streams = False
|
||||||
|
|
||||||
if client_capabilities is None:
|
if client_capabilities is None:
|
||||||
client_capabilities = {}
|
client_capabilities = {}
|
||||||
|
@ -85,7 +100,7 @@ def events_register_backend(
|
||||||
|
|
||||||
ret = do_events_register(
|
ret = do_events_register(
|
||||||
user_profile,
|
user_profile,
|
||||||
user_profile.realm,
|
realm,
|
||||||
client,
|
client,
|
||||||
apply_markdown,
|
apply_markdown,
|
||||||
client_gravatar,
|
client_gravatar,
|
||||||
|
|
|
@ -469,7 +469,7 @@ v1_api_and_json_patterns = [
|
||||||
rest_path("users/me/subscriptions/muted_topics", PATCH=update_muted_topic),
|
rest_path("users/me/subscriptions/muted_topics", PATCH=update_muted_topic),
|
||||||
rest_path("users/me/muted_users/<int:muted_user_id>", POST=mute_user, DELETE=unmute_user),
|
rest_path("users/me/muted_users/<int:muted_user_id>", POST=mute_user, DELETE=unmute_user),
|
||||||
# used to register for an event queue in tornado
|
# used to register for an event queue in tornado
|
||||||
rest_path("register", POST=events_register_backend),
|
rest_path("register", POST=(events_register_backend, {"allow_anonymous_user_web"})),
|
||||||
# events -> zerver.tornado.views
|
# events -> zerver.tornado.views
|
||||||
rest_path("events", GET=get_events, DELETE=cleanup_event_queue),
|
rest_path("events", GET=get_events, DELETE=cleanup_event_queue),
|
||||||
# report -> zerver.views.report
|
# report -> zerver.views.report
|
||||||
|
|
Loading…
Reference in New Issue