Importing `upload_backend` directly means that in testing it must also
be mocked where it is imported, in order to correctly test the right
backend. Since `get_avatar_url` is part of the public
`ZulipUploadBackend` API, add another helper method to call that.
The `django-sendfile2` module unfortunately only supports a single
`SENDFILE` root path -- an invariant which subsequent commits need to
break. Especially as Zulip only runs with a single webserver, and
thus sendfile backend, the functionality is simple to inline.
It is worth noting that the following headers from the initial Django
response are _preserved_, if present, and sent unmodified to the
client; all other headers are overridden by those supplied by the
internal redirect[^1]:
- Content-Type
- Content-Disposition
- Accept-Ranges
- Set-Cookie
- Cache-Control
- Expires
As such, we explicitly unset the Content-type header to allow nginx to
set it from the static file, but set Content-Disposition and
Cache-Control as we want them to be.
[^1]: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/
Enforcing a consistent `type` helps us double-check that we're not
playing fast-and-loose with any file paths for local files. As noted
in the comment, this is purely for defense-in-depth.
Passing `write_local_file` a consistent `type` requires removing the
"avatars" out of `realm_avatar_and_logo_path` -- which makes it
consistent across upload backends.
This, in turn, requires a compensatory change to zerver.lib.export, to
be explicit that the realm icons are exported from the avatars
directory. This clarity is likely an improvement.
sendfile already applied a Content-Disposition header, but the
algorithm may provide both `filename=` and `filename*=` values (which
is potentially confusing to clients) and incorrectly slash-escapes
quotes in Unicode strings.
Django provides a correct implementation, but it is only accessible to
FileResponse objects. Since the entire point is to offload the
filehandle handling, we cannot use a FileResponse.
Django 4.2 will make the function available outside of FileResponse.
Until then, extract our own Content-Disposition handling, based on
Django's.
We remove the very verbose comment added in d4360e2287, describing
Content-Disposition headers, as it does not add much.
As uploads are a feature of the application, not of a generic nginx
deployment, move them into the `zulip::app_frontend_base` class. This
is purely for organizational clarity -- we do not support deployments
with has `zulip::nginx` but not `zulip::app_frontend_base`.
Previously, `templates/zerver/api/missing.md` was a symlink to the
file in the help center documentation.
Prep commit for moving the help center documentation to a top level
directory.
Add more tests analogous to existing ones but for different scenarios.
This is mostly boring text, but is important for completeness, since the
notificability logic underneath is subtle.
Split the one giant `test_end_to_end_missedmessage_hook` into many
smaller tests.
This allows us to not worry about resetting database state after each
test case and also allows extracting a lot of common stuff into setUp
and tearDown.
There is probably even more scope of deduplication here (for example,
the mock and the `assert_maybe_enqueue_notifications_call_args` call are
same for all test cases) but that might not be worth the added
complexity.
We also change a few
```
user_profile.<setting> = <value>
user_profile.save()
```
expressions to instead use the `do_change_user_setting` function.
For alert words, we currently don't send email/push notifications --
only desktop notifications. Thus, we don't need to consider alert words
here, since desktop notifications do not utilize the presence status
calculated at this stage.
Tested manually that alert word desktop notifications work as expected.
When we implement email/push notifications for alert words (issues #5137
and #13127), we can add new fields like
`notifications_data.alert_word_email_notify`, similar to the existing
`notifications_data.wildcard_mention_email_notify`, which will allow us
to keep the alert word notifiability check inside the dataclass, similar
to how the mentions checks are done currently. So, even when that
feature is implemented, the code which this commit removes would be
unnecessary.
We now use the undo supporting `insert` function from the
`text-field-edit` module to update the text after autocompletion,
instead of just resetting the value of the textarea / input, which was
not undo-able.
So that the undo history seems sensible, we replace only the minimal
diff between the text before and after autocompletion. This ensures
that only this diff, and not the entire text, is highlighted when
undoing, as would be ideal.
Fixes: #14311.
The new function specifies the single minimal diff between 2 strings.
It takes in 2 string parameters and returns an array with 3 integers
where the 1st is the index where the difference starts and the 2nd and
3rd are the indices of the end of the diff in the 2 strings.
Updates the help center articles on restricting email and avatar
changes so that it is clear that administrators can always change
these settings for themselves.
Also, fixes a broken link and a few small text/formatting errors.
--attachments is redundant and should not be used:
```
$ mmctl export create --attachments
Flag --attachments has been deprecated, the tool now includes attachments by default. The flag will be removed in a future version.
```
Intercom sends a HEAD request to validate the webhook URL on their side,
which was not expected in the previous implementation.
This fixes the problem that we send out a confusing error message for it.
Fixes#23912.
Signed-off-by: Zixuan James Li <p359101898@gmail.com>
Uptil now, with the composebox expanded and some content in it, when a
task in a todo widget was clicked, it did not toggle as expected but
focused the composebox, selecting all the text in it.
This is fixed by ensuring the task is a clickable message element and
clicking it doesn't collapse the composebox. This has the added benefit
of fixing the bug where toggling a task expanded a collapsed composebox.
Fixes: #22928.
During installation on a new host, `create-database` attempts to
verify that there isn't a bunch of data already in the database which
is it about to drop and recreate. In the most common case, this
statement emits a scary-looking warning, since the database does not
exist yet:
```
+ /home/zulip/deployments/current/scripts/setup/create-database
+ POSTGRES_USER=postgres
++ crudini --get /etc/zulip/zulip.conf postgresql database_name
++ echo zulip
+ DATABASE_NAME=zulip
++ crudini --get /etc/zulip/zulip.conf postgresql database_user
++ echo zulip
+ DATABASE_USER=zulip
++ cd /
++ su postgres -c 'psql -v ON_ERROR_STOP=1 -Atc '\''SELECT COUNT(*) FROM zulip.zerver_message;'\'' zulip'
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: database "zulip" does not exist
```
Because we are attempting to gracefully handle the case where the
database does not exist yet, we also continue (and drop the database)
in other, less expected cases -- for instance, if database contains a
schema we do not expect.
Explicitly check for the database existence first, and once we verify
that, allow any further failures in the `SELECT COUNT(*)` to abort
`create-database`. This serves the dual purpose of hiding the "FATAL"
error for the common case when the database does not exist, as well as
preventing dropping the database if anything else goes awry.
This commit refactors the code for dropdown list widget settings
such that we can reuse the added functions for further settings
that will use dropdown_list_widget.
This change will be helpful when we will add group-based settings
and change some of the existing role-based settings to be group-based.
We add a new function "get_widget_for_dropdown_list_settings" to
get the widget variable from setting name. The functions to get
and set the setting value use "get_widget_for_dropdown_list_settings"
function to get the widget and then gets or sets the setting value
accordingly.
We also add "data-setting-widget-type" and "data-setting-value-type"
attributes to the element like other settings.
The "data-setting-widget-type" attr is used by get_input_element_value
to use "get_dropdown_list_widget_setting_value" function for
dropdown-list-widget settings.
The "data-setting-value-type" attribute is used to parse the setting
value to correct types in "get_dropdown_list_widget_setting_value"
function.
There are a few account settings that are possibly deactivated if
a user is not an administrator (email, name and avatar changes),
depending on the organization's policy for changing those settings.
When a user's role is updated to become (or no longer be) an admin,
the display for these account settings may need to be updated.
Adds `settings_account.update_account_settings_display` to the
functions called in `user_events.update_person` if the active
user's role is changed to or from an administrator role.