{: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
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.
#### 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
"""
"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
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"
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),
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)