Commit Graph

137 Commits

Author SHA1 Message Date
Alex Vandiver
257cfad667 outgoing_webhook: Lump chunked-encoding errors with connection errors. 2025-09-05 10:35:01 -07:00
Kislay Verma
6bd6f23549 url_encoding: Add support for with message links.
We abstract away "near" vs "with" from the function names and
allow callers to specify whether they want a conversation_link,
ie, use the "with" operator. The default choice is "near".
2025-06-30 11:19:00 -07:00
Prakhar Pratyush
5d9beb3655 fetch_messages: Add support for empty topic names.
This commit is a part of the work to support empty string
as a topic name.

Previously, empty string was not a valid topic name.

Adds `allow_empty_topic_name` boolean parameter to `GET /messages`
and `GET /messages/{message_id}` endpoints to decide whether the
topic names in the fetched messages can be empty strings.

If False, the topic names in the fetched message will have the
value of `realm_empty_topic_display_name` field in `POST /register`
response replacing "" for channel messages.
2025-01-07 17:24:00 -08:00
Anders Kaseorg
e2d56db2a3 message_cache: Use the sender’s recipient_id for incoming 1:1 DMs.
For an incoming 1:1 DM, the recipient’s own recipient_id is useless to
the recipient themselves. Substitute the sender’s recipient_id, so the
recipient can use recipient_id as documented to uniquely represent the
set of 2 users in this conversation.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-12-11 12:05:03 -08:00
Anders Kaseorg
e20e2f4883 outgoing_webhook: Optimize can_access_sender computation.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-12-05 14:25:16 -08:00
Anders Kaseorg
76df4b2574 message_cache: Require can_access_sender for finalize_payload.
An access control parameter should never be optional with a default of
open.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-12-05 12:07:22 -08:00
Anders Kaseorg
80d3e60df8 ruff: Fix FURB180 Use of metaclass=abc.ABCMeta.
This is a preview rule, not yet enabled by default.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-14 13:53:40 -07:00
Anders Kaseorg
531b34cb4c ruff: Fix UP007 Use X | Y for type annotations.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Anders Kaseorg
e08a24e47f ruff: Fix UP006 Use list instead of List for type annotation.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Alex Vandiver
737a751f5c message: Split MessageDict and friends into its own file. 2024-02-14 12:27:03 -08:00
Anders Kaseorg
712917b2c9 ruff: Fix RUF019 Unnecessary key check before dictionary access.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-02-02 10:30:45 -08:00
Anders Kaseorg
1f1b2f9a68 models: Extract zerver.models.bots.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg
bac027962f models: Extract zerver.models.clients.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg
45bb8d2580 models: Extract zerver.models.users.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg
a50eb2e809 mypy: Enable new error explicit-override.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-10-12 12:28:41 -07:00
Alex Vandiver
ffaccb8af2 outgoing_webhook: Respect settings.OUTGOING_WEBHOOK_TIMEOUT_SECONDS.
The use of the setting was accidentally removed in b88d7a741e, and
replaced with a static 10 seconds.
2023-05-16 07:00:37 -07:00
Lauryn Menard
42d9560413 message: Use recipient_type_name for API message type references.
Refactors instances of `message_type_name` and `message_type`
that are referring to API message type value ("stream" or
"private") to use `recipient_type_name` instead.

Prep commit for adding "direct" as a value for endpoints with a
`type` parameter to indicate whether the message is a stream or
direct  message.
2023-04-18 12:29:33 -07:00
Lauryn Menard
017b05fd84 outgoing-webhook: Update Slack outgoing webhook error for private messages.
Updates the error message for the outgoing Slack webhook to use
"direct message" instead of "private message".
2023-02-24 11:47:26 -08:00
Anders Kaseorg
df001db1a9 black: Reformat with Black 23.
Black 23 enforces some slightly more specific rules about empty line
counts and redundant parenthesis removal, but the result is still
compatible with Black 22.

(This does not actually upgrade our Python environment to Black 23
yet.)

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-02-02 10:40:13 -08:00
Anders Kaseorg
ff1971f5ad ruff: Fix SIM105 Use contextlib.suppress instead of try-except-pass.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-01-23 11:18:36 -08:00
Alex Vandiver
d8ebbedbbb outgoing_webhook: Ignore the exception on failure if the stream is gone.
In the outgoing webhook handler, there is potentially several seconds
of trying between when a message triggering an outgoing webhook
arrives, and when it fails.  In the meantime, the stream the
triggering message was on may have been deleted, causing the
"Failure!" message to have no valid stream to be sent to.

Rather than raise an exception in the outgoing webhook worker, ignore
the exception and move on.
2022-11-04 14:46:17 -07:00
Anders Kaseorg
975066e3f0 actions: Split out zerver.actions.message_send.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-04-14 17:14:34 -07:00
Tim Abbott
417c32629d outgoing webhooks: Fix inconsistencies with Slack's API.
Apparently, our slack compatible outgoing webhook format didn't
exactly match Slack, especially in the types used for values.  Fix
this by using a much more consistent format, where we preserve their
pattern of prefixing IDs with letters.

This fixes a bug where Zulip's team_id could be the empty string,
which tripped up using GitLab's slash commands with Zulip.

Fixes #19588.
2021-09-23 11:19:20 -07:00
Anders Kaseorg
fb3ddf50d4 python: Fix mypy no_implicit_reexport errors.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-07-16 14:02:31 -07:00
Mateusz Mandera
de6bd22ee9 outgoing_webhook: Treat "" json in response as response_not_required.
b7b1ec0aeb made our checks of the response
format stronger, to enforce that the json translates to a valid dict.
However, old client code (zulip_botserver) was using "" as equivalent to
response_not_required - so we need to keep backward-compatibility to not
break things built on it.
2021-05-13 08:07:38 -07:00
Mateusz Mandera
c95cac2dd7 outgoing_webhook: Send response payload to bot owner if it was invalid.
When the format of the response received from the outgoing webhook
server is invalid (unparsable json, or just wrong format that doesn't
translate into a dictionary etc.), a message with the error is sent to
the bot owner. We should include the actual payload to make reasonable
debugging possible.

In notify_bot_owner we have to move the `if response_content` block to
append the payload to the message whenever it was specified as an
argument to the function. It shouldn't be nested inside
`elif status_code` as before.
2021-05-11 14:27:00 -07:00
Alex Vandiver
8df82f50e4 outgoing_http: Provide a convenient way to set default headers. 2021-05-07 08:39:36 -07:00
Alex Vandiver
6339e7fd47 outgoing_http: Put the X-Smokescreen-Role in the proxy headers. 2021-05-07 08:39:36 -07:00
Alex Vandiver
b88d7a741e outgoing_http: Factor out outgoing HTTP session with timeout. 2021-05-07 08:39:36 -07:00
Alex Vandiver
2dc6df33ae tests: Switch outgoing_webhook_system to use responses. 2021-05-07 08:39:36 -07:00
Alex Vandiver
af26849554 outgoing_webhook: Set a default timeout of 10s.
Support for the timeouts, and tests for them, was added in
53a8b2ac87 -- though no code could have set them after 31597cf33e.

Add a 10-second default timeout.  Observationally, p99 is just about
5s, with everything else being previously being destined to meet the
30s worker timeout; 10s provides a sizable buffer between them.

Fixes #17742.
2021-05-07 08:39:36 -07:00
Alex Vandiver
8711ab7676 outgoing_webhook: Add a logging statement for each outgoing webhook.
This will help determine potentail timeout lengths, as well as serve
as a generally-useful log for locations which do not have Smokescreen
enabled.

In service of #17742.
2021-04-29 12:37:14 -07:00
Mateusz Mandera
b7b1ec0aeb outgoing_webhook: Improve invalid json handling when parsing response.
It's better to just raise JsonableError here, as that makes this error
processed in the central place for this kind of thing in do_rest_call:
---------
except JsonableError as e:
    response_message = e.msg
    logging.info("Outhook trigger failed:", stack_info=True)
    fail_with_message(event, response_message)
    response_message = f"The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error:\n> {e}"
    notify_bot_owner(event, failure_message=response_message)
    return None
----------

which does all the things that are supposed to happen -
fail_with_message, appropriate logging and notifying the bot owner.
2021-04-26 09:32:35 -07:00
Mateusz Mandera
b998138d3a outgoing_webhook: Handle valid, but unexpected json in response.
Responses such as "null" or "true" are valid json, but json.loads
returns different objects than dicts that the codepath expects.

Fixes #18223.
2021-04-26 09:32:35 -07:00
Anders Kaseorg
e7ed907cf6 python: Convert deprecated Django ugettext alias to gettext.
django.utils.translation.ugettext is a deprecated alias of
django.utils.translation.gettext as of Django 3.0, and will be removed
in Django 4.0.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-15 18:01:34 -07:00
Mateusz Mandera
4235be759d CVE-2021-30477: Prevent outgoing webhook bots from sending arbitrary messages to any stream.
A bug in the implementation of replies to messages sent by outgoing
webhooks to private streams meant that an outgoing webhook bot could be
used to send messages to private streams that the user was not intended
to be able to send messages to.

Completely skipping stream access check in check_message whenever the
sender is an outgoing webhook bot is insecure, as it might allow someone
with access to the bot's API key to send arbitrary messages to all
streams in the organization. The check is only meant to be bypassed in
send_response_message, where the stream message is only being sent
because someone mentioned the bot in that stream (and thus the bot
posting there is the desired outcome). We get much better control over
what's going by passing an explicit argument to check_message when
skipping the access check is desirable.
2021-04-14 12:37:34 -07:00
PIG208
c6dfe7bf40 api: Add bot name to outgoing webhook payload.
Fixes: #12282
2021-04-06 17:37:50 -07:00
Sundar Guntnur
5aefb5e656 webhook: Catch potential JsonableError when parsing widget_content.
The `widget_content` key is expected to contain a string which parses
as JSON; in the event that it does not, log the error and notify the
bot owner, instead of failing silently.

Fixes #16850.
2021-03-31 13:31:42 -07:00
Alex Vandiver
134db206a9 outgoing_webhook: Set an X-Smokescreen-Role on requests.
This header is used by the Smokescreen outgoing proxy to provide
identification.
2021-03-29 18:24:44 -07:00
Alex Vandiver
bd37dc0b83 outgoing_webhook: Set the user-agent on all requests. 2021-03-29 18:24:44 -07:00
Alex Vandiver
cb3e6df8b9 outgoing_webhook: Add a requests session on the webhook.
The session object provides a common place to set headers on all
requests, no matter which implementation.

Because the `headers` attribute of Session is not a true static
attribute, but rather exposed via overriding `__getstate__`, `mock`'s
autospec cannot know about it, and thus throws an error; in tests that
mock the Session, we thus must explicitly set the `session.headers`.
2021-03-29 18:24:44 -07:00
Alex Vandiver
be100154dd outgoing_webhook: Type do_rest_call with fewer Anys. 2021-03-29 18:24:44 -07:00
Alex Vandiver
a280905a89 outgoing_webhook: Join build_bot_request and send_data_to_server.
The existing organization, of returning an opaque blob from
`build_bot_request`, which was later consumed by
`send_data_to_server`, is not particularly sensible; the steps become
oddly split between the OutgoingWebhookWorker, `do_rest_call`, and the
`OutgoingWebhookServiceInterface`.

Make the `OutgoingWebhookServiceInterface` in charge of building,
making, and returning the request in one method; another method
handles extracting content from a successful response.  `do_rest_call`
is responsible for calling both halves of this, and doing common error
handling.
2021-03-29 18:24:44 -07:00
Alex Vandiver
d88e6fe3fa outgoing_webhook: Use json= to automatically set content-type. 2021-03-29 18:24:44 -07:00
Tim Abbott
88f351cdee outgoing_webhook: Simplify error handling logic.
Structurally, exception, failure_message, and status_code are mutually
exclusive in how this function is called, and it's best for the
function's flow to represent that.
2021-03-18 14:41:34 -07:00
Siddharth Asthana
ec28a7555c outgoing_webhook: modify outgoing_webhook's 407 error message.
The message from the bot which triggered the 407 error message notifies
the bot owner about the exceptions as well in the error message. This
commit handles it more gracefully and shows a generic message.
2021-03-18 14:39:26 -07:00
Siddharth Asthana
5ec0860a2f outgoing_webhook: Add bot name when a outgoing_webhook is triggered.
The messages from the bot which were triggered by the outgoing_webhooks
didn't have the bot name in them. This commit adds the bot name to it
and makes the corresponding changes in the tests.
2021-03-18 14:39:26 -07:00
Anders Kaseorg
6e4c3e41dc python: Normalize quotes with Black.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-12 13:11:19 -08:00
Anders Kaseorg
11741543da python: Reformat with Black, except quotes.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-12 13:11:19 -08:00
Anders Kaseorg
5028c081cb python: Merge concatenated string literals that Black would uglify.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-12 13:11:19 -08:00