ostatus remote follow views

This commit is contained in:
Hugh Rundle 2021-11-28 16:56:21 +11:00
parent 610114b4eb
commit e275b98183
No known key found for this signature in database
GPG key ID: CD23D6039184286B
3 changed files with 85 additions and 2 deletions

View file

@ -44,6 +44,7 @@ urlpatterns = [
re_path(r"^api/v1/instance/?$", views.instance_info),
re_path(r"^api/v1/instance/peers/?$", views.peers),
re_path(r"^opensearch.xml$", views.opensearch, name="opensearch"),
re_path(r"^ostatus_subscribe/?$", views.ostatus_follow_request),
# polling updates
re_path("^api/updates/notifications/?$", views.get_notification_count),
re_path("^api/updates/stream/(?P<stream>[a-z]+)/?$", views.get_unread_status_count),
@ -450,4 +451,6 @@ urlpatterns = [
re_path(r"^unfollow/?$", views.unfollow, name="unfollow"),
re_path(r"^accept-follow-request/?$", views.accept_follow_request),
re_path(r"^delete-follow-request/?$", views.delete_follow_request),
# re_path(r"^ostatus_follow/?$", views.remote_follow),
re_path(r"^ostatus_success/?$", views.ostatus_follow_success, name="ostatus-success"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View file

@ -58,7 +58,7 @@ from .author import Author, EditAuthor
from .directory import Directory
from .discover import Discover
from .feed import DirectMessage, Feed, Replies, Status
from .follow import follow, unfollow
from .follow import follow, unfollow, ostatus_follow_request, ostatus_follow_success
from .follow import accept_follow_request, delete_follow_request
from .get_started import GetStartedBooks, GetStartedProfile, GetStartedUsers
from .goal import Goal, hide_goal

View file

@ -1,11 +1,14 @@
""" views for actions you can take in the application """
import urllib.parse
import re
from django.contrib.auth.decorators import login_required
from django.db import IntegrityError
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.views.decorators.http import require_POST
from bookwyrm import models
from .helpers import get_user_from_username
from .helpers import get_user_from_username, handle_remote_webfinger
@login_required
@ -23,9 +26,13 @@ def follow(request):
except IntegrityError:
pass
if request.GET.get("next"):
return redirect(request.GET.get("next", "/"))
return redirect(to_follow.local_path)
@login_required
@require_POST
def unfollow(request):
@ -84,3 +91,76 @@ def delete_follow_request(request):
follow_request.delete()
return redirect(f"/user/{request.user.localname}")
def ostatus_follow_request(request):
"""prepare an outgoing remote follow request"""
# parse the acct URI into a user string
uri = urllib.parse.unquote(request.GET.get("acct"))
username_parts = re.search("(?:^http(?:s?):\/\/)([\w\-\.]*)(?:.)*(?:(?:\/)([\w]*))", uri)
account = f"{username_parts[2]}@{username_parts[1]}"
user = handle_remote_webfinger(account)
error = None
if user is None or user == "":
error = "ostatus_subscribe"
if bool(user) and user in request.user.blocks.all():
error = "is_blocked"
if hasattr(user, "followers") and request.user in user.followers.all():
error = "already_following"
if hasattr(user, "follower_requests") and request.user in user.follower_requests.all():
error = "already_requested"
data = {
"account": account,
"user": user,
"error": error
}
return TemplateResponse(request, "ostatus/subscribe.html", data)
@login_required
def ostatus_follow_success(request):
"""display success message for remote follow"""
user = get_user_from_username(request.user, request.GET.get("following"))
data = {
"account": user.name,
"user": user,
"error": None
}
return TemplateResponse(request, "ostatus/success.html", data)
@login_required
@require_POST
def remote_follow(request):
"""complete an incoming remote follow request"""
# this is triggered from remote follow form
# attempt the follow request
# on success [[return success page]]
# on fail return [[ostatus_error]]
"""
REQUEST TO FOLLOW FROM REMOTE ACCOUNT
1. click remote follow button [default checked option to open new window]
2. popup new small window
3. enter user acct to follow from (user@domain.tld) and submit form
5. GET {base_url}/.well-known/webfinger/?resource=acct:{user@domain.tld}
6. parse json for links
6.1 rel="http://ostatus.org/schema/1.0/subscribe" and return 'template'
6.2 rel="self" and return href
7. replace '{uri}' in the returned string with self.href
8. GET the URI at 6.1
REQUEST TO FOLLOW FROM LOCAL ACCOUNT
1. receive request to /ostatus_subscribe?acct={uri}
2. check user is logged in and present confirmation screen (remote_follow_request)
3. On confirmation, 3. parse user into info needed for a normal follow
4. send follow request, on 200 response display success else display error (remote_follow)
5. Include button inviting to close window
"""