Commit Graph

1234 Commits

Author SHA1 Message Date
Tim Abbott 342a9bd5cd zulip_updates: Prevent racing with self using a lock. 2024-04-18 15:14:02 -07:00
Anders Kaseorg f31579a220 python: Avoid relying on Collection supertype of QuerySet.
QuerySet doesn’t implement __contains__, so it can’t be a subtype of
Container or Collection (https://code.djangoproject.com/ticket/35154).
This incorrect subtyping annotation was removed in
https://github.com/typeddjango/django-stubs/pull/1925, so we need to
stop relying on it before upgrading to django-stubs 5.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-16 23:02:16 -07:00
Alex Vandiver d341e6ced1 runtornado: Honor the --skip-checks flag.
This is particularly important because they can be quite heavy-weight.
2024-04-15 14:29:27 -07:00
Prakhar Pratyush bc0325922e commands: Add 'skip-delay' option to send_zulip_update_announcements.
This commit adds a 'skip-delay' option to the
'send_zulip_update_announcements' management command.

It will be useful for self-hosted servers after 9.0 upgrade to
avoid the 24 hour delay to receive update messages after group
DM is sent to the admins.

One can run the management command with the --skip-delay flag
to immediately send the update messages.
2024-04-11 16:13:42 -07:00
rht c77ed52fa9
slack import: Refer the archive file as a file or dir. 2024-04-11 12:05:56 -07:00
Alex Vandiver d834f1fc01 unarchive_stream: Prevent unarchiving a stream in the wrong realm. 2024-04-11 09:41:41 -07:00
Mateusz Mandera 89a22fb076 register_server: Check write access to secrets file when rotate_key.
Using --rotate-key without write access to the secrets file is currently
quite painful, since you end up rotating your registration's secret with
no local record of it; so effectively you lose your registration and
need help from support. We should just prevent this failure mode.
2024-03-22 09:33:00 -07:00
Anders Kaseorg a1a341f0ae ruff: Fix UP032 Use f-string instead of `format` call.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-03-21 08:59:17 -07:00
Prakhar Pratyush 118a7e8d9d zulip_updates: Send zulip updates based on zulip_update_*_level.
This commit adds a management command that will run regularly
as a cron job to send zulip updates to realms based on their
current and latest zulip_update_announcements_level.

For realms with:
* level = None: Send a group DM to admins notifying them about
this new feature & suggestion to set the stream accordingly.

* level = 0:
  * If stream is still not configured, wait for a week
    before setting their level to latest level. They will
    miss updates until their configure the stream.
  * If stream is configured, send updates.

* level > 0: Send one message/update per level & increase
  the level by 1 till the latest level.

Fixes #28604.
2024-03-20 11:48:06 -07:00
Alex Vandiver 64df8c7075 send_custom_email: is_realm_admin is a property, not a real column. 2024-03-19 13:19:45 -07:00
Alex Vandiver be59ef9c02 runtornado: Swap deferred reload events to the default.
This makes no immediate reloads the default for runtornado, matching
the production configuration, and changes the development incantation
to be the one to specify the departure from the norm, with
--immediate-reloads.
2024-02-26 22:29:19 -08:00
Alex Vandiver 8e7ab57bf2 export_search: Support exporting DMs or huddles. 2024-02-25 09:34:17 -08:00
Alex Vandiver b25d966352 tornado: Add a --no-immediate-reloads flag to leave web clients alone. 2024-02-15 15:42:50 -08:00
Anders Kaseorg 93198a19ed requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-29 10:41:54 -08:00
Alex Vandiver e1acd7b974 process_queue: For threaded workers, create them when they start.
Creating the QueueProcessingWorker objects when the ThreadedWorker is
created can lead to a race which caused confusing error messages:

1. A thread tries to call `self.worker = get_worker()`
2. This call raises an exception, which is caught by
   `log_and_exit_if_exception`
3. `log_and_exit_if_exception` sends our process a SIGUSR1, _but
    otherwise swallows the error_.
4. The thread's `.run()` is called, which tries to access
   `self.worker`, which was never set, and throws another exception.
5. The process handles the SIGUSR1, restarting.

Move the creation of the worker to when it is started, so the worker
object does not need to be stored, and possibly have a decoupled
failure.
2024-01-12 08:38:46 -08:00
Alex Vandiver 5b1387c9ba send_password_reset_email: Add a flag to only email users who need it.
Emailing the password reset email to users who have already logged in
is not as useful.
2024-01-07 16:43:31 -08:00
Alex Vandiver 6635f3ea12 send_password_reset_email: Narrow type of users.
5a32ea52ae changed the return type of `get_users`, enabling this.
2024-01-07 16:43:31 -08:00
Alex Vandiver 511cc4d8f7 management: Provide a way to deactivate the push registration. 2024-01-04 15:34:28 -08:00
Alex Vandiver bd38e6cb69 send_email: Distinct emails means distinct, case-insensitively. 2024-01-04 10:46:53 -08:00
Alex Vandiver 8d9ead0f6d send_custom_email: Order by delivery_email if necessary.
If we `.distinct("delivery_email")` then we must also
`.order_by("delivery_email")`; adc987dc43 added the `.order_by`
call, which broke the newsletter codepath, since it did not contain
the `delivery_email` in the ordering fields.

Add a flag to distinct on emails in `send_custom_email`.
2024-01-04 10:46:53 -08:00
Alex Vandiver 0697247d59 send_custom_email: Send to recently-active plus owners and admins.
The set of `enable_marketing_emails=True` are those that have opted
into getting marketing newsletter emails -- but we previously limited
further to only those users active in the last month.

Broaden that to "opted in, and either recently active or an owner or
an admin," with the goal of providing information to folks who may
have tried out Zulip in the past.

Co-authored-by: Tim Abbott <tabbott@zulip.com>
2024-01-04 10:46:53 -08:00
Anders Kaseorg cff0b78771 models: Move some functions to zerver.lib.attachments.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg 4aa2d76bea models: Extract zerver.models.streams.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg 21ab3858a7 models: Extract zerver.models.linkifiers.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg cd96193768 models: Extract zerver.models.realms.
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 b472d769d1 change_user_role: List role choices in --help output.
Fixes #28227.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-14 15:06:18 -08:00
Alex Vandiver 612f2c73d6 send_custom_email: Support JSON extra context with remote servers. 2023-12-13 22:28:20 -08:00
Alex Vandiver 2863b5954e send_custom_email: Make --json an additional filter, not a target. 2023-12-13 22:28:20 -08:00
Alex Vandiver 791d66fe28 send_custom_email: Split out the sending to remote servers. 2023-12-13 22:28:20 -08:00
Alex Vandiver 62e6b10ecd send_email: Pull admins_only back into send_custom_email filtering.
There is no reason for this to be an explicit argument to
send_custom_email, when the rest of the filtering already happens
upstream.
2023-12-13 22:28:20 -08:00
Alex Vandiver 1229e38a0d send_custom_email: Stop lying about the type of options.
Saying `**options: str` is a lie, since it contains bools.  We pluck
out the two bools that we need properly typed because we will be
pushing them into function calls, and type them explicitly as bools.
2023-12-13 22:28:20 -08:00
Alex Vandiver 44e9171a46 register_server: POST requests take data, not params.
This currently _works_, but only because we are very forgiving about
how we parse requests.
2023-12-12 19:58:19 -08:00
Prakhar Pratyush 886a86866d register_server: Send server data just after registering server.
We call 'send_server_data_to_push_bouncer' just after registering
server for push notification.

This helps to have a current state of the user counts when first
logging in after the RemoteRealm flow.
2023-12-11 14:07:39 -08:00
Mateusz Mandera a45438619d register_server: Update all the text. 2023-12-10 15:39:10 -08:00
Anders Kaseorg cf16ddd4d6 tornado: Fix autoreload for Tornado 6.4 changes.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-09 14:24:45 -08:00
Anders Kaseorg 396e995502 requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-07 14:41:01 -08:00
Tim Abbott 9d3ef7f589 settings: Print about custom settings from runtornado. 2023-12-05 12:33:34 -08:00
Anders Kaseorg 8a7916f21a python: Consistently use from…import for datetime.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-05 12:01:18 -08:00
Alex Vandiver 3eb5b20c41 register_server: Redact the key when printing it. 2023-11-29 09:56:14 -08:00
Mateusz Mandera 1819b85b85 management: Allow changing is_billing_admin using change_user_role. 2023-11-15 18:36:07 -08:00
Anders Kaseorg 14b7d097a0 compilemessages: Normalize language names to NFC.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-10-26 16:27:35 -07: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 b49938265f backup: Only pass --host and --port if non-empty.
This works around the `/usr/bin/pg_dump` failure described in the
previous commit.  Since we are now calling the appropriately-versioned
`pg_dump` binary directly, it is no longer "necessary", but is added
as a defense-in-depth.
2023-10-11 11:50:56 -07:00
Alex Vandiver 3a8b4b0205 backup: Call the pg_dump binary whose version we are running.
`/usr/bin/pg_dump` on Ubuntu and Debian is actually a tool which
attempts to choose which `pg_dump` binary from all of the
`postgresql-client-*` packages that are installed to run.  However,
its logic is confused by passing empty `--host` and `--port` options
-- instead of looking at the running server instance on the server, it
instead assumes some remote host and chooses the highest versioned
`pg_dump` which is installed.

Because Zulip writes binary database backups, they are sensitive to
the version of the client `pg_dump` binary is used -- and the output
may not be backwards compatible.  Using a PostgreSQL 16 `pg_dump`
writes archive format 1.15, which cannot be read by a PostgreSQL 15
`pg_restore`.

Zulip does not currently support PostgreSQL 16 as a server.  This
means that backups on servers with `postgresql-client-16` installed
did not successfully round-trip Zulip backups -- their backups are
written using PostgreSQL 16's client, and the `pg_restore` chosen on
restore was correctly chosen as the one whose version matched the
server (PostgreSQL 15 or below), and thus did not understand the new
archive format.

Existing `./manage.py backups` taken since `postgresql-client-16` were
installed are thus not directly usable by the `restore-backup` script.
They are not useless, however, since they can theoretically be
converted into a format readable by PostgreSQL 15 -- by importing into
a PostgreSQL 16 instance, and re-dumping with a PostgreSQL 15
`pg_dump`.

Fix this issue by hard-coding path to the binary whose version matches
the version of the server we are connected to.  This may theoretically
fail if we are connected to a remote PostgreSQL instance and we do not
have a `postgresql-client` package locally installed which matches the
remote PostgreSQL server's version.  However, choosing a matching
version is the only way to ensure that it will be able to be imported
cleanly -- and it is preferable that we fail the backup process rather
than write backups that we cannot easily restore from.

Fixes: #27160.
2023-10-11 11:50:56 -07:00
Alex Vandiver 9d46b41e25 backup: Use simpler api for server version. 2023-10-11 11:50:56 -07:00
Alex Vandiver f3cd1c4b08 delete_old_unclaimed_attachments: Update docs on default max age.
42f1cb3444 updated the default up, from 1 week to 5 weeks, but did
not adjust the documentation.
2023-09-29 09:49:03 -07:00
Alex Vandiver 71e297efb4 realm: Differentiate reserved realms from in-use realms.
Fixes: #23896.
2023-09-25 12:48:14 -07:00
David Rosa cb123d4f15 management: Rename command reactivate_stream -> unarchive_stream. 2023-09-19 15:03:33 -07:00
Anders Kaseorg 2665a3ce2b python: Elide unnecessary list wrappers.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-13 12:41:23 -07:00
Anders Kaseorg 6988622fe8 ruff: Enable B023 Function definition does not bind loop variable.
Python’s loop scoping is misdesigned, resulting in a very common
gotcha for functions that close over loop variables [1].  The general
problem is so bad that even the Go developers plan to break
compatibility in order to fix the same design mistake in their
language [2].

Enable the Ruff rule function-uses-loop-variable (B023) [3], which
conservatively prohibits functions from binding loop variables at all.

[1] https://docs.python-guide.org/writing/gotchas/#late-binding-closures
[2] https://go.dev/s/loopvar-design
[3] https://beta.ruff.rs/docs/rules/function-uses-loop-variable/

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-11 18:03:45 -07:00
Alex Vandiver d6745209f2 django: Use .exists() instead of .count() when possible. 2023-09-11 15:00:37 -07:00
Tim Abbott bcff5580d1 makemessages: Fix handling of handlebars whitespace control.
Our logic for extracting strings from templates did not properly
handle the syntax for code containing whitespace control characters,
resulting in a couple strings from subscribe_to_more_streams.hbs not
being processed.
2023-09-08 09:09:46 -07:00
Alex Vandiver c2c67a7640 send_email: Broaden type of context dict.
jinja2 can take objects and other data structures.
2023-08-30 11:54:28 -07:00
Anders Kaseorg d26a94a0db management: Validate string_id when creating or renaming a realm.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-08-23 16:33:13 -07:00
Alex Vandiver 292595afc4 send_custom_email: Add a mode which reads data from JSON.
This allows us to not have to keep extending the tool for every
one-off use case and set of users; we build a pipeline to generate the
appropriate JSON file, write a template which uses the data it
provides, and run the tool with them together.
2023-08-09 15:49:49 -07:00
Alex Vandiver 95b0ab31be send_custom_email: Only put the unsubscribe footer on marketing emails. 2023-08-09 15:49:49 -07:00
Alex Vandiver 5a32ea52ae send_custom_email: Stop turning every user query into an id-based set.
The set of objects in the `users` object can be very large (in some
cases, literally every object in the database) and making them into a
giant `id in (...)` to handle the one tiny corner case which we never
use is silly.

Switch the `--users` codepath to returning a QuerySet as well, so it
can be composed.  We pass a QuerySet into send_custom_email as well,
so it can ensure that the realm is `select_related` in as well, no
matter how the QuerySet was generated.
2023-08-09 15:49:49 -07:00
Alex Vandiver 6b25fab38c send_custom_email: Use a mutually-exclusive group for recipients. 2023-08-09 15:49:49 -07:00
Anders Kaseorg c4748298bb ruff: Fix PERF102 Using only the keys/values of a dict.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-08-07 17:23:55 -07:00
Anders Kaseorg e932e2ce52 ruff: Fix UP032 Use f-string instead of `format` call.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-08-02 15:58:55 -07:00
Anders Kaseorg ff409342e1 runtornado: Fix COM818 Trailing comma on bare tuple prohibited.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-07-31 13:35:04 -07:00
Sahil Batra 63cc18a94b sync_ldap_user_data: Pass realm as arg to select_related.
This commit updates the select_related calls in queries
to get UserProfile objects in sync_ldap_user_data code
to pass "realm" as argument to select_related call.

Also, note that "realm" is the only non-null foreign key
field in UserProfile object, so select_related() was only
fetching realm object previously as well. But we should
still pass "realm" as argument in select_related call so
that we can make sure that only required fields are
selected in case we add more foreign keys to UserProfile
in future.
2023-07-20 10:44:39 -07:00
Sahil Batra 577555e529 send_custom_email: Pass realm as arg to select_related.
This commit updates the select_related calls in queries
to get UserProfile objects in send_custom_email code to
pass "realm" as argument to select_related call.

Also, note that "realm" is the only non-null foreign key
field in UserProfile object, so select_related() was only
fetching realm object previously as well. But we should
still pass "realm" as argument in select_related call so
that we can make sure that only required fields are selected
in case we add more foreign keys to UserProfile in future.
2023-07-20 10:44:39 -07:00
Alex Vandiver b188e6fa04 management: Add a reactivate-stream command.
Fixes #601.
2023-07-17 17:42:54 -07:00
Steve Howell 890732a88f soft activation: Avoid QuerySet and use List instead. 2023-07-13 08:09:14 -07:00
Lauryn Menard dd59e83d54 welcome-emails: Make some code comments and docstrings more evergreen. 2023-07-11 14:15:52 -07:00
Lauryn Menard 8c0d89a225 delete-user: Update management command help doc-string.
Updates the help doc-string for the delete_user management command
to use "direct message" instead of "private message".
2023-06-23 11:24:13 -07:00
Alex Vandiver 38d1b3314a convert_slack_data: Document "--token" more correctly. 2023-06-23 11:09:45 -07:00
Anders Kaseorg b7909db987 ruff: Fix PLC0208 Use a sequence type when iterating over values.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-06-06 14:58:11 -07:00
rht 1c84f02f57 slack import: Convert threads to nicely named Zulip topics.
Fixes #9006.
2023-05-30 16:35:19 -07:00
Alex Vandiver 9f231322c9 workers: Pass down if they are running multi-threaded.
This allows them to decide for themselves if they should enable
timeouts.
2023-05-16 14:05:01 -07:00
Sahil Batra 7f01b3fb63 users: Set tos_version to -1 for users who have not logged-in yet.
We now set tos_version to "-1" for imported users and the ones
created using API or using other methods like LDAP, SCIM and
management commands. This value will help us to allow users to
change email address visibility setting during first login.
2023-05-16 13:52:56 -07:00
Tim Abbott fe9656237e scheduled_message: Move remaining logic out of management command.
While this doesn't include tests yet, it will make it much easier to
write tests for the core server logic here.
2023-05-09 13:48:28 -07:00
Tim Abbott 7051d3416b scheduled_messages: Add reasonable failure handling.
Previously, it seemed possible for the scheduled messages API to try
to send infinite copies of a message if we had the very poor luck of a
persistent failure happening after a message was sent.

The failure_message field supports being able to display what happened
in the scheduled messages modal, though that's not exposed to the API
yet.
2023-05-09 13:48:28 -07:00
Tim Abbott 24bb03c89f scheduled_messages: Add logging on successful send. 2023-05-09 13:48:28 -07:00
Tim Abbott 1fc6ed224a scheduled_messages: Remove batching logic.
The previous logic would attempt to send a large number of unrelated
messages in a single transaction, which is just asking for trouble in
the event that one of the attempts fails.
2023-05-09 13:48:28 -07:00
Tim Abbott c8f3443fb6 schedules_messages: Move logic out of management command. 2023-05-09 13:48:28 -07:00
Tim Abbott 611cee177d deliver_scheduled_messages: Rename misleading message variable. 2023-05-09 13:48:28 -07:00
Lauryn Menard a5b527f321 onboarding: Specialize Welcome Bot message for education organizations.
Because education organizations and users have slightly specialized
use cases, we update the Welcome Bot message content sent to new
users and new organization owners for these types of organizations
to link to help center articles/guides geared toward these users
and organizations.

Also, updates the demo organization warning to only go to the new
demo organization owner because the 30 day deletion text is only
definitely accurate when the organization is created.

Fixes #21694.
2023-05-01 16:48:48 -07:00
Anders Kaseorg 03b3c8522d requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-04-25 21:20:33 -07:00
Zixuan James Li 032e6f8cb4 linkifier: Update edit_linkifier command to use url_template.
This is mainly updating the variable names and relevant docstrings
without actual change to the behavior of the command.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2023-04-19 12:20:49 -07:00
Mateusz Mandera ffa3aa8487 auth: Rewrite data model for tracking enabled auth backends.
So far, we've used the BitField .authentication_methods on Realm
for tracking which backends are enabled for an organization. This
however made it a pain to add new backends (requiring altering the
column and a migration - particularly troublesome if someone wanted to
create their own custom auth backend for their server).

Instead this will be tracked through the existence of the appropriate
rows in the RealmAuthenticationMethods table.
2023-04-18 09:22:56 -07:00
Alex Vandiver e3f6e810dc export-search: Support writing out attachments as well. 2023-04-07 09:13:48 -07:00
Alex Vandiver 885334a3ad export-search: Support CSV output, trim down output fields. 2023-04-07 09:13:48 -07:00
Alex Vandiver bde978d5b1 export-search: Move topic into recipient field. 2023-04-07 09:13:48 -07:00
Alex Vandiver 26bc112adc export-search: Add a --recipient filter. 2023-04-07 09:13:48 -07:00
Alex Vandiver e44ba1bef1 export-search: Write output size before beginning export. 2023-04-07 09:13:48 -07:00
Alex Vandiver 21db267202 export-search: Non-time-limited is fine with a sender. 2023-04-07 09:13:48 -07:00
Alex Vandiver ae20af84a9 export-search: Realm is required. 2023-04-07 09:13:48 -07:00
Daniil Fadeev 2f203f4de1 emails: Inline CSS in emails in build_email.
Previously, we had an architecture where CSS inlining for emails was
done at provision time in inline_email_css.py. This was necessary
because the library we were using for this, Premailer, was extremely
slow, and doing the inlining for every outgoing email would have been
prohibitively expensive.

Now that we've migrated to a more modern library that inlines the
small amount of CSS we have into emails nearly instantly, we are able
to remove the complex architecture built to work around Premailer
being slow and just do the CSS inlining as the final step in sending
each individual email.

This has several significant benefits:

* Removes a fiddly provisioning step that made the edit/refresh cycle
  for modifying email templates confusing; there's no longer a CSS
  inlining step that, if you forget to do it, results in your testing a
  stale variant of the email templates.
* Fixes internationalization problems related to translators working
  with pre-CSS-inlined emails, and then Django trying to apply the
  translators to the post-CSS-inlined version.
* Makes the send_custom_email pipeline simpler and easier to improve.

Signed-off-by: Daniil Fadeev <fadeevd@zulip.com>
2023-04-05 12:22:29 -07:00
Alex Vandiver 113a8c4782 export: Make --deactivate-realm exports be imported as active. 2023-04-03 16:08:43 -07:00
Alex Vandiver 822683249d web: Save a 301 redirect from /terms/ to /policies/terms. 2023-03-24 14:51:01 -07:00
Anders Kaseorg b719227b04 ruff: Fix C416 Unnecessary `dict` comprehension.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-24 11:57:07 -07:00
Alex Vandiver 8ad4ecb3a2 management: Add a command to send initial welcome bot messages. 2023-03-21 11:40:37 -07:00
Anders Kaseorg 8cd78d356f templates: Allow the same line-wrapping in {{t}} as in {{#tr}}.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-16 11:26:45 -07:00
Anders Kaseorg d3efd4c095 python: Import F, Q, QuerySet from their canonical module.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-05 14:46:28 -08:00
Anders Kaseorg 43b4f10578 run-dev: Drop .py from script name.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-03-03 18:02:37 -08:00
Alex Vandiver 3bf3f47b49 delete_old_unclaimed_attachments: Add flag to clean up storage.
Actions like deleting realms may leave unreferenced uploads in the
attachment storage backend.

Fix these by walking the complete contents of the attachment storage
backend, and removing files which are no longer present in the
database.  This may take quite some time, as it is necessarily O(n) in
the number of files uploaded to the system.
2023-03-02 16:36:19 -08:00
Alex Vandiver cdda4bc089 delete_realm: Clean up attachments when deleting or scrubbing realms. 2023-03-02 16:36:19 -08:00