diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/user.ex | 24 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex | 46 | ||||
-rw-r--r-- | lib/pleroma/web/api_spec/schemas/account.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/account_view.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/web/pleroma_api/controllers/account_controller.ex | 25 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/web/web_finger/web_finger.ex | 9 |
7 files changed, 109 insertions, 1 deletions
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 9240e912d..9b756c9a0 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -89,6 +89,7 @@ defmodule Pleroma.User do field(:keys, :string) field(:public_key, :string) field(:ap_id, :string) + field(:ap_aliases, {:array, :string}, default: []) field(:avatar, :map, default: %{}) field(:local, :boolean, default: true) field(:follower_address, :string) @@ -2268,4 +2269,27 @@ defmodule Pleroma.User do |> Map.put(:bio, HTML.filter_tags(user.bio, filter)) |> Map.put(:fields, fields) end + + def add_aliases(%User{} = user, aliases) when is_list(aliases) do + alias_set = + (user.ap_aliases ++ aliases) + |> MapSet.new() + |> MapSet.to_list() + + user + |> change(%{ap_aliases: alias_set}) + |> Repo.update() + end + + def delete_aliases(%User{} = user, aliases) when is_list(aliases) do + alias_set = + user.ap_aliases + |> MapSet.new() + |> MapSet.difference(MapSet.new(aliases)) + |> MapSet.to_list() + + user + |> change(%{ap_aliases: alias_set}) + |> Repo.update() + end end diff --git a/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex index 97836b2eb..1040f6e20 100644 --- a/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex @@ -4,6 +4,8 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do alias OpenApiSpex.Operation + alias OpenApiSpex.Schema + alias Pleroma.Web.ApiSpec.Schemas.Account alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship alias Pleroma.Web.ApiSpec.Schemas.ApiError alias Pleroma.Web.ApiSpec.Schemas.FlakeID @@ -87,10 +89,54 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do } end + def add_aliases_operation do + %Operation{ + tags: ["Accounts"], + summary: "Add ActivityPub aliases", + operationId: "PleromaAPI.AccountController.add_aliases", + requestBody: request_body("Parameters", alias_request(), required: true), + security: [%{"oAuth" => ["write:accounts"]}], + responses: %{ + 200 => Operation.response("Account", "application/json", Account), + 403 => Operation.response("Forbidden", "application/json", ApiError) + } + } + end + + def delete_aliases_operation do + %Operation{ + tags: ["Accounts"], + summary: "Delete ActivityPub aliases", + operationId: "PleromaAPI.AccountController.delete_aliases", + requestBody: request_body("Parameters", alias_request(), required: true), + security: [%{"oAuth" => ["write:accounts"]}], + responses: %{ + 200 => Operation.response("Account", "application/json", Account) + } + } + end + defp id_param do Operation.parameter(:id, :path, FlakeID, "Account ID", example: "9umDrYheeY451cQnEe", required: true ) end + + defp alias_request do + %Schema{ + title: "AccountAliasRequest", + description: "POST body for adding/deleting AP aliases", + type: :object, + properties: %{ + aliases: %Schema{ + type: :array, + items: %Schema{type: :string} + } + }, + example: %{ + "aliases" => ["https://beepboop.social/users/beep", "https://mushroom.kingdom/users/toad"] + } + } + end end diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index ca79f0747..4fd27edf5 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -40,6 +40,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do pleroma: %Schema{ type: :object, properties: %{ + ap_id: %Schema{type: :string}, + ap_aliases: %Schema{type: :array, items: %Schema{type: :string}}, allow_following_move: %Schema{ type: :boolean, description: "whether the user allows automatically follow moved following accounts" diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index bc9745044..e2912031a 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -248,6 +248,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do # Pleroma extension pleroma: %{ ap_id: user.ap_id, + ap_aliases: user.ap_aliases, confirmation_pending: user.confirmation_pending, tags: user.tags, hide_followers_count: user.hide_followers_count, diff --git a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex index 563edded7..03e5781a3 100644 --- a/lib/pleroma/web/pleroma_api/controllers/account_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/account_controller.ex @@ -39,6 +39,11 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do %{scopes: ["read:favourites"], fallback: :proceed_unauthenticated} when action == :favourites ) + plug( + OAuthScopesPlug, + %{scopes: ["write:accounts"]} when action in [:add_aliases, :delete_aliases] + ) + plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend) plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe]) @@ -107,4 +112,24 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do {:error, message} -> json_response(conn, :forbidden, %{error: message}) end end + + @doc "POST /api/v1/pleroma/accounts/ap_aliases" + def add_aliases(%{assigns: %{user: user}, body_params: %{aliases: aliases}} = conn, _params) + when is_list(aliases) do + with {:ok, user} <- User.add_aliases(user, aliases) do + render(conn, "show.json", user: user) + else + {:error, message} -> json_response(conn, :forbidden, %{error: message}) + end + end + + @doc "DELETE /api/v1/pleroma/accounts/ap_aliases" + def delete_aliases(%{assigns: %{user: user}, body_params: %{aliases: aliases}} = conn, _params) + when is_list(aliases) do + with {:ok, user} <- User.delete_aliases(user, aliases) do + render(conn, "show.json", user: user) + else + {:error, message} -> json_response(conn, :forbidden, %{error: message}) + end + end end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 386308362..dea95cd77 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -344,6 +344,9 @@ defmodule Pleroma.Web.Router do post("/accounts/:id/subscribe", AccountController, :subscribe) post("/accounts/:id/unsubscribe", AccountController, :unsubscribe) + + post("/accounts/ap_aliases", AccountController, :add_aliases) + delete("/accounts/ap_aliases", AccountController, :delete_aliases) end post("/accounts/confirmation_resend", AccountController, :confirmation_resend) diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 71ccf251a..fb142ce8d 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -58,12 +58,19 @@ defmodule Pleroma.Web.WebFinger do ] ++ Publisher.gather_webfinger_links(user) end + defp gather_aliases(%User{} = user) do + user.ap_aliases + |> MapSet.new() + |> MapSet.put(user.ap_id) + |> MapSet.to_list() + end + def represent_user(user, "JSON") do {:ok, user} = User.ensure_keys_present(user) %{ "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", - "aliases" => [user.ap_id], + "aliases" => gather_aliases(user), "links" => gather_links(user) } end |