Commit Graph

9200 Commits

Author SHA1 Message Date
Alex Vandiver
6b3143d7fc send_email: Add a flag to force all emails through the queue.
Sending emails synchronously is useful because it reports
configuration errors -- but it also means that occasional failures can
result in ugly 500's, since those don't retry.

Add a setting which forces all email to go through the `emil_senders`
queue, so it can be retried as needed.
2025-04-22 10:26:25 -07:00
Prakhar Pratyush
f98c36210a test_push_notifications: Move PushNotificationTest to test_classes.py.
This is a prep commit which moves the `PushNotificationTest` class
from `test_push_notifications.py` to `test_classes.py` as we plan to
import it and reuse it in other files.

This commit also renames `PushNotificationTest` to
`PushNotificationTestCase` to align with our naming convention
in `test_classes.py` to name classes, which act as a parent class
with helper methods and no actual test within itself, with a
"TestCase" suffix.
2025-04-17 10:55:05 -07:00
Niloth P
22c80117f5 integrations: Add OpenSearch incoming webhook integration.
Co-authored-by: merlinz01 <158784988+merlinz01@users.noreply.github.com>
2025-04-16 14:05:29 -07:00
Kislay Verma
e2e0603689 message_edit: Check previous message content to prevent races.
Similar to group based setting values, we expect
the client to send the previous content alongwith
the edited content to the edit message endpoint.
We reject the request incase the previous content
doesn't match the current message content, which
could happen in case two users simultaneously edit
a message - which will be implemented in #33051.
2025-04-16 14:05:12 -07:00
Kislay Verma
5b5be39b19 exceptions: Create base class ExpectationMismatchError.
This class will be inherited by all errors related to
some sort of mismatch from the expected value.

This is a prep commit for #33051, as a part of which we
add a new exception class for message content mismatch.
2025-04-16 14:05:12 -07:00
Ritwik
187a008f13 streams: Modify get_stream_permission_policy_name to return dict key.
This is a prep commit for #30212. It will allow us to compare the key
and not translated policy name.

Co-authored-by: Tanmay Kumar <tnmdotkr@gmail.com>
2025-04-15 16:28:38 -07:00
opmkumar
8482a9480b email: Apply message content visibility settings to digest too.
Fixes #33190.
2025-04-15 16:24:59 -07:00
opmkumar
ec81c027fc digest: Pass length of hot_conversations to enough_traffic function.
Previously, `hot_conversations` was incorrectly passed as a string to the
`enough_traffic` function. This commit fixes the issue by passing the length
of `hot_conversations` as a parameter instead.
2025-04-15 16:24:59 -07:00
Sahil Batra
c5b005833c groups: Do not prefetch can_access_all_users_group setting.
This commit updates code to not prefetch can_access_all_users_group
and can_access_all_users_group__named_user_group fields using
select_related. We can just use get_realm_system_groups_name_dict
function to check if setting is set to "Everyone" group when
needed and can avoid unnecessarily fetching groups for every user
query.
2025-04-11 17:37:06 -07:00
Sahil Batra
7e77100433 users: Remove unused variable in get_user_dicts_in_realm. 2025-04-11 17:37:06 -07:00
Sahil Batra
7ebea853be user_groups: Refactor user_has_permission_for_group_setting.
This commit refactors user_has_permission_for_group_setting
to accept setting group ID instead of UserGroup object.

We only need ID in checking the permission and this helps in
further commit to avoid prefetching can_access_all_users_group
setting.
2025-04-11 17:37:06 -07:00
Sanchit Sharma
d5c83e02c3 streams: Return archived web-public channels. 2025-04-11 08:12:53 -07:00
Anders Kaseorg
ad31ef22f2 narrow: Fix get_base_query_for_search access restrictions.
The type_id is the id of a UserProfile, Stream, or DirectMessageGroup,
not the id of a type.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-04-10 15:26:57 -07:00
Alex Vandiver
aeed907c50 s3: Support non-AWS S3 providers which do not support request checksums. 2025-04-10 11:11:25 -07:00
Shubham Padia
98950314ba user_groups: Realm admins should be allowed moderator permissions.
For `check_user_has_permission_by_role`, we were using
`user.is_moderator` by default to check whether the user had those
priviliges. But that specific function returns false if the user is an
admin or an owner. So we check `is_realm_admin` too in that case.
2025-04-09 15:30:05 -07:00
theofficialvedantjoshi
194dfbc84d integrations: Add common framework for webhook signature verification.
Fixes: #19774
2025-04-09 15:05:57 -07:00
Sahil Batra
7c470f0161 streams: Fix events send when archiving and unarchiving streams. 2025-04-08 12:41:09 -07:00
Sahil Batra
ae579aa25a register: Include archived channels in "streams" field. 2025-04-08 12:41:09 -07:00
Sahil Batra
a6cc33f478 events: Do not compute first_message_id unnecessarily.
"first_message_id" field for subscription objects needs
to be updated when archiving a stream as we send a
notification message, but first_message_id will only
change if the stream did not have any messages previously.

This commit updates the code to update first_message_id
only when required.
2025-04-08 12:41:09 -07:00
Sahil Batra
1b35ad3094 message: Use set instead of list when checking DM permission.
When checking DM permissions, instead of using list of
users, we now use set of users to check if any user is
in direct_message_permission_group because there can be
case when sender can also be one of the recipients.
2025-04-08 12:32:33 -07:00
Ethan Mayer
c12b94aea4 models: Refactor corporate/models.py into models package.
Fixes #34318.

Seperated models file into a package with component files.
2025-04-08 10:16:35 -07:00
Sahil Batra
f29166dbba settings: Do not pre-fetch DM permission group settings.
This commit updates code to not pre-fetch DM permission
group settings using select_related and instead just
fetch the required data from DB when checking permission.

This will increase one query but will help in pre-fetching
the settings for all users and for all type of messages.

Fixes part of #33677.
2025-04-07 15:34:30 -07:00
Sahil Batra
179782eaba user_groups: Refactor is_user_in_group and is_any_user_in_group.
This commit updates is_user_in_group and is_any_user_in_group
to accept group ID as parameter instead of UserGroup object.

This is a prep commit for updating code to not prefetch
direct message permissions group.
2025-04-07 15:34:30 -07:00
Varun-Kolanu
aaa2db4079 webhooks: Support no_previews argument for markdown messages.
This commit enables skipping inline image previews
by passing the no_previews field to check_send_webhook_message.
2025-04-07 11:53:19 -07:00
Shubham Padia
12afeee277 test_classes: Mention actual and expected count in assert_length. 2025-04-07 10:19:57 -07:00
Prakhar Pratyush
41df472d41 corporate: Replace /try-zulip with /?show_try_zulip_modal.
This commit removes the `/try-zulip` landing page.

The URLs are replaced with `chat.zulip.org/?show_try_zulip_modal`,
which leads to display a modal for spectators.

Fixes #34181.
2025-04-03 13:01:48 -07:00
Prakhar Pratyush
f64d7b6e28 home: Add a modal to replace /try-zulip landing page.
This commit adds a modal which will be displayed when
a spectator visits `/?show_try_zulip_modal`.

When a user visits `/?show_try_zulip_modal` and is a spectator,
we set a new `show_try_zulip_modal` field in `page_params` to
`true` (in all other cases, it's `false`).

Based on the `show_try_zulip_modal` page param, the web client
shows the modal.

Fixes part of #34181.
2025-04-03 13:01:48 -07:00
Evy Kassirer
ea2fd69f67 subscription_info: Send partial subscriber info to client separately.
We're doing this so that the client can keep track of which channels
it might need to request full subscriber data from, and which already
have full subscriber data.
2025-04-02 16:19:05 -07:00
Evy Kassirer
1405dd630f subscription_info: Add option to get partial subscribers.
It returns just bots for now.
2025-03-31 22:13:50 -07:00
Mateusz Mandera
716ead8f4e export: Also add guardrail to the management command. 2025-03-28 17:44:58 -07:00
Mateusz Mandera
d098b9c349 export: Don't export DirectMessageGroup info of non-consented users.
This is private information, as by inspecting the DirectMessageGroup
objects and their associated Subscription objects, you could determine
which users conversed with each other in a DM group.

This did *not* leak any actual message - only the fact that at least one
of the users in the group sent a group DM.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
0fd79e379e export: Fix public exports.
The prior significantly restricted what data gets exported from
non-consented users. The last thing we're missing is to fix the logic
to work correctly for public exports.

Prior commits focused on addressing exports with consent. This commit
adapts it to work with public exports.:
- Do not turn user accounts into mirror dummies in the public export - or
  after export->import you'll end up with a realm with no functional
  accounts; as every user is non-consented and the original logic added in
  the prior commits will turn them into mirror dummies.
- Some of the custom fetch/process functions were changed without
  considering public exports - now they work correctly, by setting
  consenting_user_ids to an empty set.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
6695e8f9eb export: Scrub Subscriptions to defaults for non-consented users.
The Subscription Config is constructed in a bit of a strange way, that's
not compatible with defining a custom_fetch function.
Instead we have to extend the system to support passing a custom
function for processing just the final list of rows right before it's
returned for writing to export files.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
03887bf871 export: Don't turn non-consented deactivated users into mirror dummies.
As explained in the comment, if we turn a non-consented deactivated user
into a mirror dummy, this will violate the rule that a deactivated user
cannot restore their account by themselves after an export->import
cycle.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
85a98009cd export: Treat is_mirror_dummy=True users as consenting.
As explained in the comment added to the function, in terms of privacy
concerns, it is fine to export all data for these accounts. And it is
important to do - so that exporting an organization which was originally
imported e.g. from Slack doesn't result in excessively limited data for
accounts that were mirror dummies and never "activated" themselves.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
a956c31645 export: Treat deactivated user with consent enabled as consenting.
Prior to this, deactivated user were presumed to be non-consenting to
private data export, regardless of their setting.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
0b5d0a348e export: Fix get_consented_user_ids to also account for bots.
Now that we severely limited the way that non-consenting users get
exported, we need to start to consider bots as consenting when
appropriate - otherwise the exported bot accounts will be unusable after
importing.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
82f17b14d3 export: Scrub RealmAuditLog rows where modified_user is non-consenting. 2025-03-28 17:44:28 -07:00
Mateusz Mandera
479b1dea84 export: Don't export real email of users unless accessible to admins.
An administrator shouldn't be able to bypass a user's setting to hide
their email address from everyone, including admins.
Therefore, we should overwrite the delivery_email for such users during
export - unless the user consented to have their private data exported.

The notable consequence of this is that such user accounts will become
completely inaccessible after importing this data to a new server, due
to not having a functional email address on record.

These accounts will only be possible to reclaim via a manual
intervention to change the email address on the `UserProfile` by server
administrators.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
9a49b6a62c export: Plumb consented_user_ids to export_usermessage_batch in a file.
This allows us to get rid of the call to `get_consented_user_ids` in
`fetch_usermessages`. Now it's only called at the beginning of the
export, eliminating the redundant db query and also resolving the
potential for data consistency issues, if some users change their
consent setting after the export starts.

Now the full export process operates with a single snapshot of these
consenting user ids.

These ids need to be plumbed through via a file rather than normal arg
passing, because this is a separate management command, run in
subprocesses during the export.
2025-03-28 17:44:28 -07:00
Mateusz Mandera
b56b9d570d export: Reset settings to default for users not in exportable_user_ids.
These users didn't consent to having their private data exported.
Therefore, correct handling of these users should involve scrubbing
their settings to just match the realm defaults.
2025-03-28 17:44:27 -07:00
Mateusz Mandera
69da235ed1 export: Use exportable_user_ids arg to plumb through consenting users.
Instead of making repeated calls to get_consented_user_ids, we can just
fetch it (mostly) once and put it in
`context["exportable_user_ids"]`. This is essentially what the
(unused until now) exportable_user_ids logic was added for after all.

The added, intended, effect of this is that non-consenting users will
now get exported as mirror dummy accounts, due to the handling of
non-exportable users in `custom_fetch_user_profile`.

The remaining additional call to `get_consented_user_ids` is in
`fetch_usermessages`. This one is tricky as this function gets called
in subprocesses via
`zerver/management/commands/export_usermessage_batch.py` management
command invoked by the export process.
It requires passing the `exportable_user_ids` in some other way. This
can be dealt with in upcoming commits.
2025-03-28 17:44:27 -07:00
Mateusz Mandera
f2024ad625 export: Only export Client objects needed by the data being exported.
We shouldn't export the entire Client table - it includes Clients for
all the realms on the server, completely unrelated to the realm we're
exporting. Since these contain parts of the UserAgents used by the
users, we should treat these as private data and only export the Clients
that the specific data we're exporting "knows" about.
2025-03-28 17:44:27 -07:00
Mateusz Mandera
7e599cf959 export: Don't export miscellaneous private data of non-consenting users. 2025-03-28 17:44:27 -07:00
Anders Kaseorg
87e4b99706 custom_profile_fields: Restrict access to users in the same realm.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-03-28 17:41:32 -07:00
Aman Agrawal
83d917853e apps: Provide arm64 app build by default for macOS.
This reduces confusion amount users when they download the
intel version and it works super slow. Downloading the arm64
version on an intel mac would just not work.

Users who use intel macs have a habit now (atleast me) to look
for `Intel` version of software when downloading an app. So, made
`Intel` bold to help that process.
2025-03-28 16:45:07 -07:00
Anders Kaseorg
721f804736 middleware: Parse Accept header properly.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2025-03-26 22:29:09 -07:00
Niloth P
b2910aa05c integration-docs: Migrate PythonAPIIntegration docs.
To zulip/python-zulip-api, to keep them closer to their source code.

- Renamed the generate_zulip_bots_static_files to
generate_bots_integrations_static_files to accomodate the new function.
- Added a new function to
tools/setup/generate_bots_integrations_static_files to copy the
integration docs into static/generated/integrations.
- Updated integrations.py and computed_settings.py to use the new doc
paths.
- Deleted the affected integration docs.
- Updated the dependency URL.
2025-03-26 11:19:31 -07:00
Niloth P
e76ace28d2 integration-docs: Rename Jira doc to avoid collision with Jira plugin.
The Jira plugin integration doc will be moved in the next commit, to
"static/generated/integrations/jira/doc.md", as the directory name of
the integration is "jira" in zulip/python-zulip-api.

- Jira integration doc (previously) - "zerver/webhooks/jira/doc.md"
- Jira plugin integration doc (next commit) -
"static/generated/integrations/jira/doc.md"

Both of these will use the same path "jira/doc.md" as their
integration.doc value, and the actual file is loaded based on the order
of template directories listed in computed_settings.py.

Hence, use a custom path for the Jira integration doc to avoid this
collision.
2025-03-26 11:19:31 -07:00
Niloth P
4b9317cee4 integrations: Add missing directory_name for Jira plugin integration. 2025-03-26 11:19:31 -07:00