X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fweb%2Factivity_pub%2Factivity_pub_controller.ex;h=2cdf132e2dc998520548ed70d654ca1881ee36f9;hb=98ec578f4d36ff1a94ee59087f57704ed109bd9c;hp=3570a75cb37f623d3424a336c5ad830e1eaae858;hpb=fe2759bc9f2dad044b49f4954693ac09f9368041;p=akkoma diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index 3570a75cb..2cdf132e2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -1,10 +1,16 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + defmodule Pleroma.Web.ActivityPub.ActivityPubController do use Pleroma.Web, :controller - alias Pleroma.{User, Object} + + alias Pleroma.{Activity, User, Object} alias Pleroma.Web.ActivityPub.{ObjectView, UserView} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.ActivityPub.Transmogrifier alias Pleroma.Web.Federator require Logger @@ -12,6 +18,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do action_fallback(:errors) plug(Pleroma.Web.FederatingPlug when action in [:inbox, :relay]) + plug(:set_requester_reachable when action in [:inbox]) plug(:relay_active? when action in [:relay]) def relay_active?(conn, _) do @@ -49,6 +56,49 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def object_likes(conn, %{"uuid" => uuid, "page" => page}) do + with ap_id <- o_status_url(conn, :object, uuid), + %Object{} = object <- Object.get_cached_by_ap_id(ap_id), + {_, true} <- {:public?, ActivityPub.is_public?(object)}, + likes <- Utils.get_object_likes(object) do + {page, _} = Integer.parse(page) + + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(ObjectView.render("likes.json", ap_id, likes, page)) + else + {:public?, false} -> + {:error, :not_found} + end + end + + def object_likes(conn, %{"uuid" => uuid}) do + with ap_id <- o_status_url(conn, :object, uuid), + %Object{} = object <- Object.get_cached_by_ap_id(ap_id), + {_, true} <- {:public?, ActivityPub.is_public?(object)}, + likes <- Utils.get_object_likes(object) do + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(ObjectView.render("likes.json", ap_id, likes)) + else + {:public?, false} -> + {:error, :not_found} + end + end + + def activity(conn, %{"uuid" => uuid}) do + with ap_id <- o_status_url(conn, :activity, uuid), + %Activity{} = activity <- Activity.normalize(ap_id), + {_, true} <- {:public?, ActivityPub.is_public?(activity)} do + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(ObjectView.render("object.json", %{object: activity})) + else + {:public?, false} -> + {:error, :not_found} + end + end + def following(conn, %{"nickname" => nickname, "page" => page}) do with %User{} = user <- User.get_cached_by_nickname(nickname), {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do @@ -89,19 +139,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end - def outbox(conn, %{"nickname" => nickname, "max_id" => max_id}) do + def outbox(conn, %{"nickname" => nickname} = params) do with %User{} = user <- User.get_cached_by_nickname(nickname), {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do conn |> put_resp_header("content-type", "application/activity+json") - |> json(UserView.render("outbox.json", %{user: user, max_id: max_id})) + |> json(UserView.render("outbox.json", %{user: user, max_id: params["max_id"]})) end end - def outbox(conn, %{"nickname" => nickname}) do - outbox(conn, %{"nickname" => nickname, "max_id" => nil}) - end - def inbox(%{assigns: %{valid_signature: true}} = conn, %{"nickname" => nickname} = params) do with %User{} = user <- User.get_cached_by_nickname(nickname), true <- Utils.recipient_in_message(user.ap_id, params), @@ -141,7 +187,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do json(conn, "error") end - def relay(conn, params) do + def relay(conn, _params) do with %User{} = user <- Relay.get_actor(), {:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do conn @@ -152,6 +198,96 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(UserView.render("user.json", %{user: user})) + end + + def whoami(_conn, _params), do: {:error, :not_found} + + def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do + if nickname == user.nickname do + conn + |> put_resp_header("content-type", "application/activity+json") + |> json(UserView.render("inbox.json", %{user: user, max_id: params["max_id"]})) + else + conn + |> put_status(:forbidden) + |> json("can't read inbox of #{nickname} as #{user.nickname}") + end + end + + def handle_user_activity(user, %{"type" => "Create"} = params) do + object = + params["object"] + |> Map.merge(Map.take(params, ["to", "cc"])) + |> Map.put("attributedTo", user.ap_id()) + |> Transmogrifier.fix_object() + + ActivityPub.create(%{ + to: params["to"], + actor: user, + context: object["context"], + object: object, + additional: Map.take(params, ["cc"]) + }) + end + + def handle_user_activity(user, %{"type" => "Delete"} = params) do + with %Object{} = object <- Object.normalize(params["object"]), + true <- user.info.is_moderator || user.ap_id == object.data["actor"], + {:ok, delete} <- ActivityPub.delete(object) do + {:ok, delete} + else + _ -> {:error, "Can't delete object"} + end + end + + def handle_user_activity(user, %{"type" => "Like"} = params) do + with %Object{} = object <- Object.normalize(params["object"]), + {:ok, activity, _object} <- ActivityPub.like(user, object) do + {:ok, activity} + else + _ -> {:error, "Can't like object"} + end + end + + def handle_user_activity(_, _) do + {:error, "Unhandled activity type"} + end + + def update_outbox( + %{assigns: %{user: user}} = conn, + %{"nickname" => nickname} = params + ) do + if nickname == user.nickname do + actor = user.ap_id() + + params = + params + |> Map.drop(["id"]) + |> Map.put("actor", actor) + |> Transmogrifier.fix_addressing() + + with {:ok, %Activity{} = activity} <- handle_user_activity(user, params) do + conn + |> put_status(:created) + |> put_resp_header("location", activity.data["id"]) + |> json(activity.data) + else + {:error, message} -> + conn + |> put_status(:bad_request) + |> json(message) + end + else + conn + |> put_status(:forbidden) + |> json("can't update outbox of #{nickname} as #{user.nickname}") + end + end + def errors(conn, {:error, :not_found}) do conn |> put_status(404) @@ -163,4 +299,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do |> put_status(500) |> json("error") end + + defp set_requester_reachable(%Plug.Conn{} = conn, _) do + with actor <- conn.params["actor"], + true <- is_binary(actor) do + Pleroma.Instances.set_reachable(actor) + end + + conn + end end