mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	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:
		@@ -1316,7 +1316,7 @@ def apply_event(
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def do_events_register(
 | 
			
		||||
    user_profile: UserProfile,
 | 
			
		||||
    user_profile: Optional[UserProfile],
 | 
			
		||||
    realm: Realm,
 | 
			
		||||
    user_client: Client,
 | 
			
		||||
    apply_markdown: bool = True,
 | 
			
		||||
@@ -1356,6 +1356,33 @@ def do_events_register(
 | 
			
		||||
    else:
 | 
			
		||||
        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
 | 
			
		||||
    reactivate_user_if_soft_deactivated(user_profile)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9207,8 +9207,12 @@ paths:
 | 
			
		||||
                      msg: {}
 | 
			
		||||
                      queue_id:
 | 
			
		||||
                        type: string
 | 
			
		||||
                        nullable: true
 | 
			
		||||
                        description: |
 | 
			
		||||
                          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:
 | 
			
		||||
                        type: integer
 | 
			
		||||
                        description: |
 | 
			
		||||
 
 | 
			
		||||
@@ -143,6 +143,23 @@ class EventsEndpointTest(ZulipTestCase):
 | 
			
		||||
        self.assertEqual(result_dict["realm_emoji"], [])
 | 
			
		||||
        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:
 | 
			
		||||
        guest_user = self.example_user("polonius")
 | 
			
		||||
        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.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.exceptions import JsonableError
 | 
			
		||||
from zerver.lib.exceptions import JsonableError, MissingAuthenticationError
 | 
			
		||||
from zerver.lib.request import REQ, RequestNotes, has_request_variables
 | 
			
		||||
from zerver.lib.response import json_success
 | 
			
		||||
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
 | 
			
		||||
def events_register_backend(
 | 
			
		||||
    request: HttpRequest,
 | 
			
		||||
    user_profile: UserProfile,
 | 
			
		||||
    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),
 | 
			
		||||
    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),
 | 
			
		||||
) -> HttpResponse:
 | 
			
		||||
    if all_public_streams and not user_profile.can_access_public_streams():
 | 
			
		||||
        raise JsonableError(_("User not authorized for this query"))
 | 
			
		||||
    if maybe_user_profile.is_authenticated:
 | 
			
		||||
        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)
 | 
			
		||||
    narrow = _default_narrow(user_profile, narrow)
 | 
			
		||||
        if all_public_streams and not user_profile.can_access_public_streams():
 | 
			
		||||
            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:
 | 
			
		||||
        client_capabilities = {}
 | 
			
		||||
@@ -85,7 +100,7 @@ def events_register_backend(
 | 
			
		||||
 | 
			
		||||
    ret = do_events_register(
 | 
			
		||||
        user_profile,
 | 
			
		||||
        user_profile.realm,
 | 
			
		||||
        realm,
 | 
			
		||||
        client,
 | 
			
		||||
        apply_markdown,
 | 
			
		||||
        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/muted_users/<int:muted_user_id>", POST=mute_user, DELETE=unmute_user),
 | 
			
		||||
    # 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
 | 
			
		||||
    rest_path("events", GET=get_events, DELETE=cleanup_event_queue),
 | 
			
		||||
    # report -> zerver.views.report
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user