Merge pull request #881 from mouse-reeve/domain-block

Block federation at the domain level
This commit is contained in:
Mouse Reeve
2021-04-12 10:41:02 -07:00
committed by GitHub
30 changed files with 753 additions and 167 deletions

View File

@ -1,4 +1,5 @@
""" testing models """
from unittest.mock import patch
from django.test import TestCase
from bookwyrm import models
@ -9,6 +10,22 @@ from bookwyrm.settings import DOMAIN
class BaseModel(TestCase):
""" functionality shared across models """
def setUp(self):
""" shared data """
self.local_user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
"rat@rat.com",
"ratword",
local=False,
remote_id="https://example.com/users/rat",
inbox="https://example.com/users/rat/inbox",
outbox="https://example.com/users/rat/outbox",
)
def test_remote_id(self):
""" these should be generated """
instance = base_model.BookWyrmModel()
@ -18,11 +35,8 @@ class BaseModel(TestCase):
def test_remote_id_with_user(self):
""" format of remote id when there's a user object """
user = models.User.objects.create_user(
"mouse", "mouse@mouse.com", "mouseword", local=True, localname="mouse"
)
instance = base_model.BookWyrmModel()
instance.user = user
instance.user = self.local_user
instance.id = 1
expected = instance.get_remote_id()
self.assertEqual(expected, "https://%s/user/mouse/bookwyrmmodel/1" % DOMAIN)
@ -42,3 +56,66 @@ class BaseModel(TestCase):
instance.remote_id = None
base_model.set_remote_id(None, instance, False)
self.assertIsNone(instance.remote_id)
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
def test_object_visible_to_user(self, _):
""" does a user have permission to view an object """
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertTrue(obj.visible_to_user(self.local_user))
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertTrue(obj.visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertFalse(obj.visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(obj.visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(obj.visible_to_user(self.local_user))
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
def test_object_visible_to_user_follower(self, _):
""" what you can see if you follow a user """
self.remote_user.followers.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertTrue(obj.visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(obj.visible_to_user(self.local_user))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(obj.visible_to_user(self.local_user))
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
def test_object_visible_to_user_blocked(self, _):
""" you can't see it if they block you """
self.remote_user.blocks.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertFalse(obj.visible_to_user(self.local_user))
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertFalse(obj.visible_to_user(self.local_user))

View File

@ -0,0 +1,67 @@
""" testing models """
from unittest.mock import patch
from django.test import TestCase
from bookwyrm import models
class FederatedServer(TestCase):
""" federate server management """
def setUp(self):
""" we'll need a user """
self.server = models.FederatedServer.objects.create(server_name="test.server")
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
"rat@rat.com",
"ratword",
federated_server=self.server,
local=False,
remote_id="https://example.com/users/rat",
inbox="https://example.com/users/rat/inbox",
outbox="https://example.com/users/rat/outbox",
)
self.inactive_remote_user = models.User.objects.create_user(
"nutria",
"nutria@nutria.com",
"nutriaword",
federated_server=self.server,
local=False,
remote_id="https://example.com/users/nutria",
inbox="https://example.com/users/nutria/inbox",
outbox="https://example.com/users/nutria/outbox",
is_active=False,
deactivation_reason="self_deletion",
)
def test_block_unblock(self):
""" block a server and all users on it """
self.assertEqual(self.server.status, "federated")
self.assertTrue(self.remote_user.is_active)
self.assertFalse(self.inactive_remote_user.is_active)
self.server.block()
self.assertEqual(self.server.status, "blocked")
self.remote_user.refresh_from_db()
self.assertFalse(self.remote_user.is_active)
self.assertEqual(self.remote_user.deactivation_reason, "domain_block")
self.inactive_remote_user.refresh_from_db()
self.assertFalse(self.inactive_remote_user.is_active)
self.assertEqual(self.inactive_remote_user.deactivation_reason, "self_deletion")
# UNBLOCK
self.server.unblock()
self.assertEqual(self.server.status, "federated")
# user blocked in deactivation is reactivated
self.remote_user.refresh_from_db()
self.assertTrue(self.remote_user.is_active)
self.assertIsNone(self.remote_user.deactivation_reason)
# deleted user remains deleted
self.inactive_remote_user.refresh_from_db()
self.assertFalse(self.inactive_remote_user.is_active)
self.assertEqual(self.inactive_remote_user.deactivation_reason, "self_deletion")

View File

@ -4,8 +4,9 @@ from unittest.mock import patch
from django.http import HttpResponseNotAllowed, HttpResponseNotFound
from django.test import TestCase, Client
from django.test.client import RequestFactory
from bookwyrm import models
from bookwyrm import models, views
# pylint: disable=too-many-public-methods
@ -15,6 +16,7 @@ class Inbox(TestCase):
def setUp(self):
""" basic user and book data """
self.client = Client()
self.factory = RequestFactory()
local_user = models.User.objects.create_user(
"mouse@example.com",
"mouse@mouse.com",
@ -106,3 +108,26 @@ class Inbox(TestCase):
"/inbox", json.dumps(activity), content_type="application/json"
)
self.assertEqual(result.status_code, 200)
def test_is_blocked_user_agent(self):
""" check for blocked servers """
request = self.factory.post(
"",
HTTP_USER_AGENT="http.rb/4.4.1 (Mastodon/3.3.0; +https://mastodon.social/)",
)
self.assertFalse(views.inbox.is_blocked_user_agent(request))
models.FederatedServer.objects.create(
server_name="mastodon.social", status="blocked"
)
self.assertTrue(views.inbox.is_blocked_user_agent(request))
def test_is_blocked_activity(self):
""" check for blocked servers """
activity = {"actor": "https://mastodon.social/user/whaatever/else"}
self.assertFalse(views.inbox.is_blocked_activity(activity))
models.FederatedServer.objects.create(
server_name="mastodon.social", status="blocked"
)
self.assertTrue(views.inbox.is_blocked_activity(activity))

View File

@ -1,9 +1,10 @@
""" test for app action functionality """
from unittest.mock import patch
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.client import RequestFactory
from bookwyrm import models, views
from bookwyrm import forms, models, views
class FederationViews(TestCase):
@ -19,6 +20,16 @@ class FederationViews(TestCase):
local=True,
localname="mouse",
)
with patch("bookwyrm.models.user.set_remote_server.delay"):
self.remote_user = models.User.objects.create_user(
"rat",
"rat@rat.com",
"ratword",
local=False,
remote_id="https://example.com/users/rat",
inbox="https://example.com/users/rat/inbox",
outbox="https://example.com/users/rat/outbox",
)
models.SiteSettings.objects.create()
def test_federation_page(self):
@ -44,3 +55,75 @@ class FederationViews(TestCase):
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
def test_server_page_block(self):
""" block a server """
server = models.FederatedServer.objects.create(server_name="hi.there.com")
self.remote_user.federated_server = server
self.remote_user.save()
self.assertEqual(server.status, "federated")
view = views.federation.block_server
request = self.factory.post("")
request.user = self.local_user
request.user.is_superuser = True
view(request, server.id)
server.refresh_from_db()
self.remote_user.refresh_from_db()
self.assertEqual(server.status, "blocked")
# and the user was deactivated
self.assertFalse(self.remote_user.is_active)
def test_server_page_unblock(self):
""" unblock a server """
server = models.FederatedServer.objects.create(
server_name="hi.there.com", status="blocked"
)
self.remote_user.federated_server = server
self.remote_user.is_active = False
self.remote_user.deactivation_reason = "domain_block"
self.remote_user.save()
request = self.factory.post("")
request.user = self.local_user
request.user.is_superuser = True
views.federation.unblock_server(request, server.id)
server.refresh_from_db()
self.remote_user.refresh_from_db()
self.assertEqual(server.status, "federated")
# and the user was re-activated
self.assertTrue(self.remote_user.is_active)
def test_add_view_get(self):
""" there are so many views, this just makes sure it LOADS """
# create mode
view = views.AddFederatedServer.as_view()
request = self.factory.get("")
request.user = self.local_user
request.user.is_superuser = True
result = view(request)
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
def test_add_view_post_create(self):
""" create a server entry """
form = forms.ServerForm()
form.data["server_name"] = "remote.server"
form.data["application_type"] = "coolsoft"
form.data["status"] = "blocked"
view = views.AddFederatedServer.as_view()
request = self.factory.post("", form.data)
request.user = self.local_user
request.user.is_superuser = True
view(request)
server = models.FederatedServer.objects.get()
self.assertEqual(server.server_name, "remote.server")
self.assertEqual(server.application_type, "coolsoft")
self.assertEqual(server.status, "blocked")

View File

@ -146,6 +146,15 @@ class ViewsHelpers(TestCase):
self.assertIsInstance(result, models.User)
self.assertEqual(result.username, "mouse@example.com")
def test_user_on_blocked_server(self, _):
""" find a remote user using webfinger """
models.FederatedServer.objects.create(
server_name="example.com", status="blocked"
)
result = views.helpers.handle_remote_webfinger("@mouse@example.com")
self.assertIsNone(result)
def test_handle_reading_status_to_read(self, _):
""" posts shelve activities """
shelf = self.local_user.shelf_set.get(identifier="to-read")
@ -190,66 +199,6 @@ class ViewsHelpers(TestCase):
)
self.assertFalse(models.GeneratedNote.objects.exists())
def test_object_visible_to_user(self, _):
""" does a user have permission to view an object """
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertTrue(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertTrue(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertFalse(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(views.helpers.object_visible_to_user(self.local_user, obj))
def test_object_visible_to_user_follower(self, _):
""" what you can see if you follow a user """
self.remote_user.followers.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="followers"
)
self.assertTrue(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
self.assertFalse(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="direct"
)
obj.mention_users.add(self.local_user)
self.assertTrue(views.helpers.object_visible_to_user(self.local_user, obj))
def test_object_visible_to_user_blocked(self, _):
""" you can't see it if they block you """
self.remote_user.blocks.add(self.local_user)
obj = models.Status.objects.create(
content="hi", user=self.remote_user, privacy="public"
)
self.assertFalse(views.helpers.object_visible_to_user(self.local_user, obj))
obj = models.Shelf.objects.create(
name="test", user=self.remote_user, privacy="unlisted"
)
self.assertFalse(views.helpers.object_visible_to_user(self.local_user, obj))
def test_get_annotated_users(self, _):
""" list of people you might know """
user_1 = models.User.objects.create_user(