kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
114 wiersze
3.6 KiB
Python
114 wiersze
3.6 KiB
Python
import json
|
|
import logging
|
|
import sys
|
|
import uuid
|
|
|
|
from django.core import validators
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
|
|
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(f"- {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,
|
|
headers={"Accept": "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")
|