add remote follow button

This commit is contained in:
Hugh Rundle 2021-11-28 20:09:29 +11:00
parent 2e428e6ea1
commit 6e7d23c1ae
No known key found for this signature in database
GPG key ID: CD23D6039184286B
5 changed files with 51 additions and 18 deletions

View file

@ -39,6 +39,9 @@
{% if not is_self and request.user.is_authenticated %}
{% include 'snippets/follow_button.html' with user=user %}
{% endif %}
{% if not is_self %}
{% include 'ostatus/remote_follow_button.html' with user=user %}
{% endif %}
{% if is_self and user.follower_requests.all %}
<div class="follow-requests">

View file

@ -451,6 +451,7 @@ 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_follow/?$", views.remote_follow, name="remote-follow"),
re_path(r"^remote_follow/?$", views.remote_follow_page, name="remote-follow-page"),
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, ostatus_follow_request, ostatus_follow_success
from .follow import follow, unfollow, ostatus_follow_request, ostatus_follow_success, remote_follow, remote_follow_page
from .follow import accept_follow_request, delete_follow_request
from .get_started import GetStartedBooks, GetStartedProfile, GetStartedUsers
from .goal import Goal, hide_goal

View file

@ -8,7 +8,7 @@ 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, handle_remote_webfinger
from .helpers import get_user_from_username, handle_remote_webfinger, subscribe_remote_webfinger
@login_required
@ -134,33 +134,35 @@ def ostatus_follow_success(request):
}
return TemplateResponse(request, "ostatus/success.html", data)
@login_required
@require_POST
def remote_follow(request):
"""complete an incoming remote follow request"""
def remote_follow_page(request):
"""Display remote follow page"""
# this is triggered from remote follow form
# attempt the follow request
# on success [[return success page]]
# on fail return [[ostatus_error]]
user = get_user_from_username(request.user, request.GET.get("user"))
data = {
"user": user
}
return TemplateResponse(request, "ostatus/remote_follow.html", data)
@require_POST
def remote_follow(request):
"""direct user to follow from remote account using ostatus subscribe protocol"""
remote_user = request.POST.get("remote_user")
template = subscribe_remote_webfinger(remote_user)
url = template.replace("{uri}", request.POST.get("user"))
return redirect(url)
"""
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)
4. send follow request, on 200 response display success else display error
5. Include button inviting to close window
"""

View file

@ -84,6 +84,33 @@ def handle_remote_webfinger(query):
return None
return user
def subscribe_remote_webfinger(query):
"""get subscribe template from other servers"""
template = None
# usernames could be @user@domain or user@domain
if not query:
return None
if query[0] == "@":
query = query[1:]
try:
domain = query.split("@")[1]
except IndexError:
return None
url = f"https://{domain}/.well-known/webfinger?resource=acct:{query}"
try:
data = get_data(url)
except (ConnectorException, HTTPError):
return None
for link in data.get("links"):
if link.get("rel") == "http://ostatus.org/schema/1.0/subscribe":
template = link["template"]
return template
def get_edition(book_id):
"""look up a book in the db and return an edition"""