mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-29 13:01:08 +00:00
Adds automod view
This commit is contained in:
parent
c8b4d5ecf1
commit
12f67dc0ce
9 changed files with 168 additions and 11 deletions
|
@ -550,3 +550,9 @@ class ReadThroughForm(CustomForm):
|
|||
class Meta:
|
||||
model = models.ReadThrough
|
||||
fields = ["user", "book", "start_date", "finish_date"]
|
||||
|
||||
|
||||
class AutoModRuleForm(CustomForm):
|
||||
class Meta:
|
||||
model = models.AutoMod
|
||||
fields = ["string_match", "flag_users", "flag_statuses", "created_by"]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 3.2.12 on 2022-02-18 04:53
|
||||
# Generated by Django 3.2.12 on 2022-02-24 18:59
|
||||
|
||||
from django.conf import settings
|
||||
import django.contrib.postgres.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
@ -14,12 +13,12 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AutoFlag',
|
||||
name='AutoMod',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('flag_users', models.BooleanField(default=False)),
|
||||
('flag_statuses', models.BooleanField(default=False)),
|
||||
('string_match', models.CharField(max_length=200)),
|
||||
('string_match', models.CharField(max_length=200, unique=True)),
|
||||
('flag_users', models.BooleanField(default=True)),
|
||||
('flag_statuses', models.BooleanField(default=True)),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
|
@ -29,7 +29,7 @@ from .import_job import ImportJob, ImportItem
|
|||
from .site import SiteSettings, SiteInvite
|
||||
from .site import PasswordReset, InviteRequest
|
||||
from .announcement import Announcement
|
||||
from .antispam import EmailBlocklist, IPBlocklist
|
||||
from .antispam import EmailBlocklist, IPBlocklist, AutoMod
|
||||
|
||||
from .notification import Notification
|
||||
|
||||
|
|
|
@ -35,9 +35,9 @@ class IPBlocklist(models.Model):
|
|||
ordering = ("-created_date",)
|
||||
|
||||
|
||||
class AutoFlag(models.Model):
|
||||
class AutoMod(models.Model):
|
||||
"""rules to automatically flag suspicious activity"""
|
||||
string_match = models.CharField(max_length=200, unique=True)
|
||||
flag_users = models.BooleanField(default=True)
|
||||
flag_statuses = models.BooleanField(default=True)
|
||||
created_by = models.ForeignKey("User", on_delete=models.PROTECT)
|
||||
flag_users = models.BooleanField(default=False)
|
||||
flag_statuses = models.BooleanField(default=False)
|
||||
string_match = models.CharField(max_length=200)
|
||||
|
|
91
bookwyrm/templates/settings/automod/rules.html
Normal file
91
bookwyrm/templates/settings/automod/rules.html
Normal file
|
@ -0,0 +1,91 @@
|
|||
{% extends 'settings/layout.html' %}
|
||||
{% load i18n %}
|
||||
{% load utilities %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Auto-moderation rules" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% trans "Auto-moderation rules" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block panel %}
|
||||
|
||||
<div class="notification content">
|
||||
<p>
|
||||
{% trans "Auto-moderation rules will create reports for any user or status with fields matching the provided string." %}
|
||||
{% trans "At this time, reports are <em>not</em> being generated automatically, and you must manually trigger a scan." %}
|
||||
</p>
|
||||
<button class="button is-warning">{% trans "Run scan" %}</button>
|
||||
</div>
|
||||
|
||||
{% if success %}
|
||||
<div class="notification is-success is-light">
|
||||
<span class="icon icon-check" aria-hidden="true"></span>
|
||||
<span>
|
||||
{% trans "Successfully added rule" %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="block table-container">
|
||||
<table class="table is-striped">
|
||||
<form action="{% url 'settings-automod' %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" value="{{ request.user.id }}" name="created_by">
|
||||
<tr>
|
||||
<th>
|
||||
<label for="id_string_match">{% trans "String match" %}</label>
|
||||
</th>
|
||||
<th>
|
||||
<label for="id_flag_users">{% trans "Flag users" %}</label>
|
||||
</th>
|
||||
<th>
|
||||
<label for+"id_flag_statuses">{% trans "Flag statuses" %}</label>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{ form.string_match }}
|
||||
{% include 'snippets/form_errors.html' with errors_list=form.string_match.errors id="desc_string_match" %}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.flag_users }}
|
||||
</td>
|
||||
<td>
|
||||
{{ form.flag_statuses }}
|
||||
</td>
|
||||
<td>
|
||||
<button type="submit" class="button is-primary">{% trans "Add rule" %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
{% for rule in rules %}
|
||||
<tr>
|
||||
<td>
|
||||
<code>{{ rule.string_match }}</code>
|
||||
</td>
|
||||
<td>
|
||||
{{ rule.flag_users|yesno }}
|
||||
</td>
|
||||
<td>
|
||||
{{ rule.flag_statuses|yesno }}
|
||||
</td>
|
||||
<td>
|
||||
<form action="{% url 'settings-automod-delete' rule.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="button is-danger is-light">
|
||||
<span class="icon icon-x m-0-mobile" aria-hidden="true"></span>
|
||||
<span class="is-sr-only-mobile">{% trans "Remove rule" %}</span>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -56,6 +56,10 @@
|
|||
{% url 'settings-reports' as url %}
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Reports" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
{% url 'settings-automod' as url %}
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Auto-moderation rules" %}</a>
|
||||
</li>
|
||||
<li>
|
||||
{% url 'settings-email-blocks' as url %}
|
||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Email Blocklist" %}</a>
|
||||
|
|
|
@ -214,6 +214,9 @@ urlpatterns = [
|
|||
views.IPBlocklist.as_view(),
|
||||
name="settings-ip-blocks-delete",
|
||||
),
|
||||
# auto-moderation rules
|
||||
re_path(r"^settings/automod/?$", views.AutoMod.as_view(), name="settings-automod"),
|
||||
re_path(r"^settings/automod/(?P<rule_id>\d+)/delete?$", views.automod_delete, name="settings-automod-delete"),
|
||||
# moderation
|
||||
re_path(
|
||||
r"^settings/reports/?$", views.ReportsAdmin.as_view(), name="settings-reports"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# site admin
|
||||
from .admin.announcements import Announcements, Announcement
|
||||
from .admin.announcements import EditAnnouncement, delete_announcement
|
||||
from .admin.automod import AutoMod, automod_delete
|
||||
from .admin.dashboard import Dashboard
|
||||
from .admin.federation import Federation, FederatedServer
|
||||
from .admin.federation import AddFederatedServer, ImportServerBlocklist
|
||||
|
|
53
bookwyrm/views/admin/automod.py
Normal file
53
bookwyrm/views/admin/automod.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
""" moderation via flagged posts and users """
|
||||
from django.contrib.auth.decorators import login_required, permission_required
|
||||
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 forms, models
|
||||
|
||||
|
||||
@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",
|
||||
)
|
||||
# pylint: disable=no-self-use
|
||||
class AutoMod(View):
|
||||
"""Manage automated flagging"""
|
||||
|
||||
def get(self, request):
|
||||
"""view rules"""
|
||||
data = {"rules": models.AutoMod.objects.all(), "form": forms.AutoModRuleForm()}
|
||||
return TemplateResponse(request, "settings/automod/rules.html", data)
|
||||
|
||||
def post(self, request):
|
||||
"""add rule"""
|
||||
form = forms.AutoModRuleForm(request.POST)
|
||||
success = form.is_valid()
|
||||
if success:
|
||||
form.save()
|
||||
form = forms.AutoModRuleForm()
|
||||
|
||||
data = {
|
||||
"rules": models.AutoMod.objects.all(),
|
||||
"form": form,
|
||||
"success": success,
|
||||
}
|
||||
return TemplateResponse(request, "settings/automod/rules.html", data)
|
||||
|
||||
@require_POST
|
||||
@permission_required("bookwyrm.moderate_user", raise_exception=True)
|
||||
@permission_required("bookwyrm.moderate_post", raise_exception=True)
|
||||
# pylint: disable=unused-argument
|
||||
def automod_delete(request, rule_id):
|
||||
""" Remove a rule """
|
||||
rule = get_object_or_404(models.AutoMod, id=rule_id)
|
||||
rule.delete()
|
||||
return redirect("settings-automod")
|
Loading…
Reference in a new issue