Merge pull request #728 from mouse-reeve/wellknown-view

Moves federation info endpoints into views module
This commit is contained in:
Mouse Reeve 2021-03-13 11:11:28 -08:00 committed by GitHub
commit 6e5f2f411f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 28 deletions

View file

@ -5,7 +5,6 @@ from PIL import Image
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory

View file

@ -0,0 +1,84 @@
""" test for app action functionality """
import json
from unittest.mock import patch
from django.contrib.auth.models import AnonymousUser
from django.http import JsonResponse
from django.test import TestCase
from django.test.client import RequestFactory
from bookwyrm import models, views
class UserViews(TestCase):
""" view user and edit profile """
def setUp(self):
""" we need basic test data and mocks """
self.factory = RequestFactory()
self.local_user = models.User.objects.create_user(
"mouse@local.com",
"mouse@mouse.mouse",
"password",
local=True,
localname="mouse",
)
models.User.objects.create_user(
"rat@local.com", "rat@rat.rat", "password", local=True, localname="rat"
)
with patch("bookwyrm.models.user.set_remote_server.delay"):
models.User.objects.create_user(
"rat",
"rat@remote.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()
self.anonymous_user = AnonymousUser
self.anonymous_user.is_authenticated = False
def test_webfinger(self):
""" there are so many views, this just makes sure it LOADS """
request = self.factory.get("", {"resource": "acct:mouse@local.com"})
request.user = self.anonymous_user
result = views.webfinger(request)
self.assertIsInstance(result, JsonResponse)
data = json.loads(result.getvalue())
self.assertEqual(data["subject"], "acct:mouse@local.com")
def test_nodeinfo_pointer(self):
""" just tells you where nodeinfo is """
request = self.factory.get("")
request.user = self.anonymous_user
result = views.nodeinfo_pointer(request)
data = json.loads(result.getvalue())
self.assertIsInstance(result, JsonResponse)
self.assertTrue("href" in data["links"][0])
def test_nodeinfo(self):
""" info about the instance """
request = self.factory.get("")
request.user = self.anonymous_user
result = views.nodeinfo(request)
data = json.loads(result.getvalue())
self.assertIsInstance(result, JsonResponse)
self.assertEqual(data["software"]["name"], "bookwyrm")
self.assertEqual(data["usage"]["users"]["total"], 2)
self.assertEqual(models.User.objects.count(), 3)
def test_instanceinfo(self):
""" about the instance's user activity """
request = self.factory.get("")
request.user = self.anonymous_user
result = views.instance_info(request)
data = json.loads(result.getvalue())
self.assertIsInstance(result, JsonResponse)
self.assertEqual(data["stats"]["user_count"], 2)
self.assertEqual(models.User.objects.count(), 3)

View file

@ -4,7 +4,7 @@ from django.contrib import admin
from django.urls import path, re_path from django.urls import path, re_path
from bookwyrm import settings, views, wellknown from bookwyrm import settings, views
from bookwyrm.utils import regex from bookwyrm.utils import regex
user_path = r"^user/(?P<username>%s)" % regex.username user_path = r"^user/(?P<username>%s)" % regex.username
@ -31,11 +31,11 @@ urlpatterns = [
re_path(r"^inbox/?$", views.Inbox.as_view()), re_path(r"^inbox/?$", views.Inbox.as_view()),
re_path(r"%s/inbox/?$" % local_user_path, views.Inbox.as_view()), re_path(r"%s/inbox/?$" % local_user_path, views.Inbox.as_view()),
re_path(r"%s/outbox/?$" % local_user_path, views.Outbox.as_view()), re_path(r"%s/outbox/?$" % local_user_path, views.Outbox.as_view()),
re_path(r"^.well-known/webfinger/?$", wellknown.webfinger), re_path(r"^.well-known/webfinger/?$", views.webfinger),
re_path(r"^.well-known/nodeinfo/?$", wellknown.nodeinfo_pointer), re_path(r"^.well-known/nodeinfo/?$", views.nodeinfo_pointer),
re_path(r"^nodeinfo/2\.0/?$", wellknown.nodeinfo), re_path(r"^nodeinfo/2\.0/?$", views.nodeinfo),
re_path(r"^api/v1/instance/?$", wellknown.instance_info), re_path(r"^api/v1/instance/?$", views.instance_info),
re_path(r"^api/v1/instance/peers/?$", wellknown.peers), re_path(r"^api/v1/instance/peers/?$", views.peers),
# polling updates # polling updates
re_path("^api/updates/notifications/?$", views.Updates.as_view()), re_path("^api/updates/notifications/?$", views.Updates.as_view()),
# authentication # authentication

View file

@ -14,6 +14,7 @@ from .import_data import Import, ImportStatus
from .inbox import Inbox from .inbox import Inbox
from .interaction import Favorite, Unfavorite, Boost, Unboost from .interaction import Favorite, Unfavorite, Boost, Unboost
from .invite import ManageInvites, Invite from .invite import ManageInvites, Invite
from .isbn import Isbn
from .landing import About, Home, Discover from .landing import About, Home, Discover
from .list import Lists, List, Curate, UserLists from .list import Lists, List, Curate, UserLists
from .notifications import Notifications from .notifications import Notifications
@ -32,4 +33,4 @@ from .status import CreateStatus, DeleteStatus
from .tag import Tag, AddTag, RemoveTag from .tag import Tag, AddTag, RemoveTag
from .updates import Updates from .updates import Updates
from .user import User, EditUser, Followers, Following from .user import User, EditUser, Followers, Following
from .isbn import Isbn from .wellknown import webfinger, nodeinfo_pointer, nodeinfo, instance_info, peers

View file

@ -4,18 +4,17 @@ from dateutil.relativedelta import relativedelta
from django.http import HttpResponseNotFound from django.http import HttpResponseNotFound
from django.http import JsonResponse from django.http import JsonResponse
from django.utils import timezone from django.utils import timezone
from django.views.decorators.http import require_GET
from bookwyrm import models from bookwyrm import models
from bookwyrm.settings import DOMAIN, VERSION from bookwyrm.settings import DOMAIN, VERSION
@require_GET
def webfinger(request): def webfinger(request):
""" allow other servers to ask about a user """ """ allow other servers to ask about a user """
if request.method != "GET":
return HttpResponseNotFound()
resource = request.GET.get("resource") resource = request.GET.get("resource")
if not resource and not resource.startswith("acct:"): if not resource or not resource.startswith("acct:"):
return HttpResponseNotFound() return HttpResponseNotFound()
username = resource.replace("acct:", "") username = resource.replace("acct:", "")
@ -38,11 +37,9 @@ def webfinger(request):
) )
def nodeinfo_pointer(request): @require_GET
def nodeinfo_pointer(_):
""" direct servers to nodeinfo """ """ direct servers to nodeinfo """
if request.method != "GET":
return HttpResponseNotFound()
return JsonResponse( return JsonResponse(
{ {
"links": [ "links": [
@ -55,11 +52,9 @@ def nodeinfo_pointer(request):
) )
def nodeinfo(request): @require_GET
def nodeinfo(_):
""" basic info about the server """ """ basic info about the server """
if request.method != "GET":
return HttpResponseNotFound()
status_count = models.Status.objects.filter(user__local=True).count() status_count = models.Status.objects.filter(user__local=True).count()
user_count = models.User.objects.filter(local=True).count() user_count = models.User.objects.filter(local=True).count()
@ -92,11 +87,9 @@ def nodeinfo(request):
) )
def instance_info(request): @require_GET
def instance_info(_):
""" let's talk about your cool unique instance """ """ let's talk about your cool unique instance """
if request.method != "GET":
return HttpResponseNotFound()
user_count = models.User.objects.filter(local=True).count() user_count = models.User.objects.filter(local=True).count()
status_count = models.Status.objects.filter(user__local=True).count() status_count = models.Status.objects.filter(user__local=True).count()
@ -120,10 +113,8 @@ def instance_info(request):
) )
def peers(request): @require_GET
def peers(_):
""" list of federated servers this instance connects with """ """ list of federated servers this instance connects with """
if request.method != "GET":
return HttpResponseNotFound()
names = models.FederatedServer.objects.values_list("server_name", flat=True) names = models.FederatedServer.objects.values_list("server_name", flat=True)
return JsonResponse(list(names), safe=False) return JsonResponse(list(names), safe=False)