Updates inbox view
This commit is contained in:
@ -3,8 +3,9 @@ import json
|
||||
import re
|
||||
from urllib.parse import urldefrag
|
||||
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
from django.http import HttpResponseBadRequest, HttpResponseForbidden
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.core.exceptions import BadRequest, PermissionDenied
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
@ -21,36 +22,30 @@ from bookwyrm.utils import regex
|
||||
class Inbox(View):
|
||||
"""requests sent by outside servers"""
|
||||
|
||||
# pylint: disable=too-many-return-statements
|
||||
def post(self, request, username=None):
|
||||
"""only works as POST request"""
|
||||
# first check if this server is on our shitlist
|
||||
if is_blocked_user_agent(request):
|
||||
return HttpResponseForbidden()
|
||||
raise_is_blocked_user_agent(request)
|
||||
|
||||
# make sure the user's inbox even exists
|
||||
if username:
|
||||
try:
|
||||
models.User.objects.get(localname=username)
|
||||
except models.User.DoesNotExist:
|
||||
return HttpResponseNotFound()
|
||||
get_object_or_404(models.User, localname=username, is_active=True)
|
||||
|
||||
# is it valid json? does it at least vaguely resemble an activity?
|
||||
try:
|
||||
activity_json = json.loads(request.body)
|
||||
except json.decoder.JSONDecodeError:
|
||||
return HttpResponseBadRequest()
|
||||
raise BadRequest()
|
||||
|
||||
# let's be extra sure we didn't block this domain
|
||||
if is_blocked_activity(activity_json):
|
||||
return HttpResponseForbidden()
|
||||
raise_is_blocked_activity(activity_json)
|
||||
|
||||
if (
|
||||
not "object" in activity_json
|
||||
or not "type" in activity_json
|
||||
or not activity_json["type"] in activitypub.activity_objects
|
||||
):
|
||||
return HttpResponseNotFound()
|
||||
raise Http404()
|
||||
|
||||
# verify the signature
|
||||
if not has_valid_signature(request, activity_json):
|
||||
@ -65,32 +60,35 @@ class Inbox(View):
|
||||
return HttpResponse()
|
||||
|
||||
|
||||
def is_blocked_user_agent(request):
|
||||
def raise_is_blocked_user_agent(request):
|
||||
"""check if a request is from a blocked server based on user agent"""
|
||||
# check user agent
|
||||
user_agent = request.headers.get("User-Agent")
|
||||
if not user_agent:
|
||||
return False
|
||||
return
|
||||
url = re.search(rf"https?://{regex.DOMAIN}/?", user_agent)
|
||||
if not url:
|
||||
return False
|
||||
return
|
||||
url = url.group()
|
||||
return models.FederatedServer.is_blocked(url)
|
||||
if models.FederatedServer.is_blocked(url):
|
||||
raise PermissionDenied()
|
||||
|
||||
|
||||
def is_blocked_activity(activity_json):
|
||||
def raise_is_blocked_activity(activity_json):
|
||||
"""get the sender out of activity json and check if it's blocked"""
|
||||
actor = activity_json.get("actor")
|
||||
|
||||
# check if the user is banned/deleted
|
||||
existing = models.User.find_existing_by_remote_id(actor)
|
||||
if existing and existing.deleted:
|
||||
return True
|
||||
raise PermissionDenied()
|
||||
|
||||
if not actor:
|
||||
# well I guess it's not even a valid activity so who knows
|
||||
return False
|
||||
return models.FederatedServer.is_blocked(actor)
|
||||
return
|
||||
|
||||
if models.FederatedServer.is_blocked(actor):
|
||||
raise PermissionDenied()
|
||||
|
||||
|
||||
@app.task(queue="medium_priority")
|
||||
|
Reference in New Issue
Block a user