More cleanup

This commit is contained in:
Thomas Sileo 2019-08-04 19:02:35 +02:00
parent 6c4e213b72
commit aa7528e49a
3 changed files with 76 additions and 78 deletions

81
app.py
View file

@ -24,9 +24,7 @@ from little_boxes.activitypub import get_backend
from little_boxes.errors import ActivityGoneError from little_boxes.errors import ActivityGoneError
from little_boxes.errors import Error from little_boxes.errors import Error
from little_boxes.httpsig import verify_request from little_boxes.httpsig import verify_request
from little_boxes.webfinger import get_actor_url
from little_boxes.webfinger import get_remote_follow_template from little_boxes.webfinger import get_remote_follow_template
from u2flib_server import u2f
import blueprints.admin import blueprints.admin
import blueprints.indieauth import blueprints.indieauth
@ -36,7 +34,6 @@ import config
from blueprints.api import _api_required from blueprints.api import _api_required
from blueprints.tasks import TaskError from blueprints.tasks import TaskError
from config import DB from config import DB
from config import HEADERS
from config import ID from config import ID
from config import ME from config import ME
from config import MEDIA_CACHE from config import MEDIA_CACHE
@ -54,14 +51,14 @@ from core.meta import _meta
from core.meta import by_remote_id from core.meta import by_remote_id
from core.meta import in_outbox from core.meta import in_outbox
from core.meta import is_public from core.meta import is_public
from core.shared import MY_PERSON from core.shared import jsonify
from core.shared import is_api_request
from core.shared import _build_thread from core.shared import _build_thread
from core.shared import _get_ip from core.shared import _get_ip
from core.shared import csrf from core.shared import csrf
from core.shared import login_required from core.shared import login_required
from core.shared import noindex from core.shared import noindex
from core.shared import paginated_query from core.shared import paginated_query
from utils import now
from utils.key import get_secret_key from utils.key import get_secret_key
from utils.template_filters import filters from utils.template_filters import filters
@ -162,29 +159,6 @@ def set_x_powered_by(response):
return response return response
def jsonify(**data):
if "@context" not in data:
data["@context"] = config.DEFAULT_CTX
return Response(
response=json.dumps(data),
headers={
"Content-Type": "application/json"
if app.debug
else "application/activity+json"
},
)
def is_api_request():
h = request.headers.get("Accept")
if h is None:
return False
h = h.split(",")[0]
if h in HEADERS or h == "application/json":
return True
return False
@app.errorhandler(ValueError) @app.errorhandler(ValueError)
def handle_value_error(error): def handle_value_error(error):
logger.error( logger.error(
@ -269,12 +243,9 @@ def serve_uploads(oid, fname):
return resp return resp
#######
# Login
@app.route("/remote_follow", methods=["GET", "POST"]) @app.route("/remote_follow", methods=["GET", "POST"])
def remote_follow(): def remote_follow():
"""Form to allow visitor to perform the remote follow dance."""
if request.method == "GET": if request.method == "GET":
return render_template("remote_follow.html") return render_template("remote_follow.html")
@ -285,52 +256,6 @@ def remote_follow():
return redirect(get_remote_follow_template(profile).format(uri=ID)) return redirect(get_remote_follow_template(profile).format(uri=ID))
@app.route("/authorize_follow", methods=["GET", "POST"])
@login_required
def authorize_follow():
if request.method == "GET":
return render_template(
"authorize_remote_follow.html", profile=request.args.get("profile")
)
actor = get_actor_url(request.form.get("profile"))
if not actor:
abort(500)
q = {
"box": Box.OUTBOX.value,
"type": ActivityType.FOLLOW.value,
"meta.undo": False,
"activity.object": actor,
}
if DB.activities.count(q) > 0:
return redirect("/following")
follow = ap.Follow(
actor=MY_PERSON.id, object=actor, to=[actor], cc=[ap.AS_PUBLIC], published=now()
)
post_to_outbox(follow)
return redirect("/following")
@app.route("/u2f/register", methods=["GET", "POST"])
@login_required
def u2f_register():
# TODO(tsileo): ensure no duplicates
if request.method == "GET":
payload = u2f.begin_registration(ID)
session["challenge"] = payload
return render_template("u2f.html", payload=payload)
else:
resp = json.loads(request.form.get("resp"))
device, device_cert = u2f.complete_registration(session["challenge"], resp)
session["challenge"] = None
DB.u2f.insert_one({"device": device, "cert": device_cert})
session["logged_in"] = False
return redirect("/login")
####### #######
# Activity pub routes # Activity pub routes

View file

@ -1,4 +1,5 @@
import json import json
from little_boxes.webfinger import get_actor_url
from datetime import datetime from datetime import datetime
from datetime import timedelta from datetime import timedelta
from datetime import timezone from datetime import timezone
@ -412,3 +413,49 @@ def admin_bookmarks() -> _Response:
return render_template( return render_template(
tpl, inbox_data=inbox_data, older_than=older_than, newer_than=newer_than tpl, inbox_data=inbox_data, older_than=older_than, newer_than=newer_than
) )
@blueprint.route("/u2f/register", methods=["GET", "POST"])
@login_required
def u2f_register():
# TODO(tsileo): ensure no duplicates
if request.method == "GET":
payload = u2f.begin_registration(ID)
session["challenge"] = payload
return render_template("u2f.html", payload=payload)
else:
resp = json.loads(request.form.get("resp"))
device, device_cert = u2f.complete_registration(session["challenge"], resp)
session["challenge"] = None
DB.u2f.insert_one({"device": device, "cert": device_cert})
session["logged_in"] = False
return redirect("/login")
@blueprint.route("/authorize_follow", methods=["GET", "POST"])
@login_required
def authorize_follow():
if request.method == "GET":
return render_template(
"authorize_remote_follow.html", profile=request.args.get("profile")
)
actor = get_actor_url(request.form.get("profile"))
if not actor:
abort(500)
q = {
"box": Box.OUTBOX.value,
"type": ap.ActivityType.FOLLOW.value,
"meta.undo": False,
"activity.object": actor,
}
if DB.activities.count(q) > 0:
return redirect("/following")
follow = ap.Follow(
actor=MY_PERSON.id, object=actor, to=[actor], cc=[ap.AS_PUBLIC], published=now()
)
post_to_outbox(follow)
return redirect("/following")

View file

@ -1,3 +1,4 @@
import json
import os import os
from functools import wraps from functools import wraps
from typing import Any from typing import Any
@ -7,12 +8,14 @@ from bson.objectid import ObjectId
from flask import current_app as app from flask import current_app as app
from flask import redirect from flask import redirect
from flask import request from flask import request
from flask import Response
from flask import session from flask import session
from flask import url_for from flask import url_for
from flask_wtf.csrf import CSRFProtect from flask_wtf.csrf import CSRFProtect
from little_boxes import activitypub as ap from little_boxes import activitypub as ap
from poussetaches import PousseTaches from poussetaches import PousseTaches
import config
from config import DB from config import DB
from config import ME from config import ME
from core import activitypub from core import activitypub
@ -35,6 +38,29 @@ ap.use_backend(back)
MY_PERSON = ap.Person(**ME) MY_PERSON = ap.Person(**ME)
def jsonify(**data):
if "@context" not in data:
data["@context"] = config.DEFAULT_CTX
return Response(
response=json.dumps(data),
headers={
"Content-Type": "application/json"
if app.debug
else "application/activity+json"
},
)
def is_api_request():
h = request.headers.get("Accept")
if h is None:
return False
h = h.split(",")[0]
if h in config.HEADERS or h == "application/json":
return True
return False
def add_response_headers(headers={}): def add_response_headers(headers={}):
"""This decorator adds the headers passed in to the response""" """This decorator adds the headers passed in to the response"""