mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-05 10:29:28 +02:00
MRF / Dropping of incoming/outgoing messages based on allow-list
This commit is contained in:
parent
371dc01205
commit
08262529ec
24 changed files with 897 additions and 89 deletions
117
api/funkwhale_api/moderation/management/commands/mrf_check.py
Normal file
117
api/funkwhale_api/moderation/management/commands/mrf_check.py
Normal file
|
@ -0,0 +1,117 @@
|
|||
import json
|
||||
import sys
|
||||
import uuid
|
||||
import logging
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core import validators
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from funkwhale_api.common import session
|
||||
from funkwhale_api.federation import models
|
||||
from funkwhale_api.moderation import mrf
|
||||
|
||||
|
||||
def is_uuid(v):
|
||||
try:
|
||||
uuid.UUID(v)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_url(v):
|
||||
validator = validators.URLValidator()
|
||||
try:
|
||||
validator(v)
|
||||
except (ValueError, validators.ValidationError):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Check a given message against all or a specific MRF rule"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"type",
|
||||
type=str,
|
||||
choices=["inbox"],
|
||||
help=("The type of MRF. Only inbox is supported at the moment"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"input",
|
||||
nargs="?",
|
||||
help=(
|
||||
"The path to a file containing JSON data. Use - to read from stdin. "
|
||||
"If no input is provided, registered MRF policies will be listed "
|
||||
"instead.",
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--policy",
|
||||
"-p",
|
||||
dest="policies",
|
||||
nargs="+",
|
||||
default=False,
|
||||
help="Restrict to a list of MRF policies that will be applied, in that order",
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
logger = logging.getLogger("funkwhale.mrf")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(logging.StreamHandler(stream=sys.stderr))
|
||||
|
||||
input = options["input"]
|
||||
if not input:
|
||||
registry = getattr(mrf, options["type"])
|
||||
self.stdout.write(
|
||||
"No input given, listing registered policies for '{}' MRF:".format(
|
||||
options["type"]
|
||||
)
|
||||
)
|
||||
for name in registry.keys():
|
||||
self.stdout.write("- {}".format(name))
|
||||
return
|
||||
raw_content = None
|
||||
content = None
|
||||
if input == "-":
|
||||
raw_content = sys.stdin.read()
|
||||
elif is_uuid(input):
|
||||
self.stderr.write("UUID provided, retrieving payload from db")
|
||||
content = models.Activity.objects.get(uuid=input).payload
|
||||
elif is_url(input):
|
||||
response = session.get_session().get(
|
||||
input,
|
||||
timeout=5,
|
||||
verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL,
|
||||
headers={"Content-Type": "application/activity+json"},
|
||||
)
|
||||
response.raise_for_status()
|
||||
content = response.json()
|
||||
else:
|
||||
with open(input, "rb") as f:
|
||||
raw_content = f.read()
|
||||
content = json.loads(raw_content) if content is None else content
|
||||
|
||||
policies = options["policies"] or []
|
||||
registry = getattr(mrf, options["type"])
|
||||
for policy in policies:
|
||||
if policy not in registry:
|
||||
raise CommandError(
|
||||
"Unknown policy '{}' for MRF '{}'".format(policy, options["type"])
|
||||
)
|
||||
|
||||
payload, updated = registry.apply(content, policies=policies)
|
||||
if not payload:
|
||||
self.stderr.write("Payload was discarded by MRF")
|
||||
elif updated:
|
||||
self.stderr.write("Payload was modified by MRF")
|
||||
self.stderr.write("Initial payload:\n")
|
||||
self.stdout.write(json.dumps(content, indent=2, sort_keys=True))
|
||||
self.stderr.write("Modified payload:\n")
|
||||
self.stdout.write(json.dumps(payload, indent=2, sort_keys=True))
|
||||
else:
|
||||
self.stderr.write("Payload left untouched by MRF")
|
Loading…
Add table
Add a link
Reference in a new issue