forked from mirrors/bookwyrm
more descriptive remote follow errors
- distinguish between invalid username, user not found, and remote follow not supported - make helpers DRYer
This commit is contained in:
parent
c77edab79c
commit
781fe69470
4 changed files with 83 additions and 38 deletions
|
@ -2,7 +2,28 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% if not request.user.is_authenticated and not error == 'remote_subscribe' %}
|
{% if error == 'invalid_username' %}
|
||||||
|
<div class="notification is-warning has-text-centered" role="status">
|
||||||
|
{% blocktrans %}
|
||||||
|
<p><strong>{{ account }}</strong> is not a valid username.</p>
|
||||||
|
<p>Check you have the correct username before trying again.</p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
{% elif error == 'user_not_found' %}
|
||||||
|
<div class="notification is-warning has-text-centered" role="status">
|
||||||
|
{% blocktrans %}
|
||||||
|
<p><strong>{{ account }}</strong> could not be found or <code>{{ remote_domain }}</code> does not support identity discovery.</p>
|
||||||
|
<p>Check you have the correct username before trying again.</p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
{% elif error == 'not_supported' %}
|
||||||
|
<div class="notification is-warning has-text-centered" role="status">
|
||||||
|
{% blocktrans %}
|
||||||
|
<p><strong>{{ account }}</strong> was found but <code>{{ remote_domain }}</code> does not support 'remote follow'.</p>
|
||||||
|
<p>Try searching for <strong>{{ user }}</strong> on <code>{{ remote_domain }}</code> instead.</p>
|
||||||
|
{% endblocktrans %}
|
||||||
|
</div>
|
||||||
|
{% elif not request.user.is_authenticated %}
|
||||||
<div class="navbar-item">
|
<div class="navbar-item">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
|
@ -31,11 +52,6 @@
|
||||||
<p>{% blocktrans %}Something went wrong trying to follow <strong>{{ account }}</strong>{% endblocktrans %}</p>
|
<p>{% blocktrans %}Something went wrong trying to follow <strong>{{ account }}</strong>{% endblocktrans %}</p>
|
||||||
<p>{% trans 'Check you have the correct username before trying again.' %}</p>
|
<p>{% trans 'Check you have the correct username before trying again.' %}</p>
|
||||||
</div>
|
</div>
|
||||||
{% elif error == 'remote_subscribe' %}
|
|
||||||
<div class="notification is-warning has-text-centered" role="status">
|
|
||||||
<p>{% blocktrans %}Something went wrong trying to follow from <strong>{{ account }}</strong>{% endblocktrans %}</p>
|
|
||||||
<p>{% trans 'Check you have the correct username before trying again.' %}</p>
|
|
||||||
</div>
|
|
||||||
{% elif error == 'is_blocked' %}
|
{% elif error == 'is_blocked' %}
|
||||||
<div class="notification is-danger has-text-centered" role="status">
|
<div class="notification is-danger has-text-centered" role="status">
|
||||||
<p>{% blocktrans %}You have blocked <strong>{{ account }}</strong>{% endblocktrans %}</p>
|
<p>{% blocktrans %}You have blocked <strong>{{ account }}</strong>{% endblocktrans %}</p>
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
{% if not request.user.is_authenticated and not error == 'remote_subscribe' %}
|
{% if error %}
|
||||||
{% trans "Let's log in first..." %}
|
|
||||||
{% elif error %}
|
|
||||||
{% trans 'Uh oh...' %}
|
{% trans 'Uh oh...' %}
|
||||||
|
{% elif not request.user.is_authenticated %}
|
||||||
|
{% trans "Let's log in first..." %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% blocktrans with sitename=site.name %}Follow from {{ sitename }}{% endblocktrans %}
|
{% blocktrans with sitename=site.name %}Follow from {{ sitename }}{% endblocktrans %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -12,6 +12,7 @@ from .helpers import (
|
||||||
get_user_from_username,
|
get_user_from_username,
|
||||||
handle_remote_webfinger,
|
handle_remote_webfinger,
|
||||||
subscribe_remote_webfinger,
|
subscribe_remote_webfinger,
|
||||||
|
WebFingerError,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,7 +143,7 @@ def ostatus_follow_success(request):
|
||||||
|
|
||||||
|
|
||||||
def remote_follow_page(request):
|
def remote_follow_page(request):
|
||||||
"""Display remote follow page"""
|
"""display remote follow page"""
|
||||||
user = get_user_from_username(request.user, request.GET.get("user"))
|
user = get_user_from_username(request.user, request.GET.get("user"))
|
||||||
data = {"user": user}
|
data = {"user": user}
|
||||||
return TemplateResponse(request, "ostatus/remote_follow.html", data)
|
return TemplateResponse(request, "ostatus/remote_follow.html", data)
|
||||||
|
@ -152,10 +153,33 @@ def remote_follow_page(request):
|
||||||
def remote_follow(request):
|
def remote_follow(request):
|
||||||
"""direct user to follow from remote account using ostatus subscribe protocol"""
|
"""direct user to follow from remote account using ostatus subscribe protocol"""
|
||||||
remote_user = request.POST.get("remote_user")
|
remote_user = request.POST.get("remote_user")
|
||||||
template = subscribe_remote_webfinger(remote_user)
|
try:
|
||||||
if template is None:
|
if remote_user[0] == "@":
|
||||||
data = {"account": remote_user, "user": None, "error": "remote_subscribe"}
|
remote_user = remote_user[1:]
|
||||||
return TemplateResponse(request, "ostatus/subscribe.html", data)
|
remote_domain = remote_user.split("@")[1]
|
||||||
|
except:
|
||||||
|
remote_domain = None
|
||||||
|
|
||||||
|
wf_response = subscribe_remote_webfinger(remote_user)
|
||||||
user = get_object_or_404(models.User, id=request.POST.get("user"))
|
user = get_object_or_404(models.User, id=request.POST.get("user"))
|
||||||
url = template.replace("{uri}", urllib.parse.quote(user.remote_id))
|
|
||||||
|
if wf_response is None:
|
||||||
|
data = {
|
||||||
|
"account": remote_user,
|
||||||
|
"user": user,
|
||||||
|
"error": "not_supported",
|
||||||
|
"remote_domain": remote_domain,
|
||||||
|
}
|
||||||
|
return TemplateResponse(request, "ostatus/subscribe.html", data)
|
||||||
|
|
||||||
|
if type(wf_response) == WebFingerError:
|
||||||
|
data = {
|
||||||
|
"account": remote_user,
|
||||||
|
"user": user,
|
||||||
|
"error": str(wf_response),
|
||||||
|
"remote_domain": remote_domain,
|
||||||
|
}
|
||||||
|
return TemplateResponse(request, "ostatus/subscribe.html", data)
|
||||||
|
|
||||||
|
url = wf_response.replace("{uri}", urllib.parse.quote(user.remote_id))
|
||||||
return redirect(url)
|
return redirect(url)
|
||||||
|
|
|
@ -15,6 +15,27 @@ from bookwyrm.status import create_generated_note
|
||||||
from bookwyrm.utils import regex
|
from bookwyrm.utils import regex
|
||||||
|
|
||||||
|
|
||||||
|
class WebFingerError(Exception):
|
||||||
|
"""error class for problems finding user information with webfinger"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_domain_from_username(username):
|
||||||
|
# usernames could be @user@domain or user@domain
|
||||||
|
if not username:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if username[0] == "@":
|
||||||
|
username = username[1:]
|
||||||
|
|
||||||
|
try:
|
||||||
|
domain = username.split("@")[1]
|
||||||
|
return domain
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_user_from_username(viewer, username):
|
def get_user_from_username(viewer, username):
|
||||||
"""helper function to resolve a localname or a username to a user"""
|
"""helper function to resolve a localname or a username to a user"""
|
||||||
if viewer.is_authenticated and viewer.localname == username:
|
if viewer.is_authenticated and viewer.localname == username:
|
||||||
|
@ -52,17 +73,8 @@ def is_bookwyrm_request(request):
|
||||||
def handle_remote_webfinger(query):
|
def handle_remote_webfinger(query):
|
||||||
"""webfingerin' other servers"""
|
"""webfingerin' other servers"""
|
||||||
user = None
|
user = None
|
||||||
|
domain = get_domain_from_username(query)
|
||||||
# usernames could be @user@domain or user@domain
|
if domain is None:
|
||||||
if not query:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if query[0] == "@":
|
|
||||||
query = query[1:]
|
|
||||||
|
|
||||||
try:
|
|
||||||
domain = query.split("@")[1]
|
|
||||||
except IndexError:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -88,24 +100,17 @@ def handle_remote_webfinger(query):
|
||||||
def subscribe_remote_webfinger(query):
|
def subscribe_remote_webfinger(query):
|
||||||
"""get subscribe template from other servers"""
|
"""get subscribe template from other servers"""
|
||||||
template = None
|
template = None
|
||||||
|
domain = get_domain_from_username(query)
|
||||||
|
|
||||||
# usernames could be @user@domain or user@domain
|
if domain is None:
|
||||||
if not query:
|
return WebFingerError("invalid_username")
|
||||||
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}"
|
url = f"https://{domain}/.well-known/webfinger?resource=acct:{query}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = get_data(url)
|
data = get_data(url)
|
||||||
except (ConnectorException, HTTPError):
|
except (ConnectorException, HTTPError):
|
||||||
return None
|
return WebFingerError("user_not_found")
|
||||||
|
|
||||||
for link in data.get("links"):
|
for link in data.get("links"):
|
||||||
if link.get("rel") == "http://ostatus.org/schema/1.0/subscribe":
|
if link.get("rel") == "http://ostatus.org/schema/1.0/subscribe":
|
||||||
|
|
Loading…
Reference in a new issue