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.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse
from django.test import TestCase
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 bookwyrm import settings, views, wellknown
from bookwyrm import settings, views
from bookwyrm.utils import regex
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"%s/inbox/?$" % local_user_path, views.Inbox.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/nodeinfo/?$", wellknown.nodeinfo_pointer),
re_path(r"^nodeinfo/2\.0/?$", wellknown.nodeinfo),
re_path(r"^api/v1/instance/?$", wellknown.instance_info),
re_path(r"^api/v1/instance/peers/?$", wellknown.peers),
re_path(r"^.well-known/webfinger/?$", views.webfinger),
re_path(r"^.well-known/nodeinfo/?$", views.nodeinfo_pointer),
re_path(r"^nodeinfo/2\.0/?$", views.nodeinfo),
re_path(r"^api/v1/instance/?$", views.instance_info),
re_path(r"^api/v1/instance/peers/?$", views.peers),
# polling updates
re_path("^api/updates/notifications/?$", views.Updates.as_view()),
# authentication

View file

@ -14,6 +14,7 @@ from .import_data import Import, ImportStatus
from .inbox import Inbox
from .interaction import Favorite, Unfavorite, Boost, Unboost
from .invite import ManageInvites, Invite
from .isbn import Isbn
from .landing import About, Home, Discover
from .list import Lists, List, Curate, UserLists
from .notifications import Notifications
@ -32,4 +33,4 @@ from .status import CreateStatus, DeleteStatus
from .tag import Tag, AddTag, RemoveTag
from .updates import Updates
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 JsonResponse
from django.utils import timezone
from django.views.decorators.http import require_GET
from bookwyrm import models
from bookwyrm.settings import DOMAIN, VERSION
@require_GET
def webfinger(request):
""" allow other servers to ask about a user """
if request.method != "GET":
return HttpResponseNotFound()
resource = request.GET.get("resource")
if not resource and not resource.startswith("acct:"):
if not resource or not resource.startswith("acct:"):
return HttpResponseNotFound()
username = resource.replace("acct:", "")
@ -38,11 +37,9 @@ def webfinger(request):
)
def nodeinfo_pointer(request):
@require_GET
def nodeinfo_pointer(_):
""" direct servers to nodeinfo """
if request.method != "GET":
return HttpResponseNotFound()
return JsonResponse(
{
"links": [
@ -55,11 +52,9 @@ def nodeinfo_pointer(request):
)
def nodeinfo(request):
@require_GET
def nodeinfo(_):
""" basic info about the server """
if request.method != "GET":
return HttpResponseNotFound()
status_count = models.Status.objects.filter(user__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 """
if request.method != "GET":
return HttpResponseNotFound()
user_count = models.User.objects.filter(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 """
if request.method != "GET":
return HttpResponseNotFound()
names = models.FederatedServer.objects.values_list("server_name", flat=True)
return JsonResponse(list(names), safe=False)