From 760eb72a382b36d37e8fed3a9c0e48360ec65f8d Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 26 May 2018 18:03:23 +0000 Subject: [PATCH] add a bunch of stuff --- .../web/activity_pub/transmogrifier.ex | 21 ++++++++++++++++ lib/pleroma/web/activity_pub/utils.ex | 20 ++++++++++++++-- .../mastodon_api/mastodon_api_controller.ex | 24 ++++++++++++++++--- lib/pleroma/web/router.ex | 2 ++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index ab744f6a2..0ebb49dc0 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -434,6 +434,27 @@ def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = obj {:ok, data} end + # Mastodon Accept/Reject requires a non-normalized object containing the actor URIs, + # because of course it does. + def prepare_outgoing(%{"type" => "Accept"} = data) do + with follow_activity <- Activity.get_by_ap_id(data["object"]) do + object = %{ + "actor" => follow_activity.actor, + "object" => follow_activity.data["object"], + "id" => follow_activity.data["id"], + "type" => "Follow" + } + + data = + data + |> Map.put("object", object) + + IO.inspect(data) + + {:ok, data} + end + end + def prepare_outgoing(%{"type" => _type} = data) do data = data diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 3229949c0..6ce954cd0 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -4,6 +4,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do alias Pleroma.Web.Endpoint alias Ecto.{Changeset, UUID} import Ecto.Query + require Logger # Some implementations send the actor URI as the actor field, others send the entire actor object, # so figure out what the actor's URI is based on what we have. @@ -216,6 +217,19 @@ def remove_like_from_object(%Activity{data: %{"actor" => actor}}, object) do #### Follow-related helpers + @doc """ + Updates a follow activity's state (for locked accounts). + """ + def update_follow_state(%Activity{} = activity, state) do + with new_data <- + activity.data + |> Map.put("state", state), + changeset <- Changeset.change(activity, data: new_data), + {:ok, activity} <- Repo.update(changeset) do + {:ok, activity} + end + end + @doc """ Makes a follow activity data for the given follower and followed """ @@ -228,8 +242,10 @@ def make_follow_data(%User{ap_id: follower_id}, %User{ap_id: followed_id} = foll "object" => followed_id } - if activity_id, do: Map.put(data, "id", activity_id), else: data - if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data + data = if activity_id, do: Map.put(data, "id", activity_id), else: data + data = if User.locked?(followed), do: Map.put(data, "state", "pending"), else: data + + data end def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 90b0da8da..cae81c43d 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -487,9 +487,10 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id} with %User{} = follower <- Repo.get(User, id), {:ok, follower} <- User.follow(follower, followed), %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "accept"), {:ok, _activity} <- ActivityPub.accept(%{ - to: follower.ap_id, + to: [follower.ap_id], actor: followed.ap_id, object: follow_activity.data["id"], type: "Accept" @@ -503,8 +504,25 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id} end end - # def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do - # end + def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do + with %User{} = follower <- Repo.get(User, id), + %Activity{} = follow_activity <- Utils.fetch_latest_follow(follower, followed), + {:ok, follow_activity} <- Utils.update_follow_state(follow_activity, "reject"), + {:ok, _activity} <- + ActivityPub.reject(%{ + to: [follower.ap_id], + actor: followed.ap_id, + object: follow_activity.data["id"], + type: "Reject" + }) do + render(conn, AccountView, "relationship.json", %{user: followed, target: follower}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do with %User{} = followed <- Repo.get(User, id), diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index e517510b8..b37c8168f 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -98,6 +98,8 @@ def user_fetcher(username) do post("/accounts/:id/unmute", MastodonAPIController, :relationship_noop) get("/follow_requests", MastodonAPIController, :follow_requests) + post("/follow_requests/:id/authorize", MastodonAPIController, :authorize_follow_request) + post("/follow_requests/:id/reject", MastodonAPIController, :reject_follow_request) post("/follows", MastodonAPIController, :follow)