This function will be useful in finding out affected groups when
sending events for users gaining or losing metadata access when the
members of a user group change in any way.
If there were no users found for `find_team`, we need to provide
a default langauge for the email as one cannot be extracted from
`UserProfile` in this case.
This refactors `parse_migration_status` to copy the algorithm of
Django's `showmigrations` command instead of parsing its output. This is
done so that the code is not susceptible to breaking changes if Django
modifies showmigrations's implementation.
The previous `parse_migration_status` logic has been repurposed into a
test utility function (`prase_showmigrations`). It is used to verify
that the new `parse_migration_status` generates output identical to the
actual `showmigrations` command.
The `test_clean_up_migration_status_json` is removed because
`test_parse_migration_status` has covered that behavior.
This commit renames "(no topic)" to "" when used as
topic name, while sending or scheduling messages.
This is particularly helpful for older clients where
sending messages with empty topic input box resulted
in messages being sent to "(no topic)" topic.
Now, it will be sent in empty string topic and will
appear in the "general chat" topic.
This helps older clients to somewhat align with the UX
of the clients supporting empty string topic.
Renames WHITELISTED_EMAIL_DOMAINS to OVERRIDE_ALLOW_EMAIL_DOMAINS
as the set of email domains that are allowed even if they are in
the set of disposable email domains.
On the event side, orjson does the work of converting
UserGroupMembersData to json. But when fetching intial state data,
UserGroupMembersData was being returned which is not
json-serializable. This was causing a mismatch in the `verify_action`
workflow of test_events related to stream group settings where
apply_events resulted in a state with `direct_members` and
`direct_subgroups` as part of an ordinary dict, while fetching initial
state data was giving us a UserGroupMembersData class.
This commit uses UserGroupMembersDict where appropriate. It will
still be good to keep around the dataclass class since it has the added
benefit of storing the relevant value when needed.
We set it to True when fetching streams in `fetch_initial_state_data`
and when trying to find newly accessible or inaccesible streams on role
update. We've added tests for role update, but since we don't test
`fetch_initial_state_data` directly, the role update tests changed in
this commit will fail if include_all is not set to True in
`fetch_inital_state_data`.
Tuple is converted into a list by orjson, which in turn causes mismatch
in the initial state and the hybrid state after using apply_events.
Using a list instead helps us prevent that.
UserGroupMembersData is not serializable by orjson. We will be
introducing a TypedDict (which is serializable) in the next commit
called UserGroupMembersDict. This rename will help us distinguish
between the two.
This commit updates the code which computes the dict for
setting groups mapping named user groups to ID and anonymous
groups to UserGroupMembersDict. After the changes, the dict
contains only anonymous groups values and the setting values
for group IDs not present in dict will be computed based on
the fact that those are named user groups.
This is a preparatory refactor for optimizing computing group
setting values for register response by fetching all anonymous
groups membership data just once.
This mirrors the restrictions in
zerver.lib.message.bulk_access_stream_messages_query, in order to
prevent leftover UserMessage rows from granting access to messages the
user was previously allowed to access but no longer is.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit adds a one-time modal to display navigation tour
video to new users.
Includes an `NAVIGATION_TOUR_VIDEO_URL` server-setting to specify
the video's URL. When set to None, the modal is not displayed.
Fixes#29304.
This commit separates the "resolve topic" permissions from the
topic editing permissions, through the introduction of setting -
"can_resolve_topics_group" which user group whose members
can resolve topics.
Fixes#21811
We now return the members and subgroups ID list sorted for
settings that are set to anonymous groups. This is needed to
make sure we do not show save discard buttons when only pill
order is changed.
This commit fixes the code to not include deactivated groups in
stream setting values when the setting is set to an anonymous
group. This is consistent with what we do for realm and user
group settings.
As a result, we also deduplicate some code by using existing
function used for realm and group settings.
Add the `is:muted` search operator.
`-is:muted` is an alias for the `in:home` operator.
Co-authored-by: Kenneth <Kenneth012004@outlook.com>
Fixes#16943
This will allow clients to display MOVED/EDITED indicators, and their
tooltips, without interacting with the `edit_history` section of
message objects, which we plan to remove in the future.
Supporting that requires both introducing both last_moved_timestamp,
and changing the definition of last_edit_timestamp to not include
message moves, which involves recalculating it at the API layer.
The last_moved_timestamp is not present if the topic moves for the
message are for resolving or unresolving the topic. It is always
present for channel moves.
Co-authored-by: Lauryn Menard <lauryn@zulip.com>
Documents organization setting that configures what message edit
history can be viewed: content edits and topic/channel moves, only
topic/channel moves, or disabling viewing edit history completely.
Renames article to match new help article header and creates URL
redirect for previous article header.
Also, clean up and consolidate related articles.
Fixes#33684.
Co-authored-by: Alya Abbott <alya@zulip.com>
Email clients tend to sort emails by the "Date" header, which is not
when the email was received -- emails can be arbitrarily delayed
during relaying. Messages without a Date header (as all Zulip
messages previously) have one inserted by the first mailserver they
encounter. As there are now multiple email-sending queues, we would
like the view of the database, as presented by the emails that are
sent out, to be consistent based on the Date header, which may not be
the same as when the client gets the email in their inbox.
Insert a Date header of when the Zulip system inserted the data into
the local queue, as that encodes when the full information was pulled
from the database. This also opens the door to multiple workers
servicing the email_senders queue, to limit backlogging during large
notifications, without having to worry about inconsistent delivery
order between those two workers.
Messages which are sent synchronously via `send_email()` get a Date
header of when we attempt to send the message; this is, in practice,
no different from Django's default behaviour of doing so, but makes
the behaviour slightly more consistent.
This table's export and import weren't working:
1. It didn't have a Config in export.py, so it wasn't exported at all.
2. Its `date_created` wasn't registered in `DATE_FIELDS`.
3. It wasn't registered in `ID_MAPS` in import_realm.py, so having any
SavedSnippets in the export would cause the import to fail with an
exception.
4. It was missing a `fix_datetime_fields` call in its import codepath.
Without this change, the child tables of UserProfile didn't get their
objects exported if those objects were tied to a mirror dummy user.
For example, a `Recipient` of type `PERSONAL`, or the associated
`Subscription` would not get exported. Same for other tables with
foreign keys to `UserProfile` - such as `UserPresence`.
This happened because the Configs for the export are defined as follows:
```python
user_profile_config = Config(
custom_tables=[
"zerver_userprofile",
"zerver_userprofile_mirrordummy",
],
# set table for children who treat us as normal parent
table="zerver_userprofile",
virtual_parent=realm_config,
custom_fetch=custom_fetch_user_profile,
)
user_subscription_config = Config(
table="_user_subscription",
model=Subscription,
normal_parent=user_profile_config,
filter_args={"recipient__type": Recipient.PERSONAL},
include_rows="user_profile_id__in",
)
Config(
table="_user_recipient",
model=Recipient,
virtual_parent=user_subscription_config,
id_source=("_user_subscription", "recipient"),
)
```
while in `export_from_config` we have:
```python
elif config.normal_parent:
# In this mode, our current model is figuratively Article,
# and normal_parent is figuratively Blog, and
# now we just need to get all the articles
# contained by the blogs.
model = config.model
assert parent is not None
assert parent.table is not None
assert config.include_rows is not None
parent_ids = {r["id"] for r in response[parent.table]}
```
This meant that when processing a table with
`normal_parent=user_profile_config`, the `parent_ids` above would only
have the ids of `UserProfile` objects under the `zerver_userprofile` key in
the exported data - completely missing those in
`zerver_userprofile_mirrordummy`.
Removed `is_billing_admin` user property as it is no longer used since
billing permissions are now determined by `can_manage_billing_group`
realm setting.
Since this does impact the ability to access the channel's content, it
makes sense to permit changing subscriptions, just like other
permissions settings on the archived channel.