snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
134
zerver/views/events_register.py
Normal file
134
zerver/views/events_register.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from typing import Annotated, Literal, TypeAlias
|
||||
|
||||
from annotated_types import Len
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import gettext as _
|
||||
from pydantic import Json, PositiveInt
|
||||
|
||||
from zerver.context_processors import get_valid_realm_from_request
|
||||
from zerver.lib.compatibility import is_pronouns_field_type_supported
|
||||
from zerver.lib.events import DEFAULT_CLIENT_CAPABILITIES, ClientCapabilities, do_events_register
|
||||
from zerver.lib.exceptions import JsonableError, MissingAuthenticationError
|
||||
from zerver.lib.narrow_helpers import narrow_dataclasses_from_tuples
|
||||
from zerver.lib.request import RequestNotes
|
||||
from zerver.lib.response import json_success
|
||||
from zerver.lib.typed_endpoint import ApiParamConfig, typed_endpoint
|
||||
from zerver.models import Stream, UserProfile
|
||||
from zerver.views.streams import parse_include_subscribers
|
||||
|
||||
|
||||
def _default_all_public_streams(user_profile: UserProfile, all_public_streams: bool | None) -> bool:
|
||||
if all_public_streams is not None:
|
||||
return all_public_streams
|
||||
else:
|
||||
return user_profile.default_all_public_streams
|
||||
|
||||
|
||||
def _default_narrow(user_profile: UserProfile, narrow: list[list[str]]) -> list[list[str]]:
|
||||
default_stream: Stream | None = user_profile.default_events_register_stream
|
||||
if not narrow and default_stream is not None:
|
||||
narrow = [["stream", default_stream.name]]
|
||||
return narrow
|
||||
|
||||
|
||||
NarrowT: TypeAlias = list[Annotated[list[str], Len(min_length=2, max_length=2)]]
|
||||
|
||||
|
||||
@typed_endpoint
|
||||
def events_register_backend(
|
||||
request: HttpRequest,
|
||||
maybe_user_profile: UserProfile | AnonymousUser,
|
||||
*,
|
||||
all_public_streams: Json[bool] | None = None,
|
||||
apply_markdown: Json[bool] = False,
|
||||
client_capabilities: Json[ClientCapabilities] = DEFAULT_CLIENT_CAPABILITIES,
|
||||
client_gravatar_raw: Annotated[Json[bool | None], ApiParamConfig("client_gravatar")] = None,
|
||||
event_types: Json[list[str]] | None = None,
|
||||
fetch_event_types: Json[list[str]] | None = None,
|
||||
include_subscribers: Literal["true", "false", "partial"] = "false",
|
||||
narrow: Json[NarrowT] | None = None,
|
||||
presence_history_limit_days: Json[int] | None = None,
|
||||
idle_queue_timeout: Json[PositiveInt | Literal["mobile"]] | None = None,
|
||||
slim_presence: Json[bool] = False,
|
||||
) -> HttpResponse:
|
||||
if narrow is None:
|
||||
narrow = []
|
||||
if client_gravatar_raw is None:
|
||||
client_gravatar = maybe_user_profile.is_authenticated
|
||||
else:
|
||||
client_gravatar = client_gravatar_raw
|
||||
|
||||
parsed_include_subscribers = parse_include_subscribers(include_subscribers)
|
||||
|
||||
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"))
|
||||
|
||||
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
|
||||
|
||||
# These parameters must be false for anonymous requests.
|
||||
if client_gravatar:
|
||||
raise JsonableError(
|
||||
_("Invalid '{key}' parameter for anonymous request").format(key="client_gravatar")
|
||||
)
|
||||
if parsed_include_subscribers:
|
||||
raise JsonableError(
|
||||
_("Invalid '{key}' parameter for anonymous request").format(
|
||||
key="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
|
||||
)
|
||||
|
||||
all_public_streams = False
|
||||
include_streams = False
|
||||
|
||||
client = RequestNotes.get_notes(request).client
|
||||
assert client is not None
|
||||
|
||||
pronouns_field_type_supported = is_pronouns_field_type_supported(
|
||||
request.headers.get("User-Agent")
|
||||
)
|
||||
|
||||
# TODO: We eventually want to let callers pass in dictionaries over the wire,
|
||||
# but we will still need to support tuples for a long time.
|
||||
modern_narrow = narrow_dataclasses_from_tuples(narrow)
|
||||
|
||||
ret = do_events_register(
|
||||
user_profile,
|
||||
realm,
|
||||
client,
|
||||
apply_markdown,
|
||||
client_gravatar,
|
||||
slim_presence,
|
||||
None,
|
||||
presence_history_limit_days,
|
||||
event_types,
|
||||
idle_queue_timeout,
|
||||
all_public_streams,
|
||||
narrow=modern_narrow,
|
||||
include_subscribers=parsed_include_subscribers,
|
||||
include_streams=include_streams,
|
||||
client_capabilities=client_capabilities,
|
||||
fetch_event_types=fetch_event_types,
|
||||
spectator_requested_language=spectator_requested_language,
|
||||
pronouns_field_type_supported=pronouns_field_type_supported,
|
||||
)
|
||||
return json_success(request, data=ret)
|
||||
Reference in New Issue
Block a user