From d640e4ac96005cdc2b21b6a08f97a8805c26d00b Mon Sep 17 00:00:00 2001
From: Hugh Rundle
Date: Tue, 16 Jan 2024 21:32:13 +1100
Subject: [PATCH 1/2] disable user exports by default
- new setting to enable user exports defaults to False
- add setting to enable and disable user exports
- do not allow user exports when using s3 storage
- do not serve non-image files from /images/ (requires update to nginx settings)
- increase default file upload limit to 100MB to enable user exports to be imported (can be changed in .env)
---
.env.example | 3 ++
.../0192_sitesettings_user_exports_enabled.py | 18 +++++++
bookwyrm/models/site.py | 1 +
bookwyrm/settings.py | 2 +
.../templates/preferences/export-user.html | 6 ++-
.../templates/settings/imports/imports.html | 51 ++++++++++++++++++-
bookwyrm/urls.py | 10 ++++
bookwyrm/views/__init__.py | 2 +
bookwyrm/views/admin/imports.py | 25 ++++++++-
nginx/development | 7 ++-
nginx/production | 7 ++-
11 files changed, 127 insertions(+), 5 deletions(-)
create mode 100644 bookwyrm/migrations/0192_sitesettings_user_exports_enabled.py
diff --git a/.env.example b/.env.example
index fb0f7308d..20ce8240b 100644
--- a/.env.example
+++ b/.env.example
@@ -137,3 +137,6 @@ TWO_FACTOR_LOGIN_MAX_SECONDS=60
# and AWS_S3_CUSTOM_DOMAIN (if used) are added by default.
# Value should be a comma-separated list of host names.
CSP_ADDITIONAL_HOSTS=
+# The last number here means "megabytes"
+# Increase if users are having trouble uploading BookWyrm export files.
+DATA_UPLOAD_MAX_MEMORY_SIZE = (1024**2 * 100)
\ No newline at end of file
diff --git a/bookwyrm/migrations/0192_sitesettings_user_exports_enabled.py b/bookwyrm/migrations/0192_sitesettings_user_exports_enabled.py
new file mode 100644
index 000000000..ec5b411e2
--- /dev/null
+++ b/bookwyrm/migrations/0192_sitesettings_user_exports_enabled.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.23 on 2024-01-16 10:28
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("bookwyrm", "0191_merge_20240102_0326"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="sitesettings",
+ name="user_exports_enabled",
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py
index bd53f1f07..8075b6434 100644
--- a/bookwyrm/models/site.py
+++ b/bookwyrm/models/site.py
@@ -96,6 +96,7 @@ class SiteSettings(SiteModel):
imports_enabled = models.BooleanField(default=True)
import_size_limit = models.IntegerField(default=0)
import_limit_reset = models.IntegerField(default=0)
+ user_exports_enabled = models.BooleanField(default=False)
user_import_time_limit = models.IntegerField(default=48)
field_tracker = FieldTracker(fields=["name", "instance_tagline", "logo"])
diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py
index fcc91857a..cc941da84 100644
--- a/bookwyrm/settings.py
+++ b/bookwyrm/settings.py
@@ -442,3 +442,5 @@ if HTTP_X_FORWARDED_PROTO:
# Do not change this setting unless you already have an existing
# user with the same username - in which case you should change it!
INSTANCE_ACTOR_USERNAME = "bookwyrm.instance.actor"
+
+DATA_UPLOAD_MAX_MEMORY_SIZE = env.int("DATA_UPLOAD_MAX_MEMORY_SIZE", (1024**2 * 100))
diff --git a/bookwyrm/templates/preferences/export-user.html b/bookwyrm/templates/preferences/export-user.html
index a468c3f74..cd3119e3e 100644
--- a/bookwyrm/templates/preferences/export-user.html
+++ b/bookwyrm/templates/preferences/export-user.html
@@ -46,7 +46,11 @@
{% trans "If you wish to migrate any statuses (comments, reviews, or quotes) you must either set the account you are moving to as an alias of this one, or move this account to the new account, before you import your user data." %}
{% endspaceless %}
- {% if next_available %}
+ {% if not site.user_exports_enabled %}
+
+ {% trans "New user exports are currently disabled." %}
+
+ {% elif next_available %}
{% blocktrans trimmed %}
You will be able to create a new export file at {{ next_available }}
diff --git a/bookwyrm/templates/settings/imports/imports.html b/bookwyrm/templates/settings/imports/imports.html
index 8898aab71..11b3c7e03 100644
--- a/bookwyrm/templates/settings/imports/imports.html
+++ b/bookwyrm/templates/settings/imports/imports.html
@@ -90,6 +90,33 @@
+
+ {% if site.user_exports_enabled %}
+
+
+
+ {% trans "Disable starting new user exports" %}
+
+
+
+
+
@@ -108,7 +135,7 @@
{% trans "Set the value to 0 to not enforce any limit." %}
-
+
{% csrf_token %}
@@ -120,6 +147,28 @@
+ {% else %}
+
+ {% endif %}
{% trans "Book Imports" %}
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index 76e60245b..1a577c84b 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -338,6 +338,16 @@ urlpatterns = [
views.disable_imports,
name="settings-imports-disable",
),
+ re_path(
+ r"^settings/user-exports/enable/?$",
+ views.enable_user_exports,
+ name="settings-user-exports-enable",
+ ),
+ re_path(
+ r"^settings/user-exports/disable/?$",
+ views.disable_user_exports,
+ name="settings-user-exports-disable",
+ ),
re_path(
r"^settings/imports/enable/?$",
views.enable_imports,
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index 3be813208..f11c11dd6 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -18,6 +18,8 @@ from .admin.imports import (
set_import_size_limit,
set_user_import_completed,
set_user_import_limit,
+ enable_user_exports,
+ disable_user_exports,
)
from .admin.ip_blocklist import IPBlocklist
from .admin.invite import ManageInvites, Invite, InviteRequest
diff --git a/bookwyrm/views/admin/imports.py b/bookwyrm/views/admin/imports.py
index a85d6c79e..0924536bf 100644
--- a/bookwyrm/views/admin/imports.py
+++ b/bookwyrm/views/admin/imports.py
@@ -9,7 +9,7 @@ from django.views.decorators.http import require_POST
from bookwyrm import models
from bookwyrm.views.helpers import redirect_to_referer
-from bookwyrm.settings import PAGE_LENGTH
+from bookwyrm.settings import PAGE_LENGTH, USE_S3
# pylint: disable=no-self-use
@@ -59,6 +59,7 @@ class ImportList(View):
"import_size_limit": site_settings.import_size_limit,
"import_limit_reset": site_settings.import_limit_reset,
"user_import_time_limit": site_settings.user_import_time_limit,
+ "use_s3": USE_S3,
}
return TemplateResponse(request, "settings/imports/imports.html", data)
@@ -126,3 +127,25 @@ def set_user_import_limit(request):
site.user_import_time_limit = int(request.POST.get("limit"))
site.save(update_fields=["user_import_time_limit"])
return redirect("settings-imports")
+
+
+@require_POST
+@permission_required("bookwyrm.edit_instance_settings", raise_exception=True)
+# pylint: disable=unused-argument
+def enable_user_exports(request):
+ """Allow users to export account data"""
+ site = models.SiteSettings.objects.get()
+ site.user_exports_enabled = True
+ site.save(update_fields=["user_exports_enabled"])
+ return redirect("settings-imports")
+
+
+@require_POST
+@permission_required("bookwyrm.edit_instance_settings", raise_exception=True)
+# pylint: disable=unused-argument
+def disable_user_exports(request):
+ """Don't allow users to export account data"""
+ site = models.SiteSettings.objects.get()
+ site.user_exports_enabled = False
+ site.save(update_fields=["user_exports_enabled"])
+ return redirect("settings-imports")
diff --git a/nginx/development b/nginx/development
index 841db0124..ac663053c 100644
--- a/nginx/development
+++ b/nginx/development
@@ -64,13 +64,18 @@ server {
# directly serve images and static files from the
# bookwyrm filesystem using sendfile.
# make the logs quieter by not reporting these requests
- location ~ ^/(images|static)/ {
+ location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp)$ {
root /app;
try_files $uri =404;
add_header X-Cache-Status STATIC;
access_log off;
}
+ # block access to any non-image files from images or static
+ location ~ ^/(images|static)/ {
+ return 403;
+ }
+
# monitor the celery queues with flower, no caching enabled
location /flower/ {
proxy_pass http://flower:8888;
diff --git a/nginx/production b/nginx/production
index 9018ab9de..4e40f32a0 100644
--- a/nginx/production
+++ b/nginx/production
@@ -96,12 +96,17 @@ server {
# # directly serve images and static files from the
# # bookwyrm filesystem using sendfile.
# # make the logs quieter by not reporting these requests
-# location ~ ^/(images|static)/ {
+# location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp)$ {
# root /app;
# try_files $uri =404;
# add_header X-Cache-Status STATIC;
# access_log off;
# }
+
+# # block access to any non-image files from images or static
+# location ~ ^/(images|static)/ {
+# return 403;
+# }
#
# # monitor the celery queues with flower, no caching enabled
# location /flower/ {
From ea7f3c297e6f92ca82c06b6fb3ace0d37ebdd53f Mon Sep 17 00:00:00 2001
From: Hugh Rundle
Date: Wed, 17 Jan 2024 20:12:06 +1100
Subject: [PATCH 2/2] allow js and css
---
nginx/development | 4 ++--
nginx/production | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/nginx/development b/nginx/development
index ac663053c..64cd1b911 100644
--- a/nginx/development
+++ b/nginx/development
@@ -64,7 +64,7 @@ server {
# directly serve images and static files from the
# bookwyrm filesystem using sendfile.
# make the logs quieter by not reporting these requests
- location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp)$ {
+ location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp|css|js)$ {
root /app;
try_files $uri =404;
add_header X-Cache-Status STATIC;
@@ -72,7 +72,7 @@ server {
}
# block access to any non-image files from images or static
- location ~ ^/(images|static)/ {
+ location ~ ^/images/ {
return 403;
}
diff --git a/nginx/production b/nginx/production
index 4e40f32a0..76ed19449 100644
--- a/nginx/production
+++ b/nginx/production
@@ -96,7 +96,7 @@ server {
# # directly serve images and static files from the
# # bookwyrm filesystem using sendfile.
# # make the logs quieter by not reporting these requests
-# location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp)$ {
+# location ~ \.(bmp|ico|jpg|jpeg|png|tif|tiff|webp|css|js)$ {
# root /app;
# try_files $uri =404;
# add_header X-Cache-Status STATIC;
@@ -104,7 +104,7 @@ server {
# }
# # block access to any non-image files from images or static
-# location ~ ^/(images|static)/ {
+# location ~ ^/images/ {
# return 403;
# }
#