webhooks: Support filtering GitHub activity from private repositories.

Currently, the GitHub webhook sends activity from both public and private
repositories, which could lead to unintended disclosure of sensitive
information from private repositories.

This commit introduces a ignore_private_repositories parameter to the
webhook URL. When set to true, the webhook ignore processing activity from
private repositories, ensuring that such activities are not posted to
Zulip streams. By default, if the parameter is omitted or set to false,
activities from both public and private repositories are processed
normally. This provides users with the flexibility to control the
visibility of private repository activities without altering the default
behavior.

More importantly, this introduces a cleaner mechanism for individual
incoming webhooks to declare support for settings not common to all
webhook integrations.

Fixes #31638.
This commit is contained in:
Aditya Kumar Kasaudhan
2024-09-20 15:11:30 +05:30
committed by Tim Abbott
parent fdf90f7ad1
commit d1ff871523
20 changed files with 927 additions and 12 deletions

View File

@@ -12,6 +12,8 @@ from django.views.decorators.csrf import csrf_exempt
from django_stubs_ext import StrPromise
from zerver.lib.storage import static_path
from zerver.lib.validator import check_bool, check_string
from zerver.lib.webhooks.common import WebhookConfigOption
"""This module declares all of the (documented) integrations available
in the Zulip server. The Integration class is used as part of
@@ -34,7 +36,7 @@ Over time, we expect this registry to grow additional convenience
features for writing and configuring integrations efficiently.
"""
OptionValidator: TypeAlias = Callable[[str, str], str | None]
OptionValidator: TypeAlias = Callable[[str, str], str | bool | None]
META_CATEGORY: dict[str, StrPromise] = {
"meta-integration": gettext_lazy("Integration frameworks"),
@@ -75,7 +77,7 @@ class Integration:
doc: str | None = None,
stream_name: str | None = None,
legacy: bool = False,
config_options: Sequence[tuple[str, str, OptionValidator]] = [],
config_options: Sequence[WebhookConfigOption] = [],
) -> None:
self.name = name
self.client_name = client_name
@@ -198,7 +200,7 @@ class WebhookIntegration(Integration):
doc: str | None = None,
stream_name: str | None = None,
legacy: bool = False,
config_options: Sequence[tuple[str, str, OptionValidator]] = [],
config_options: Sequence[WebhookConfigOption] = [],
dir_name: str | None = None,
) -> None:
if client_name is None:
@@ -408,6 +410,18 @@ WEBHOOK_INTEGRATIONS: list[WebhookIntegration] = [
logo="images/integrations/logos/github.svg",
function="zerver.webhooks.github.view.api_github_webhook",
stream_name="github",
config_options=[
WebhookConfigOption(
name="branches",
description="Filter by branches (comma-separated list)",
validator=check_string,
),
WebhookConfigOption(
name="ignore_private_repositories",
description="Exclude notifications from private repositories",
validator=check_bool,
),
],
),
WebhookIntegration(
"githubsponsors",