diff --git a/.env.example b/.env.example index b47c683c5..2be08224b 100644 --- a/.env.example +++ b/.env.example @@ -126,3 +126,8 @@ HTTP_X_FORWARDED_PROTO=false # which will be accepted. TWO_FACTOR_LOGIN_VALIDITY_WINDOW=2 TWO_FACTOR_LOGIN_MAX_SECONDS=60 + +# Additional hosts to allow in the Content-Security-Policy, "self" (should be DOMAIN) +# and AWS_S3_CUSTOM_DOMAIN (if used) are added by default. +# Value should be a comma-separated list of host names. +CSP_ADDITIONAL_HOSTS= diff --git a/bookwyrm/forms/status.py b/bookwyrm/forms/status.py index 0800166bf..b562595ee 100644 --- a/bookwyrm/forms/status.py +++ b/bookwyrm/forms/status.py @@ -53,6 +53,7 @@ class QuotationForm(CustomForm): "sensitive", "privacy", "position", + "endposition", "position_mode", ] diff --git a/bookwyrm/migrations/0174_auto_20230130_1240.py b/bookwyrm/migrations/0174_auto_20230130_1240.py new file mode 100644 index 000000000..7337b6b46 --- /dev/null +++ b/bookwyrm/migrations/0174_auto_20230130_1240.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2.16 on 2023-01-30 12:40 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ("bookwyrm", "0173_default_user_auth_group_setting"), + ] + + operations = [ + migrations.AddField( + model_name="quotation", + name="endposition", + field=models.IntegerField( + blank=True, + null=True, + validators=[django.core.validators.MinValueValidator(0)], + ), + ), + migrations.AlterField( + model_name="sitesettings", + name="default_user_auth_group", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="auth.group", + ), + ), + ] diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 9361854ba..ec1c34a40 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -21,7 +21,7 @@ from django.utils.http import http_date from bookwyrm import activitypub from bookwyrm.settings import USER_AGENT, PAGE_LENGTH from bookwyrm.signatures import make_signature, make_digest -from bookwyrm.tasks import app, MEDIUM +from bookwyrm.tasks import app, MEDIUM, BROADCAST from bookwyrm.models.fields import ImageField, ManyToManyField logger = logging.getLogger(__name__) @@ -126,7 +126,7 @@ class ActivitypubMixin: # there OUGHT to be only one match return match.first() - def broadcast(self, activity, sender, software=None, queue=MEDIUM): + def broadcast(self, activity, sender, software=None, queue=BROADCAST): """send out an activity""" broadcast_task.apply_async( args=( @@ -198,7 +198,7 @@ class ActivitypubMixin: class ObjectMixin(ActivitypubMixin): """add this mixin for object models that are AP serializable""" - def save(self, *args, created=None, software=None, priority=MEDIUM, **kwargs): + def save(self, *args, created=None, software=None, priority=BROADCAST, **kwargs): """broadcast created/updated/deleted objects as appropriate""" broadcast = kwargs.get("broadcast", True) # this bonus kwarg would cause an error in the base save method @@ -506,7 +506,7 @@ def unfurl_related_field(related_field, sort_field=None): return related_field.remote_id -@app.task(queue=MEDIUM) +@app.task(queue=BROADCAST) def broadcast_task(sender_id: int, activity: str, recipients: List[str]): """the celery task for broadcast""" user_model = apps.get_model("bookwyrm.User", require_ready=True) diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index e40609f36..35f007be2 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -72,7 +72,7 @@ class SiteSettings(SiteModel): invite_request_question = models.BooleanField(default=False) require_confirm_email = models.BooleanField(default=True) default_user_auth_group = models.ForeignKey( - auth_models.Group, null=True, blank=True, on_delete=models.PROTECT + auth_models.Group, null=True, blank=True, on_delete=models.RESTRICT ) invite_question_text = models.CharField( diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index bd99deee5..e51c7b2a1 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -329,6 +329,9 @@ class Quotation(BookStatus): position = models.IntegerField( validators=[MinValueValidator(0)], null=True, blank=True ) + endposition = models.IntegerField( + validators=[MinValueValidator(0)], null=True, blank=True + ) position_mode = models.CharField( max_length=3, choices=ProgressMode.choices, diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 51f3fe8a7..bf0467ebc 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -11,7 +11,7 @@ from django.utils.translation import gettext_lazy as _ env = Env() env.read_env() DOMAIN = env("DOMAIN") -VERSION = "0.5.4" +VERSION = "0.5.5" RELEASE_API = env( "RELEASE_API", @@ -101,6 +101,7 @@ MIDDLEWARE = [ "django.middleware.locale.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", + "csp.middleware.CSPMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "bookwyrm.middleware.TimezoneMiddleware", "bookwyrm.middleware.IPBlocklistMiddleware", @@ -329,12 +330,15 @@ IMAGEKIT_DEFAULT_CACHEFILE_STRATEGY = "bookwyrm.thumbnail_generation.Strategy" # https://docs.djangoproject.com/en/3.2/howto/static-files/ PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) +CSP_ADDITIONAL_HOSTS = env.list("CSP_ADDITIONAL_HOSTS", []) # Storage PROTOCOL = "http" if USE_HTTPS: PROTOCOL = "https" + SESSION_COOKIE_SECURE = True + CSRF_COOKIE_SECURE = True USE_S3 = env.bool("USE_S3", False) @@ -358,11 +362,17 @@ if USE_S3: MEDIA_FULL_URL = MEDIA_URL STATIC_FULL_URL = STATIC_URL DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage" + CSP_DEFAULT_SRC = ["'self'", AWS_S3_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS + CSP_SCRIPT_SRC = ["'self'", AWS_S3_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS else: STATIC_URL = "/static/" MEDIA_URL = "/images/" MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}" STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}" + CSP_DEFAULT_SRC = ["'self'"] + CSP_ADDITIONAL_HOSTS + CSP_SCRIPT_SRC = ["'self'"] + CSP_ADDITIONAL_HOSTS + +CSP_INCLUDE_NONCE_IN = ["script-src"] OTEL_EXPORTER_OTLP_ENDPOINT = env("OTEL_EXPORTER_OTLP_ENDPOINT", None) OTEL_EXPORTER_OTLP_HEADERS = env("OTEL_EXPORTER_OTLP_HEADERS", None) diff --git a/bookwyrm/signatures.py b/bookwyrm/signatures.py index 772d39cce..3102f8da2 100644 --- a/bookwyrm/signatures.py +++ b/bookwyrm/signatures.py @@ -15,7 +15,7 @@ MAX_SIGNATURE_AGE = 300 def create_key_pair(): """a new public/private key pair, used for creating new users""" random_generator = Random.new().read - key = RSA.generate(1024, random_generator) + key = RSA.generate(2048, random_generator) private_key = key.export_key().decode("utf8") public_key = key.public_key().export_key().decode("utf8") diff --git a/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss b/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss index cdcd74202..9ab44f89d 100644 --- a/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss +++ b/bookwyrm/static/css/bookwyrm/overrides/_bulma_overrides.scss @@ -40,7 +40,7 @@ } .navbar-item { - // see ../components/_details.scss :: Navbar details + /* see ../components/_details.scss :: Navbar details */ padding-right: 1.75rem; font-size: 1rem; } @@ -109,3 +109,9 @@ max-height: 35em; overflow: hidden; } + +.dropdown-menu .button { + @include mobile { + font-size: $size-6; + } +} diff --git a/bookwyrm/tasks.py b/bookwyrm/tasks.py index ec018e179..91977afda 100644 --- a/bookwyrm/tasks.py +++ b/bookwyrm/tasks.py @@ -16,3 +16,5 @@ MEDIUM = "medium_priority" HIGH = "high_priority" # import items get their own queue because they're such a pain in the ass IMPORTS = "imports" +# I keep making more queues?? this one broadcasting out +BROADCAST = "broadcast" diff --git a/bookwyrm/templates/discover/large-book.html b/bookwyrm/templates/discover/large-book.html index f016a2f65..939544987 100644 --- a/bookwyrm/templates/discover/large-book.html +++ b/bookwyrm/templates/discover/large-book.html @@ -46,7 +46,7 @@
- {% include "snippets/status/content_status.html" with hide_book=True trim_length=70 hide_more=True %} + {% include "snippets/status/content_status.html" with hide_book=True trim_length=70 hide_more=True expand=False %}
{% trans "View status" %} diff --git a/bookwyrm/templates/feed/status.html b/bookwyrm/templates/feed/status.html index ccec6503c..c05d2ba46 100644 --- a/bookwyrm/templates/feed/status.html +++ b/bookwyrm/templates/feed/status.html @@ -30,7 +30,7 @@ {% endif %} {% endfor %}
- {% include 'snippets/status/status.html' with status=status main=True %} + {% include 'snippets/status/status.html' with status=status main=True expand=True %}
{% for child in children %} diff --git a/bookwyrm/templates/guided_tour/book.html b/bookwyrm/templates/guided_tour/book.html index 44a37f65e..a0d60e831 100644 --- a/bookwyrm/templates/guided_tour/book.html +++ b/bookwyrm/templates/guided_tour/book.html @@ -1,6 +1,6 @@ {% load i18n %} - diff --git a/bookwyrm/templates/ostatus/template.html b/bookwyrm/templates/ostatus/template.html index eb904a693..25d2430c0 100644 --- a/bookwyrm/templates/ostatus/template.html +++ b/bookwyrm/templates/ostatus/template.html @@ -11,7 +11,7 @@ {% block title %}{% endblock %} - diff --git a/bookwyrm/templates/settings/celery.html b/bookwyrm/templates/settings/celery.html index 6a3ee6574..65315da01 100644 --- a/bookwyrm/templates/settings/celery.html +++ b/bookwyrm/templates/settings/celery.html @@ -20,31 +20,37 @@ {% if queues %}

{% trans "Queues" %}

-
-
+
+

{% trans "Low priority" %}

{{ queues.low_priority|intcomma }}

-
+

{% trans "Medium priority" %}

{{ queues.medium_priority|intcomma }}

-
+

{% trans "High priority" %}

{{ queues.high_priority|intcomma }}

-
+

{% trans "Imports" %}

{{ queues.imports|intcomma }}

+
+
+

{% trans "Broadcasts" %}

+

{{ queues.broadcast|intcomma }}

+
+
{% else %} diff --git a/bookwyrm/templates/settings/dashboard/registration_chart.html b/bookwyrm/templates/settings/dashboard/registration_chart.html index 3b258fec8..bb51ed8bc 100644 --- a/bookwyrm/templates/settings/dashboard/registration_chart.html +++ b/bookwyrm/templates/settings/dashboard/registration_chart.html @@ -1,5 +1,5 @@ {% load i18n %} -