Check if incoming domains are blocked

This commit is contained in:
Mouse Reeve 2021-04-05 15:16:21 -07:00
parent e61ed73894
commit 1901f7e6cb
2 changed files with 56 additions and 7 deletions

View file

@ -2,16 +2,27 @@
from django.db import models from django.db import models
from .base_model import BookWyrmModel from .base_model import BookWyrmModel
FederationStatus = models.TextChoices(
"Status",
[
"federated",
"blocked",
],
)
class FederatedServer(BookWyrmModel): class FederatedServer(BookWyrmModel):
""" store which servers we federate with """ """ store which servers we federate with """
server_name = models.CharField(max_length=255, unique=True) server_name = models.CharField(max_length=255, unique=True)
# federated, blocked, whatever else status = models.CharField(
status = models.CharField(max_length=255, default="federated") max_length=255, default="federated", choices=FederationStatus.choices
)
# is it mastodon, bookwyrm, etc # is it mastodon, bookwyrm, etc
application_type = models.CharField(max_length=255, null=True) application_type = models.CharField(max_length=255, null=True)
application_version = models.CharField(max_length=255, null=True) application_version = models.CharField(max_length=255, null=True)
def block(self):
# TODO: blocked servers """ block a server """
self.status = "blocked"
self.save()

View file

@ -1,9 +1,10 @@
""" incoming activities """ """ incoming activities """
import json import json
from urllib.parse import urldefrag import re
from urllib.parse import urldefrag, urlparse
from django.http import HttpResponse from django.http import HttpResponse, HttpResponseNotFound
from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.http import HttpResponseBadRequest, HttpResponseForbidden
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
@ -12,6 +13,7 @@ import requests
from bookwyrm import activitypub, models from bookwyrm import activitypub, models
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.signatures import Signature from bookwyrm.signatures import Signature
from bookwyrm.utils import regex
@method_decorator(csrf_exempt, name="dispatch") @method_decorator(csrf_exempt, name="dispatch")
@ -21,6 +23,10 @@ class Inbox(View):
def post(self, request, username=None): def post(self, request, username=None):
""" only works as POST request """ """ only works as POST request """
# first check if this server is on our shitlist
if is_blocked_user_agent(request):
return HttpResponseForbidden()
# make sure the user's inbox even exists # make sure the user's inbox even exists
if username: if username:
try: try:
@ -34,6 +40,10 @@ class Inbox(View):
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
return HttpResponseBadRequest() return HttpResponseBadRequest()
# let's be extra sure we didn't block this domain
if is_blocked_activity(activity_json):
return HttpResponseForbidden()
if ( if (
not "object" in activity_json not "object" in activity_json
or not "type" in activity_json or not "type" in activity_json
@ -54,6 +64,34 @@ class Inbox(View):
return HttpResponse() return HttpResponse()
def 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")
domain = re.match(regex.domain, user_agent)
if not domain:
# idk, we'll try again later with the actor
return False
return is_blocked(domain)
def is_blocked_activity(activity_json):
""" get the sender out of activity json and check if it's blocked """
actor = activity_json.get("actor")
if not actor:
# well I guess it's not even a valid activity so who knows
return False
url = urlparse(actor)
return is_blocked(url.netloc)
def is_blocked(domain):
""" is this domain blocked? """
return models.FederatedServer.object.filter(
server_name=domain, status="blocked"
).exists()
@app.task @app.task
def activity_task(activity_json): def activity_task(activity_json):
""" do something with this json we think is legit """ """ do something with this json we think is legit """