Skip to content

Commit

Permalink
Merge pull request #2854 from bookwyrm-social/report-actions
Browse files Browse the repository at this point in the history
Record report actions
  • Loading branch information
mouse-reeve authored Aug 6, 2023
2 parents 861d3b1 + 518f87e commit 15e82ec
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 70 deletions.
36 changes: 36 additions & 0 deletions bookwyrm/migrations/0179_reportcomment_comment_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 3.2.18 on 2023-05-16 16:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0178_auto_20230328_2132"),
]

operations = [
migrations.AddField(
model_name="reportcomment",
name="action_type",
field=models.CharField(
choices=[
("comment", "Comment"),
("resolve", "Resolved report"),
("reopen", "Re-opened report"),
("message_reporter", "Messaged reporter"),
("message_offender", "Messaged reported user"),
("user_suspension", "Suspended user"),
("user_unsuspension", "Un-suspended user"),
("user_perms", "Changed user permission level"),
("user_deletion", "Deleted user account"),
("block_domain", "Blocked domain"),
("approve_domain", "Approved domain"),
("delete_item", "Deleted item"),
],
default="comment",
max_length=20,
),
),
migrations.RenameModel("ReportComment", "ReportAction"),
]
17 changes: 17 additions & 0 deletions bookwyrm/migrations/0180_alter_reportaction_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.18 on 2023-06-21 22:01

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0179_reportcomment_comment_type"),
]

operations = [
migrations.AlterModelOptions(
name="reportaction",
options={"ordering": ("created_date",)},
),
]
13 changes: 13 additions & 0 deletions bookwyrm/migrations/0181_merge_20230806_2302.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 3.2.20 on 2023-08-06 23:02

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("bookwyrm", "0180_alter_reportaction_options"),
("bookwyrm", "0180_alter_user_preferred_language"),
]

operations = []
2 changes: 1 addition & 1 deletion bookwyrm/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .user import User, KeyPair
from .annual_goal import AnnualGoal
from .relationship import UserFollows, UserFollowRequest, UserBlocks
from .report import Report, ReportComment
from .report import Report, ReportAction
from .federated_server import FederatedServer

from .group import Group, GroupMember, GroupMemberInvitation
Expand Down
65 changes: 63 additions & 2 deletions bookwyrm/models/report.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
""" flagged for moderation """
from django.core.exceptions import PermissionDenied
from django.db import models
from django.utils.translation import gettext_lazy as _

from bookwyrm.settings import DOMAIN
from .base_model import BookWyrmModel


# Report action enums
COMMENT = "comment"
RESOLVE = "resolve"
REOPEN = "reopen"
MESSAGE_REPORTER = "message_reporter"
MESSAGE_OFFENDER = "message_offender"
USER_SUSPENSION = "user_suspension"
USER_UNSUSPENSION = "user_unsuspension"
USER_DELETION = "user_deletion"
USER_PERMS = "user_perms"
BLOCK_DOMAIN = "block_domain"
APPROVE_DOMAIN = "approve_domain"
DELETE_ITEM = "delete_item"


class Report(BookWyrmModel):
"""reported status or user"""

Expand All @@ -32,20 +48,65 @@ def raise_not_editable(self, viewer):
def get_remote_id(self):
return f"https://{DOMAIN}/settings/reports/{self.id}"

def comment(self, user, note):
"""comment on a report"""
ReportAction.objects.create(
action_type=COMMENT, user=user, note=note, report=self
)

def resolve(self, user):
"""Mark a report as complete"""
self.resolved = True
self.save()
ReportAction.objects.create(action_type=RESOLVE, user=user, report=self)

def reopen(self, user):
"""Wait! This report isn't complete after all"""
self.resolved = False
self.save()
ReportAction.objects.create(action_type=REOPEN, user=user, report=self)

@classmethod
def record_action(cls, report_id: int, action: str, user):
"""Note that someone did something"""
if not report_id:
return
report = cls.objects.get(id=report_id)
ReportAction.objects.create(action_type=action, user=user, report=report)

class Meta:
"""set order by default"""

ordering = ("-created_date",)


class ReportComment(BookWyrmModel):
ReportActionTypes = [
(COMMENT, _("Comment")),
(RESOLVE, _("Resolved report")),
(REOPEN, _("Re-opened report")),
(MESSAGE_REPORTER, _("Messaged reporter")),
(MESSAGE_OFFENDER, _("Messaged reported user")),
(USER_SUSPENSION, _("Suspended user")),
(USER_UNSUSPENSION, _("Un-suspended user")),
(USER_PERMS, _("Changed user permission level")),
(USER_DELETION, _("Deleted user account")),
(BLOCK_DOMAIN, _("Blocked domain")),
(APPROVE_DOMAIN, _("Approved domain")),
(DELETE_ITEM, _("Deleted item")),
]


class ReportAction(BookWyrmModel):
"""updates on a report"""

user = models.ForeignKey("User", on_delete=models.PROTECT)
action_type = models.CharField(
max_length=20, blank=False, default="comment", choices=ReportActionTypes
)
note = models.TextField()
report = models.ForeignKey(Report, on_delete=models.PROTECT)

class Meta:
"""sort comments"""

ordering = ("-created_date",)
ordering = ("created_date",)
76 changes: 53 additions & 23 deletions bookwyrm/templates/settings/reports/report.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% extends 'settings/layout.html' %}
{% load i18n %}
{% load humanize %}
{% load utilities %}
{% load feed_page_tags %}

{% block title %}
Expand All @@ -21,7 +22,7 @@
<div class="block">
<details class="details-panel box">
<summary>
<span class="title is-4">{% trans "Message reporter" %}</span>
<span class="title is-6">{% trans "Message reporter" %}</span>
<span class="details-close icon icon-x" aria-hidden="true"></span>
</summary>
<div class="box">
Expand Down Expand Up @@ -61,30 +62,59 @@ <h3 class="title is-4">{% trans "Reported links" %}</h3>
{% include 'settings/users/user_moderation_actions.html' with user=report.user %}
{% endif %}

<div class="block">
<h3 class="title is-4">{% trans "Moderator Comments" %}</h3>
{% for comment in report.reportcomment_set.all %}
<div class="card block">
<p class="card-content">{{ comment.note }}</p>
<div class="card-footer">
<div class="card-footer-item">
<a href="{{ comment.user.local_path }}">{{ comment.user.display_name }}</a>
<div class="block content">
<h3 class="title is-4">{% trans "Moderation Activity" %}</h3>

<div class="box">
<ul class="mt-0">
<li class="mb-2">
<div class="is-flex">
<p class="mb-0 is-flex-grow-1">
{% blocktrans trimmed with user=report.reporter|username user_link=report.reporter.local_path %}
<a href="{{ user_link }}">{{ user}}</a> opened this report
{% endblocktrans %}
</p>
<span class="tag">{{ report.created_date }}</span>
</div>
</li>

{% for comment in report.reportaction_set.all %}
<li class="mb-2">
<div class="is-flex">
<p class="mb-0 is-flex-grow-1">
{% if comment.action_type == "comment" %}
{% blocktrans trimmed with user=comment.user|username user_link=comment.user.local_path %}
<a href="{{ user_link }}">{{ user}}</a> commented on this report:
{% endblocktrans %}
{% else %}
{% blocktrans trimmed with user=comment.user|username user_link=comment.user.local_path %}
<a href="{{ user_link }}">{{ user}}</a> took an action on this report:
{% endblocktrans %}
<span class="has-text-weight-bold">
{{ comment.get_action_type_display }}
</span>
{% endif %}
</p>
<span class="tag">{{ comment.created_date }}</span>
</div>

{% if comment.note %}
<blockquote>{{ comment.note }}</blockquote>
{% endif %}
</li>
{% endfor %}
</ul>

<form class="block" name="report-comment" method="post" action="{% url 'settings-report' report.id %}">
{% csrf_token %}
<div class="field">
<label for="report_comment" class="label">Comment on report</label>
<textarea name="note" id="report_comment" class="textarea"></textarea>
</div>
<div class="card-footer-item">
{{ comment.created_date|naturaltime }}
<div class="field">
<button class="button">{% trans "Comment" %}</button>
</div>
</div>
</form>
</div>
{% endfor %}
<form class="block" name="report-comment" method="post" action="{% url 'settings-report' report.id %}">
{% csrf_token %}
<div class="field">
<label for="report_comment" class="label">Comment on report</label>
<textarea name="note" id="report_comment" class="textarea"></textarea>
</div>
<div class="field">
<button class="button">{% trans "Comment" %}</button>
</div>
</form>
</div>
{% endblock %}
12 changes: 11 additions & 1 deletion bookwyrm/templates/settings/reports/report_links_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@
</a>
</td>
<td>
<form>
{% if link.domain.status != "approved" %}
<form method="POST" action="{% url 'settings-link-domain-status' link.domain.id 'approved' report.id %}">
{% csrf_token %}
<button type="submit" class="button is-success is-light">{% trans "Approve domain" %}</button>
</form>
{% endif %}

{% if link.domain.status != "blocked" %}
<form method="POST" action="{% url 'settings-link-domain-status' link.domain.id 'blocked' report.id %}">
{% csrf_token %}
<button type="submit" class="button is-danger is-light">{% trans "Block domain" %}</button>
</form>
{% endif %}
</td>
{% endblock %}
2 changes: 1 addition & 1 deletion bookwyrm/templates/settings/users/delete_user_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{% endblock %}

{% block form %}
<form name="delete-user" action="{% url 'settings-delete-user' user.id %}" method="post">
<form name="delete-user" action="{% url 'settings-delete-user' user.id report.id %}" method="post">
{% csrf_token %}
<p>
{% blocktrans trimmed with username=user.localname %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ <h3>{% trans "User Actions" %}</h3>
</form>
{% endif %}
{% if user.is_active or user.deactivation_reason == "pending" %}
<form name="suspend" method="post" action="{% url 'settings-report-suspend' user.id %}" class="mr-1">
<form name="suspend" method="post" action="{% url 'settings-report-suspend' user.id report.id %}" class="mr-1">
{% csrf_token %}
<button type="submit" class="button is-danger is-light">{% trans "Suspend user" %}</button>
</form>
{% else %}
<form name="unsuspend" method="post" action="{% url 'settings-report-unsuspend' user.id %}" class="mr-1">
<form name="unsuspend" method="post" action="{% url 'settings-report-unsuspend' user.id report.id %}" class="mr-1">
{% csrf_token %}
<button class="button">{% trans "Un-suspend user" %}</button>
</form>
Expand All @@ -49,7 +49,7 @@ <h3>{% trans "User Actions" %}</h3>

{% if user.local %}
<div>
<form name="permission" method="post" action="{% url 'settings-user' user.id %}">
<form name="permission" method="post" action="{% url 'settings-user' user.id report.id %}">
{% csrf_token %}
<label class="label" for="id_user_group">{% trans "Access level:" %}</label>
{% if group_form.non_field_errors %}
Expand Down
2 changes: 1 addition & 1 deletion bookwyrm/templates/snippets/status/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

<div class="card-footer-item">
{# moderation options #}
<form name="delete-{{ status.id }}" action="/delete-status/{{ status.id }}" method="post">
<form name="delete-{{ status.id }}" action="/delete-status/{{ status.id }}/{{ report.id }}" method="post">
{% csrf_token %}
<button class="button is-danger is-light" type="submit">
{% trans "Delete status" %}
Expand Down
28 changes: 22 additions & 6 deletions bookwyrm/tests/views/admin/test_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,26 @@ def test_report_page(self):
validate_html(result.render())
self.assertEqual(result.status_code, 200)

def test_report_comment(self):
"""comment on a report"""
def test_report_action(self):
"""action on a report"""
view = views.ReportAdmin.as_view()
request = self.factory.post("", {"note": "hi"})
request.user = self.local_user
report = models.Report.objects.create(reporter=self.local_user, user=self.rat)

view(request, report.id)

comment = models.ReportComment.objects.get()
self.assertEqual(comment.user, self.local_user)
self.assertEqual(comment.note, "hi")
self.assertEqual(comment.report, report)
action = models.ReportAction.objects.get()
self.assertEqual(action.user, self.local_user)
self.assertEqual(action.note, "hi")
self.assertEqual(action.report, report)
self.assertEqual(action.action_type, "comment")

def test_resolve_report(self):
"""toggle report resolution status"""
report = models.Report.objects.create(reporter=self.local_user, user=self.rat)
self.assertFalse(report.resolved)
self.assertFalse(models.ReportAction.objects.exists())
request = self.factory.post("")
request.user = self.local_user

Expand All @@ -104,11 +106,25 @@ def test_resolve_report(self):
report.refresh_from_db()
self.assertTrue(report.resolved)

# check that the action was noted
self.assertTrue(
models.ReportAction.objects.filter(
report=report, action_type="resolve", user=self.local_user
).exists()
)

# un-resolve
views.resolve_report(request, report.id)
report.refresh_from_db()
self.assertFalse(report.resolved)

# check that the action was noted
self.assertTrue(
models.ReportAction.objects.filter(
report=report, action_type="reopen", user=self.local_user
).exists()
)

@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay")
@patch("bookwyrm.activitystreams.populate_stream_task.delay")
@patch("bookwyrm.suggested_users.remove_user_task.delay")
Expand Down
Loading

0 comments on commit 15e82ec

Please sign in to comment.