Clean up account aliases

This commit is contained in:
Alex Gleason 2020-08-07 16:48:03 -05:00
commit 4af1b80381
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
17 changed files with 47 additions and 222 deletions

View file

@ -96,7 +96,6 @@ 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)
@ -486,6 +485,7 @@ defmodule Pleroma.User do
:hide_follows_count,
:hide_favorites,
:allow_following_move,
:also_known_as,
:background,
:show_role,
:skip_thread_containment,
@ -494,12 +494,12 @@ defmodule Pleroma.User do
:pleroma_settings_store,
:discoverable,
:actor_type,
:also_known_as,
:accepts_chat_messages
]
)
|> unique_constraint(:nickname)
|> validate_format(:nickname, local_nickname_regex())
|> validate_also_known_as()
|> validate_length(:bio, max: bio_limit)
|> validate_length(:name, min: 1, max: name_limit)
|> validate_inclusion(:actor_type, ["Person", "Service"])
@ -2387,36 +2387,11 @@ defmodule Pleroma.User do
|> 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})
|> validate_ap_aliases()
|> 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})
|> validate_ap_aliases()
|> Repo.update()
end
defp validate_ap_aliases(changeset) do
validate_change(changeset, :ap_aliases, fn :ap_aliases, ap_aliases ->
case Enum.all?(ap_aliases, fn a -> Regex.match?(@url_regex, a) end) do
defp validate_also_known_as(changeset) do
validate_change(changeset, :also_known_as, fn :also_known_as, also_known_as ->
case Enum.all?(also_known_as, fn a -> Regex.match?(@url_regex, a) end) do
true -> []
false -> [ap_aliases: "Invalid ap_id format. Must be a URL."]
false -> [also_known_as: "Invalid ap_id format. Must be a URL."]
end
end)
end

View file

@ -597,6 +597,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
nullable: true,
description: "Allows automatically follow moved following accounts"
},
also_known_as: %Schema{
type: :array,
items: %Schema{type: :string},
nullable: true,
description: "List of alternate ActivityPub IDs"
},
pleroma_background_image: %Schema{
type: :string,
nullable: true,
@ -627,6 +633,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
skip_thread_containment: false,
allow_following_move: false,
also_known_as: ["https://foo.bar/users/foo"],
discoverable: false,
actor_type: "Person"
}

View file

@ -4,8 +4,6 @@
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
@ -89,54 +87,10 @@ 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

View file

@ -41,7 +41,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do
type: :object,
properties: %{
ap_id: %Schema{type: :string},
ap_aliases: %Schema{type: :array, items: %Schema{type: :string}},
also_known_as: %Schema{type: :array, items: %Schema{type: :string}},
allow_following_move: %Schema{
type: :boolean,
description: "whether the user allows automatically follow moved following accounts"

View file

@ -186,6 +186,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
:show_role,
:skip_thread_containment,
:allow_following_move,
:also_known_as,
:discoverable,
:accepts_chat_messages
]
@ -210,6 +211,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
if bot, do: {:ok, "Service"}, else: {:ok, "Person"}
end)
|> Maps.put_if_present(:actor_type, params[:actor_type])
|> Maps.put_if_present(:also_known_as, params[:also_known_as])
# What happens here:
#

View file

@ -267,7 +267,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
# Pleroma extension
pleroma: %{
ap_id: user.ap_id,
ap_aliases: user.ap_aliases,
also_known_as: user.also_known_as,
confirmation_pending: user.confirmation_pending,
tags: user.tags,
hide_followers_count: user.hide_followers_count,

View file

@ -39,11 +39,6 @@ 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])
@ -112,24 +107,4 @@ 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

View file

@ -345,9 +345,6 @@ 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)

View file

@ -59,10 +59,7 @@ defmodule Pleroma.Web.WebFinger do
end
defp gather_aliases(%User{} = user) do
user.ap_aliases
|> MapSet.new()
|> MapSet.put(user.ap_id)
|> MapSet.to_list()
[user.ap_id] ++ user.also_known_as
end
def represent_user(user, "JSON") do
@ -78,6 +75,10 @@ defmodule Pleroma.Web.WebFinger do
def represent_user(user, "XML") do
{:ok, user} = User.ensure_keys_present(user)
aliases =
gather_aliases(user)
|> Enum.map(fn the_alias -> {:Alias, the_alias} end)
links =
gather_links(user)
|> Enum.map(fn link -> {:Link, link} end)
@ -86,9 +87,8 @@ defmodule Pleroma.Web.WebFinger do
:XRD,
%{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
[
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"},
{:Alias, user.ap_id}
] ++ links
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"}
] ++ aliases ++ links
}
|> XmlBuilder.to_doc()
end