diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 380e701f..654130cf 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -231,3 +231,9 @@ class ListForm(CustomForm): class Meta: model = models.List fields = ["user", "name", "description", "curation", "privacy"] + + +class ReportForm(CustomForm): + class Meta: + model = models.Report + fields = ["user", "reporter", "statuses", "note"] diff --git a/bookwyrm/migrations/0049_report_reportcomment.py b/bookwyrm/migrations/0049_auto_20210309_0156.py similarity index 83% rename from bookwyrm/migrations/0049_report_reportcomment.py rename to bookwyrm/migrations/0049_auto_20210309_0156.py index deb8ba6f..494f5bc8 100644 --- a/bookwyrm/migrations/0049_report_reportcomment.py +++ b/bookwyrm/migrations/0049_auto_20210309_0156.py @@ -1,9 +1,10 @@ -# Generated by Django 3.0.7 on 2021-03-09 00:55 +# Generated by Django 3.0.7 on 2021-03-09 01:56 import bookwyrm.models.fields from django.conf import settings from django.db import migrations, models import django.db.models.deletion +import django.db.models.expressions class Migration(migrations.Migration): @@ -23,12 +24,9 @@ class Migration(migrations.Migration): ('note', models.TextField(blank=True, null=True)), ('resolved', models.BooleanField(default=False)), ('reporter', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='reporter', to=settings.AUTH_USER_MODEL)), - ('statuses', models.ManyToManyField(to='bookwyrm.Status')), + ('statuses', models.ManyToManyField(blank=True, null=True, to='bookwyrm.Status')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ], - options={ - 'abstract': False, - }, ), migrations.CreateModel( name='ReportComment', @@ -45,4 +43,8 @@ class Migration(migrations.Migration): 'abstract': False, }, ), + migrations.AddConstraint( + model_name='report', + constraint=models.CheckConstraint(check=models.Q(_negated=True, reporter=django.db.models.expressions.F('user')), name='self_report'), + ), ] diff --git a/bookwyrm/models/report.py b/bookwyrm/models/report.py index afbc356b..e1e8c2a4 100644 --- a/bookwyrm/models/report.py +++ b/bookwyrm/models/report.py @@ -1,5 +1,6 @@ """ flagged for moderation """ from django.db import models +from django.db.models import F, Q from .base_model import BookWyrmModel @@ -11,9 +12,17 @@ class Report(BookWyrmModel): ) note = models.TextField(null=True, blank=True) user = models.ForeignKey("User", on_delete=models.PROTECT) - statuses = models.ManyToManyField("Status") + statuses = models.ManyToManyField("Status", null=True, blank=True) resolved = models.BooleanField(default=False) + class Meta: + """ don't let users report themselves """ + constraints = [ + models.CheckConstraint( + check=~Q(reporter=F('user')), + name='self_report' + ) + ] class ReportComment(BookWyrmModel): """ updates on a report """ diff --git a/bookwyrm/templates/settings/report.html b/bookwyrm/templates/settings/report.html new file mode 100644 index 00000000..1f55906b --- /dev/null +++ b/bookwyrm/templates/settings/report.html @@ -0,0 +1,2 @@ +{% extends 'settings/admin_layout.html' %} +{% load i18n %} diff --git a/bookwyrm/templates/settings/report_preview.html b/bookwyrm/templates/settings/report_preview.html index 67bffe27..b72dd958 100644 --- a/bookwyrm/templates/settings/report_preview.html +++ b/bookwyrm/templates/settings/report_preview.html @@ -2,7 +2,7 @@ {% load i18n %} {% block card-header %}
[A-Za-z0-9]+)/?$", views.Invite.as_view()),
# moderation
re_path(r"^settings/reports/?$", views.Reports.as_view(), name="settings-reports"),
re_path(
- r"^settings/report/(?P\d+)/?$",
+ r"^settings/reports/(?P\d+)/?$",
views.Report.as_view(),
name="settings-report",
),
- re_path(r"^invite/(?P[A-Za-z0-9]+)/?$", views.Invite.as_view()),
+ re_path(r"^report/?$", views.make_report, name="report"),
# landing pages
re_path(r"^about/?$", views.About.as_view()),
path("", views.Home.as_view()),
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index 36a64ddf..b433dca2 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -20,7 +20,7 @@ from .notifications import Notifications
from .outbox import Outbox
from .reading import edit_readthrough, create_readthrough, delete_readthrough
from .reading import start_reading, finish_reading, delete_progressupdate
-from .reports import Report, Reports
+from .reports import Report, Reports, make_report
from .rss_feed import RssFeed
from .password import PasswordResetRequest, PasswordReset, ChangePassword
from .search import Search
diff --git a/bookwyrm/views/reports.py b/bookwyrm/views/reports.py
index 2e374d5e..9eaf9bdc 100644
--- a/bookwyrm/views/reports.py
+++ b/bookwyrm/views/reports.py
@@ -1,11 +1,12 @@
""" moderation via flagged posts and users """
from django.contrib.auth.decorators import login_required, permission_required
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.views import View
+from django.views.decorators.http import require_POST
-from bookwyrm import models
+from bookwyrm import forms, models
# pylint: disable=no-self-use
@@ -23,7 +24,7 @@ class Reports(View):
def get(self, request):
""" view current reports """
- resolved = request.GET.get("resolved")
+ resolved = request.GET.get("resolved", False)
data = {
"resolved": resolved,
"reports": models.Report.objects.filter(resolved=resolved),
@@ -31,6 +32,15 @@ class Reports(View):
return TemplateResponse(request, "settings/reports.html", data)
+@method_decorator(login_required, name="dispatch")
+@method_decorator(
+ permission_required("bookwyrm.moderate_user", raise_exception=True),
+ name="dispatch",
+)
+@method_decorator(
+ permission_required("bookwyrm.moderate_post", raise_exception=True),
+ name="dispatch",
+)
class Report(View):
""" view a specific report """
@@ -38,3 +48,16 @@ class Report(View):
""" load a report """
data = {"report": get_object_or_404(models.Report, id=report_id)}
return TemplateResponse(request, "settings/report.html", data)
+
+
+@login_required
+@require_POST
+def make_report(request):
+ """ a user reports something """
+ form = forms.ReportForm(request.POST)
+ if not form.is_valid():
+ print(form.errors)
+ return redirect(request.headers.get("Referer", "/"))
+
+ form.save()
+ return redirect(request.headers.get("Referer", "/"))