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

This commit is contained in:
upstream-mirror
2026-09-15 15:05:30 +05:00
commit 64898b2c79
8999 changed files with 1757358 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
import os
from contextlib import suppress
from typing import TYPE_CHECKING, Any
import orjson
from django.http import HttpRequest, HttpResponse
from django.http.response import HttpResponseBase
from django.shortcuts import render
from django.test import Client
from pydantic import Json
from zerver.lib.exceptions import JsonableError, ResourceNotFoundError
from zerver.lib.integrations import INCOMING_WEBHOOK_INTEGRATIONS
from zerver.lib.response import json_success
from zerver.lib.typed_endpoint import PathOnly, typed_endpoint
from zerver.lib.webhooks.common import call_fixture_to_headers, standardize_headers
from zerver.models import UserProfile
from zerver.models.realms import get_realm
if TYPE_CHECKING:
from django.test.client import _MonkeyPatchedWSGIResponse as TestHttpResponse
ZULIP_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../")
def get_webhook_integrations() -> list[str]:
return [integration.name for integration in INCOMING_WEBHOOK_INTEGRATIONS]
def get_valid_integration_name(name: str) -> str | None:
for integration_name in get_webhook_integrations():
if name == integration_name:
return integration_name
return None
def dev_panel(request: HttpRequest) -> HttpResponse:
integrations = get_webhook_integrations()
bots = UserProfile.objects.filter(is_bot=True, bot_type=UserProfile.INCOMING_WEBHOOK_BOT)
context = {
"integrations": integrations,
"bots": bots,
# We set isolated_page to avoid clutter from footer/header.
"isolated_page": True,
}
return render(request, "zerver/development/integrations_dev_panel.html", context)
def send_webhook_fixture_message(
url: str, body: str, is_json: bool, custom_headers: dict[str, Any]
) -> "TestHttpResponse":
client = Client()
realm = get_realm("zulip")
standardized_headers = standardize_headers(custom_headers)
http_host = standardized_headers.pop("HTTP_HOST", realm.host)
if is_json:
content_type = standardized_headers.pop("HTTP_CONTENT_TYPE", "application/json")
else:
content_type = standardized_headers.pop("HTTP_CONTENT_TYPE", "text/plain")
return client.post(
url,
body,
content_type=content_type,
follow=False,
secure=False,
headers=None,
query_params=None,
HTTP_HOST=http_host,
**standardized_headers,
)
@typed_endpoint
def get_fixtures(request: HttpRequest, *, integration_name: PathOnly[str]) -> HttpResponse:
valid_integration_name = get_valid_integration_name(integration_name)
if not valid_integration_name:
raise ResourceNotFoundError(f'"{integration_name}" is not a valid webhook integration.')
fixtures = {}
fixtures_dir = os.path.join(ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
if not os.path.exists(fixtures_dir):
msg = f'The integration "{valid_integration_name}" does not have fixtures.'
raise ResourceNotFoundError(msg)
for fixture in os.listdir(fixtures_dir):
fixture_path = os.path.join(fixtures_dir, fixture)
with open(fixture_path) as f:
body = f.read()
# The file extension will be used to determine the type.
with suppress(orjson.JSONDecodeError):
body = orjson.loads(body)
headers_raw = call_fixture_to_headers(
valid_integration_name, "".join(fixture.split(".")[:-1])
)
def fix_name(header: str) -> str: # nocoverage
return header.removeprefix("HTTP_") # HTTP_ is a prefix intended for Django.
headers = {fix_name(k): v for k, v in headers_raw.items()}
fixtures[fixture] = {"body": body, "headers": headers}
return json_success(request, data={"fixtures": fixtures})
@typed_endpoint
def check_send_webhook_fixture_message(
request: HttpRequest,
*,
url: str,
body: str,
is_json: Json[bool],
custom_headers: str,
) -> HttpResponseBase:
try:
custom_headers_dict = orjson.loads(custom_headers)
except orjson.JSONDecodeError as ve: # nocoverage
raise JsonableError(f"Custom HTTP headers are not in a valid JSON format. {ve}") # nolint
response = send_webhook_fixture_message(url, body, is_json, custom_headers_dict)
if response.status_code == 200:
responses = [{"status_code": response.status_code, "message": response.content.decode()}]
return json_success(request, data={"responses": responses})
else: # nocoverage
return response
@typed_endpoint
def send_all_webhook_fixture_messages(
request: HttpRequest, *, url: str, integration_name: str
) -> HttpResponse:
valid_integration_name = get_valid_integration_name(integration_name)
if not valid_integration_name: # nocoverage
raise ResourceNotFoundError(f'"{integration_name}" is not a valid webhook integration.')
fixtures_dir = os.path.join(ZULIP_PATH, f"zerver/webhooks/{valid_integration_name}/fixtures")
if not os.path.exists(fixtures_dir):
msg = f'The integration "{valid_integration_name}" does not have fixtures.'
raise ResourceNotFoundError(msg)
responses = []
for fixture in os.listdir(fixtures_dir):
fixture_path = os.path.join(fixtures_dir, fixture)
with open(fixture_path) as f:
content = f.read()
x = fixture.split(".")
fixture_name, fixture_format = "".join(_ for _ in x[:-1]), x[-1]
headers = call_fixture_to_headers(valid_integration_name, fixture_name)
is_json = fixture_format == "json"
response = send_webhook_fixture_message(url, content, is_json, headers)
responses.append(
{
"status_code": response.status_code,
"fixture_name": fixture,
"message": response.content.decode(),
}
)
return json_success(request, data={"responses": responses})