diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/notification.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 49 | ||||
-rw-r--r-- | lib/pleroma/user/info.ex | 17 | ||||
-rw-r--r-- | lib/pleroma/web/common_api/utils.ex | 19 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 28 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 3 |
7 files changed, 118 insertions, 0 deletions
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 14de1a097..15789907a 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -142,6 +142,7 @@ defmodule Pleroma.Notification do [] |> Utils.maybe_notify_to_recipients(activity) |> Utils.maybe_notify_mentioned_recipients(activity) + |> Utils.maybe_notify_subscribers(activity) |> Enum.uniq() User.get_users_from_set(recipients, local_only) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index ed23b8ef0..6e2269aff 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -931,6 +931,38 @@ defmodule Pleroma.User do update_and_set_cache(cng) end + def subscribe(subscriber, %{ap_id: ap_id}) do + deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked]) + + with %User{} = subscribed <- get_cached_by_ap_id(ap_id) do + blocked = blocks?(subscribed, subscriber) and deny_follow_blocked + + if blocked do + {:error, "Could not subscribe: #{subscribed.nickname} is blocking you"} + else + info_cng = + subscribed.info + |> User.Info.add_to_subscribers(subscriber.ap_id) + + change(subscribed) + |> put_embed(:info, info_cng) + |> update_and_set_cache() + end + end + end + + def unsubscribe(unsubscriber, %{ap_id: ap_id}) do + with %User{} = user <- get_cached_by_ap_id(ap_id) do + info_cng = + user.info + |> User.Info.remove_from_subscribers(unsubscriber.ap_id) + + change(user) + |> put_embed(:info, info_cng) + |> update_and_set_cache() + end + end + def block(blocker, %User{ap_id: ap_id} = blocked) do # sever any follow relationships to prevent leaks per activitypub (Pleroma issue #213) blocker = @@ -941,6 +973,14 @@ defmodule Pleroma.User do blocker end + blocker = + if subscribed_to?(blocked, blocker) do + {:ok, blocker} = unsubscribe(blocked, blocker) + blocker + else + blocker + end + if following?(blocked, blocker) do unfollow(blocked, blocker) end @@ -989,12 +1029,21 @@ defmodule Pleroma.User do end) end + def subscribed_to?(user, %{ap_id: ap_id}) do + with %User{} = target <- User.get_by_ap_id(ap_id) do + Enum.member?(target.info.subscribers, user.ap_id) + end + end + def muted_users(user), do: Repo.all(from(u in User, where: u.ap_id in ^user.info.mutes)) def blocked_users(user), do: Repo.all(from(u in User, where: u.ap_id in ^user.info.blocks)) + def subscribers(user), + do: Repo.all(from(u in User, where: u.ap_id in ^user.info.subscribers)) + def block_domain(user, domain) do info_cng = user.info diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 33fd77b02..5afa7988c 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -22,6 +22,7 @@ defmodule Pleroma.User.Info do field(:domain_blocks, {:array, :string}, default: []) field(:mutes, {:array, :string}, default: []) field(:muted_reblogs, {:array, :string}, default: []) + field(:subscribers, {:array, :string}, default: []) field(:deactivated, :boolean, default: false) field(:no_rich_text, :boolean, default: false) field(:ap_enabled, :boolean, default: false) @@ -110,6 +111,14 @@ defmodule Pleroma.User.Info do |> validate_required([:blocks]) end + def set_subscribers(info, subscribers) do + params = %{subscribers: subscribers} + + info + |> cast(params, [:subscribers]) + |> validate_required([:subscribers]) + end + def add_to_mutes(info, muted) do set_mutes(info, Enum.uniq([muted | info.mutes])) end @@ -126,6 +135,14 @@ defmodule Pleroma.User.Info do set_blocks(info, List.delete(info.blocks, blocked)) end + def add_to_subscribers(info, subscribed) do + set_subscribers(info, Enum.uniq([subscribed | info.subscribers])) + end + + def remove_from_subscribers(info, subscribed) do + set_subscribers(info, List.delete(info.subscribers, subscribed)) + end + def set_domain_blocks(info, domain_blocks) do params = %{domain_blocks: domain_blocks} diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 051db6c79..7b9f0ea06 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -12,6 +12,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.Endpoint alias Pleroma.Web.MediaProxy @@ -335,6 +336,24 @@ defmodule Pleroma.Web.CommonAPI.Utils do def maybe_notify_mentioned_recipients(recipients, _), do: recipients + def maybe_notify_subscribers( + recipients, + %Activity{data: %{"actor" => actor, "type" => type}} = activity + ) + when type == "Create" do + with %User{} = user <- User.get_cached_by_ap_id(actor) do + subscriber_ids = + user + |> User.subscribers() + |> Enum.filter(&Visibility.visible_for_user?(activity, &1)) + |> Enum.map(& &1.ap_id) + + recipients ++ subscriber_ids + end + end + + def maybe_notify_subscribers(recipients, _), do: recipients + def maybe_extract_mentions(%{"tag" => tag}) do tag |> Enum.filter(fn x -> is_map(x) end) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index 5462ce8be..ed082abdf 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -931,6 +931,34 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do json(conn, %{}) end + def subscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %User{} = subscription_target <- User.get_cached_by_id(id), + {:ok, subscription_target} = User.subscribe(user, subscription_target) do + conn + |> put_view(AccountView) + |> render("relationship.json", %{user: user, target: subscription_target}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end + + def unsubscribe(%{assigns: %{user: user}} = conn, %{"id" => id}) do + with %User{} = subscription_target <- User.get_cached_by_id(id), + {:ok, subscription_target} = User.unsubscribe(user, subscription_target) do + conn + |> put_view(AccountView) + |> render("relationship.json", %{user: user, target: subscription_target}) + else + {:error, message} -> + conn + |> put_resp_content_type("application/json") + |> send_resp(403, Jason.encode!(%{"error" => message})) + end + end + def status_search(user, query) do fetched = if Regex.match?(~r/https?:/, query) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 25899e491..af56c4149 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -53,6 +53,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do blocking: User.blocks?(user, target), muting: User.mutes?(user, target), muting_notifications: false, + subscribing: User.subscribed_to?(user, target), requested: requested, domain_blocking: false, showing_reblogs: User.showing_reblogs?(user, target), diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 66db5e628..06c8d7a03 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -337,6 +337,9 @@ defmodule Pleroma.Web.Router do post("/domain_blocks", MastodonAPIController, :block_domain) delete("/domain_blocks", MastodonAPIController, :unblock_domain) + + post("/pleroma/accounts/:id/subscribe", MastodonAPIController, :subscribe) + post("/pleroma/accounts/:id/unsubscribe", MastodonAPIController, :unsubscribe) end scope [] do |