def api_follow() -> _Response: actor = _user_api_arg("actor") q = { "box": Box.OUTBOX.value, "type": ap.ActivityType.FOLLOW.value, "meta.undo": False, "activity.object": actor, } existing = DB.activities.find_one(q) if existing: return _user_api_response(activity=existing["activity"]["id"]) follow = ap.Follow( actor=MY_PERSON.id, object=actor, to=[actor], cc=[ap.AS_PUBLIC], published=now(), context=new_context(), ) follow_id = post_to_outbox(follow) return _user_api_response(activity=follow_id)
def authorize_follow(): if request.method == "GET": return htmlify( render_template("authorize_remote_follow.html", profile=request.args.get("profile"))) csrf.protect() 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")
def follow(username_or_id): """ Follow an account. --- tags: - Accounts parameters: - name: id in: query type: integer required: true description: User ID to follow responses: 200: description: Returns Relationship schema: $ref: '#/definitions/Relationship' """ current_user = current_token.user if not current_user: abort(400) user = User.query.filter(User.name == username_or_id, User.local.is_(True)).first() if not user: try: user = User.query.filter(User.flake_id == username_or_id).first() except sqlalchemy.exc.DataError: abort(404) if not user: abort(404) actor_me = current_user.actor[0] actor_them = user.actor[0] if user.local: actor_me.follow(None, actor_them) return jsonify([to_json_relationship(current_user, user)]) else: # We need to initiate a follow request # Check if not already following rel = Follower.query.filter( Follower.actor_id == actor_me.id, Follower.target_id == actor_them.id).first() if not rel: # Initiate a Follow request from actor_me to actor_target follow = ap.Follow(actor=actor_me.url, object=actor_them.url) post_to_outbox(follow) return jsonify(""), 202 else: return jsonify({"error": "already following"}), 409
def follow(): user = request.args.get("user") actor_me = current_user.actor[0] if user.startswith("https://"): actor = Actor.query.filter(Actor.url == user).first() if actor: local_user = actor.user else: local_user = None else: local_user = User.query.filter(User.name == user).first() if local_user: # Process local follow actor_me.follow(None, local_user.actor[0]) flash(gettext("Follow successful"), "success") else: # Might be a remote follow # 1. Webfinger the user try: remote_actor_url = get_actor_url(user, debug=current_app.debug) except InvalidURLError: current_app.logger.exception(f"Invalid webfinger URL: {user}") remote_actor_url = None # except requests.exceptions.HTTPError: # current_app.logger.exception(f"Invali webfinger URL: {user}") # remote_actor_url = None if not remote_actor_url: flash(gettext("User not found"), "error") return redirect(url_for("bp_users.profile", name=current_user.name)) # 2. Check if we have a local user actor_target = Actor.query.filter( Actor.url == remote_actor_url).first() if not actor_target: # 2.5 Fetch and save remote actor backend = ap.get_backend() iri = backend.fetch_iri(remote_actor_url) if not iri: flash(gettext("User not found"), "error") return redirect(url_for("bp_main.home")) act = ap.parse_activity(iri) actor_target, user_target = create_remote_actor(act) db.session.add(user_target) db.session.add(actor_target) # 2.7 Check if we already have a relation rel = Follower.query.filter( Follower.actor_id == actor_me.id, Follower.target_id == actor_target.id).first() if not rel: # 3. Initiate a Follow request from actor_me to actor_target follow = ap.Follow(actor=actor_me.url, object=actor_target.url) post_to_outbox(follow) flash(gettext("Follow request have been transmitted"), "success") else: flash(gettext("You already follow this user", "info")) return redirect(url_for("bp_users.profile", name=current_user.name))