diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 26bb17377..1a5c07c8a 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -116,8 +116,8 @@ def add_user_links({subs, text}, mentions) do
subs ++
Enum.map(mentions, fn {match, %User{ap_id: ap_id, info: info}, uuid} ->
ap_id =
- if is_binary(info["source_data"]["url"]) do
- info["source_data"]["url"]
+ if is_binary(info.source_data["url"]) do
+ info.source_data["url"]
else
ap_id
end
diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex
index 0380ce14d..630f15eec 100644
--- a/lib/pleroma/plugs/oauth_plug.ex
+++ b/lib/pleroma/plugs/oauth_plug.ex
@@ -20,7 +20,7 @@ def call(conn, _) do
with token when not is_nil(token) <- token,
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
%User{} = user <- Repo.get(User, user_id),
- false <- !!user.info["deactivated"] do
+ false <- !!user.info.deactivated do
conn
|> assign(:user, user)
else
diff --git a/lib/pleroma/plugs/user_enabled_plug.ex b/lib/pleroma/plugs/user_enabled_plug.ex
index 9c3285896..01482f47d 100644
--- a/lib/pleroma/plugs/user_enabled_plug.ex
+++ b/lib/pleroma/plugs/user_enabled_plug.ex
@@ -6,7 +6,7 @@ def init(options) do
options
end
- def call(%{assigns: %{user: %User{info: %{"deactivated" => true}}}} = conn, _) do
+ def call(%{assigns: %{user: %User{info: %{deactivated: true}}}} = conn, _) do
conn
|> assign(:user, nil)
end
diff --git a/lib/pleroma/plugs/user_is_admin_plug.ex b/lib/pleroma/plugs/user_is_admin_plug.ex
index 5312f1499..cf22ce5d0 100644
--- a/lib/pleroma/plugs/user_is_admin_plug.ex
+++ b/lib/pleroma/plugs/user_is_admin_plug.ex
@@ -6,7 +6,7 @@ def init(options) do
options
end
- def call(%{assigns: %{user: %User{info: %{"is_admin" => true}}}} = conn, _) do
+ def call(%{assigns: %{user: %User{info: %{is_admin: true}}}} = conn, _) do
conn
end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 6e1d5559d..76712b4bf 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -19,11 +19,11 @@ defmodule Pleroma.User do
field(:ap_id, :string)
field(:avatar, :map)
field(:local, :boolean, default: true)
- field(:info, :map, default: %{})
field(:follower_address, :string)
field(:search_distance, :float, virtual: true)
field(:last_refreshed_at, :naive_datetime)
has_many(:notifications, Notification)
+ embeds_one(:info, Pleroma.User.Info)
timestamps()
end
@@ -36,13 +36,13 @@ def avatar_url(user) do
end
def banner_url(user) do
- case user.info["banner"] do
+ case user.info.banner do
%{"url" => [%{"href" => href} | _]} -> href
_ -> "#{Web.base_url()}/images/banner.png"
end
end
- def profile_url(%User{info: %{"source_data" => %{"url" => url}}}), do: url
+ def profile_url(%User{info: %{source_data: %{"url" => url}}}), do: url
def profile_url(%User{ap_id: ap_id}), do: ap_id
def profile_url(_), do: nil
@@ -61,9 +61,7 @@ def follow_changeset(struct, params \\ %{}) do
end
def info_changeset(struct, params \\ %{}) do
- struct
- |> cast(params, [:info])
- |> validate_required([:info])
+ raise "NOT VALID ANYMORE"
end
def user_info(%User{} = user) do
@@ -71,27 +69,34 @@ def user_info(%User{} = user) do
%{
following_count: length(user.following) - oneself,
- note_count: user.info["note_count"] || 0,
- follower_count: user.info["follower_count"] || 0,
- locked: user.info["locked"] || false,
- default_scope: user.info["default_scope"] || "public"
+ note_count: user.info.note_count,
+ follower_count: user.info.follower_count,
+ locked: user.info.locked,
+ default_scope: user.info.default_scope
}
end
@email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
def remote_user_creation(params) do
+ params =
+ params
+ |> Map.put(:info, params[:info] || %{})
+
+ info_cng = User.Info.remote_user_creation(%User.Info{}, params[:info])
+
changes =
%User{}
- |> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar])
+ |> cast(params, [:bio, :name, :ap_id, :nickname, :avatar])
|> validate_required([:name, :ap_id])
|> unique_constraint(:nickname)
|> validate_format(:nickname, @email_regex)
|> validate_length(:bio, max: 5000)
|> validate_length(:name, max: 100)
|> put_change(:local, false)
+ |> put_embed(:info, info_cng)
if changes.valid? do
- case changes.changes[:info]["source_data"] do
+ case info_cng.changes[:source_data] do
%{"followers" => followers} ->
changes
|> put_change(:follower_address, followers)
@@ -109,7 +114,7 @@ def remote_user_creation(params) do
def update_changeset(struct, params \\ %{}) do
struct
- |> cast(params, [:bio, :name])
+ |> cast(params, [:bio, :name, :avatar])
|> unique_constraint(:nickname)
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|> validate_length(:bio, max: 5000)
@@ -121,12 +126,17 @@ def upgrade_changeset(struct, params \\ %{}) do
params
|> Map.put(:last_refreshed_at, NaiveDateTime.utc_now())
+ info_cng =
+ struct.info
+ |> User.Info.user_upgrade(params[:info])
+
struct
- |> cast(params, [:bio, :name, :info, :follower_address, :avatar, :last_refreshed_at])
+ |> cast(params, [:bio, :name, :follower_address, :avatar, :last_refreshed_at])
|> unique_constraint(:nickname)
|> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
|> validate_length(:bio, max: 5000)
|> validate_length(:name, max: 100)
+ |> put_embed(:info, info_cng)
end
def password_update_changeset(struct, params) do
@@ -191,7 +201,7 @@ def needs_update?(%User{local: false} = user) do
def needs_update?(_), do: true
- def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{"locked" => true}}) do
+ def maybe_direct_follow(%User{} = follower, %User{local: true, info: %{locked: true}}) do
{:ok, follower}
end
@@ -222,7 +232,7 @@ def follow(%User{} = follower, %User{info: info} = followed) do
ap_followers = followed.follower_address
cond do
- following?(follower, followed) or info["deactivated"] ->
+ following?(follower, followed) or info.deactivated ->
{:error, "Could not follow user: #{followed.nickname} is already on your list."}
deny_follow_blocked and blocks?(followed, follower) ->
@@ -274,7 +284,7 @@ def following?(%User{} = follower, %User{} = followed) do
end
def locked?(%User{} = user) do
- user.info["locked"] || false
+ user.info.locked || false
end
def get_by_ap_id(ap_id) do
@@ -411,22 +421,23 @@ def get_follow_requests(%User{} = user) do
end
def increase_note_count(%User{} = user) do
- note_count = (user.info["note_count"] || 0) + 1
- new_info = Map.put(user.info, "note_count", note_count)
+ info_cng = User.Info.add_to_note_count(user.info, 1)
- cs = info_changeset(user, %{info: new_info})
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
- update_and_set_cache(cs)
+ update_and_set_cache(cng)
end
def decrease_note_count(%User{} = user) do
- note_count = user.info["note_count"] || 0
- note_count = if note_count <= 0, do: 0, else: note_count - 1
- new_info = Map.put(user.info, "note_count", note_count)
+ info_cng = User.Info.add_to_note_count(user.info, -1)
- cs = info_changeset(user, %{info: new_info})
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
- update_and_set_cache(cs)
+ update_and_set_cache(cng)
end
def update_note_count(%User{} = user) do
@@ -439,11 +450,13 @@ def update_note_count(%User{} = user) do
note_count = Repo.one(note_count_query)
- new_info = Map.put(user.info, "note_count", note_count)
+ info_cng = User.Info.set_note_count(user.info, note_count)
- cs = info_changeset(user, %{info: new_info})
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
- update_and_set_cache(cs)
+ update_and_set_cache(cng)
end
def update_follower_count(%User{} = user) do
@@ -457,11 +470,15 @@ def update_follower_count(%User{} = user) do
follower_count = Repo.one(follower_count_query)
- new_info = Map.put(user.info, "follower_count", follower_count)
+ info_cng =
+ user.info
+ |> User.Info.set_follower_count(follower_count)
- cs = info_changeset(user, %{info: new_info})
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
- update_and_set_cache(cs)
+ update_and_set_cache(cng)
end
def get_users_from_set_query(ap_ids, false) do
@@ -545,12 +562,15 @@ def block(blocker, %User{ap_id: ap_id} = blocked) do
unfollow(blocked, blocker)
end
- blocks = blocker.info["blocks"] || []
- new_blocks = Enum.uniq([ap_id | blocks])
- new_info = Map.put(blocker.info, "blocks", new_blocks)
+ info_cng =
+ blocker.info
+ |> User.Info.add_to_block(ap_id)
- cs = User.info_changeset(blocker, %{info: new_info})
- update_and_set_cache(cs)
+ cng =
+ change(blocker)
+ |> put_embed(:info, info_cng)
+
+ update_and_set_cache(cng)
end
# helper to handle the block given only an actor's AP id
@@ -558,18 +578,21 @@ def block(blocker, %{ap_id: ap_id}) do
block(blocker, User.get_by_ap_id(ap_id))
end
- def unblock(user, %{ap_id: ap_id}) do
- blocks = user.info["blocks"] || []
- new_blocks = List.delete(blocks, ap_id)
- new_info = Map.put(user.info, "blocks", new_blocks)
+ def unblock(blocker, %{ap_id: ap_id}) do
+ info_cng =
+ blocker.info
+ |> User.Info.remove_from_block(ap_id)
- cs = User.info_changeset(user, %{info: new_info})
- update_and_set_cache(cs)
+ cng =
+ change(blocker)
+ |> put_embed(:info, info_cng)
+
+ update_and_set_cache(cng)
end
def blocks?(user, %{ap_id: ap_id}) do
- blocks = user.info["blocks"] || []
- domain_blocks = user.info["domain_blocks"] || []
+ blocks = user.info.blocks
+ domain_blocks = user.info.domain_blocks
%{host: host} = URI.parse(ap_id)
Enum.member?(blocks, ap_id) ||
@@ -579,21 +602,27 @@ def blocks?(user, %{ap_id: ap_id}) do
end
def block_domain(user, domain) do
- domain_blocks = user.info["domain_blocks"] || []
- new_blocks = Enum.uniq([domain | domain_blocks])
- new_info = Map.put(user.info, "domain_blocks", new_blocks)
+ info_cng =
+ user.info
+ |> User.Info.add_to_domain_block(domain)
- cs = User.info_changeset(user, %{info: new_info})
- update_and_set_cache(cs)
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
+
+ update_and_set_cache(cng)
end
def unblock_domain(user, domain) do
- blocks = user.info["domain_blocks"] || []
- new_blocks = List.delete(blocks, domain)
- new_info = Map.put(user.info, "domain_blocks", new_blocks)
+ info_cng =
+ user.info
+ |> User.Info.remove_from_domain_block(domain)
- cs = User.info_changeset(user, %{info: new_info})
- update_and_set_cache(cs)
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
+
+ update_and_set_cache(cng)
end
def local_user_query() do
@@ -613,9 +642,13 @@ def moderator_user_query() do
end
def deactivate(%User{} = user, status \\ true) do
- new_info = Map.put(user.info, "deactivated", status)
- cs = User.info_changeset(user, %{info: new_info})
- update_and_set_cache(cs)
+ info_cng = User.Info.set_activation_status(user.info, status)
+
+ cng =
+ change(user)
+ |> put_embed(:info, info_cng)
+
+ update_and_set_cache(cng)
end
def delete(%User{} = user) do
@@ -649,7 +682,7 @@ def delete(%User{} = user) do
{:ok, user}
end
- def html_filter_policy(%User{info: %{"no_rich_text" => true}}) do
+ def html_filter_policy(%User{info: %{no_rich_text: true}}) do
Pleroma.HTML.Scrubber.TwitterText
end
@@ -683,7 +716,7 @@ def get_or_create_instance_user do
user
else
changes =
- %User{}
+ %User{info: %User.Info{}}
|> cast(%{}, [:ap_id, :nickname, :local])
|> put_change(:ap_id, relay_uri)
|> put_change(:nickname, nil)
@@ -697,7 +730,7 @@ def get_or_create_instance_user do
# AP style
def public_key_from_info(%{
- "source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
+ source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
}) do
key =
:public_key.pem_decode(public_key_pem)
@@ -708,7 +741,7 @@ def public_key_from_info(%{
end
# OStatus Magic Key
- def public_key_from_info(%{"magic_key" => magic_key}) do
+ def public_key_from_info(%{magic_key: magic_key}) do
{:ok, Pleroma.Web.Salmon.decode_key(magic_key)}
end
@@ -730,11 +763,12 @@ def insert_or_update_user(data) do
|> Map.put(:name, blank?(data[:name]) || data[:nickname])
cs = User.remote_user_creation(data)
+
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
end
def ap_enabled?(%User{local: true}), do: true
- def ap_enabled?(%User{info: info}), do: info["ap_enabled"]
+ def ap_enabled?(%User{info: info}), do: info.ap_enabled
def ap_enabled?(_), do: false
def get_or_fetch(uri_or_nickname) do
diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex
new file mode 100644
index 000000000..94d403bf7
--- /dev/null
+++ b/lib/pleroma/user/info.ex
@@ -0,0 +1,164 @@
+defmodule Pleroma.User.Info do
+ use Ecto.Schema
+ import Ecto.Changeset
+
+ embedded_schema do
+ field(:banner, :map, default: %{})
+ field(:background, :string, default: nil)
+ field(:source_data, :map, default: %{})
+ field(:note_count, :integer, default: 0)
+ field(:follower_count, :integer, default: 0)
+ field(:locked, :boolean, default: false)
+ field(:default_scope, :string, default: "public")
+ field(:blocks, {:array, :string}, default: [])
+ field(:domain_blocks, {:array, :string}, default: [])
+ field(:deactivated, :boolean, default: false)
+ field(:no_rich_text, :boolean, default: false)
+ field(:ap_enabled, :boolean, default: false)
+ field(:is_moderator, :boolean, default: false)
+ field(:is_admin, :boolean, default: false)
+ field(:keys, :string, default: nil)
+ field(:settings, :map, default: nil)
+ field(:magic_key, :string, default: nil)
+ field(:uri, :string, default: nil)
+ field(:topic, :string, default: nil)
+ field(:hub, :string, default: nil)
+ field(:salmon, :string, default: nil)
+
+ # Found in the wild
+ # ap_id -> Where is this used?
+ # bio -> Where is this used?
+ # avatar -> Where is this used?
+ # fqn -> Where is this used?
+ # host -> Where is this used?
+ # subject _> Where is this used?
+ end
+
+ def set_activation_status(info, deactivated) do
+ params = %{deactivated: deactivated}
+
+ info
+ |> cast(params, [:deactivated])
+ |> validate_required([:deactivated])
+ end
+
+ def add_to_note_count(info, number) do
+ set_note_count(info, info.note_count + number)
+ end
+
+ def set_note_count(info, number) do
+ params = %{note_count: Enum.max([0, number])}
+
+ info
+ |> cast(params, [:note_count])
+ |> validate_required([:note_count])
+ end
+
+ def set_follower_count(info, number) do
+ params = %{follower_count: Enum.max([0, number])}
+
+ info
+ |> cast(params, [:follower_count])
+ |> validate_required([:follower_count])
+ end
+
+ def set_blocks(info, blocks) do
+ params = %{blocks: blocks}
+
+ info
+ |> cast(params, [:blocks])
+ |> validate_required([:blocks])
+ end
+
+ def add_to_block(info, blocked) do
+ set_blocks(info, Enum.uniq([blocked | info.blocks]))
+ end
+
+ def remove_from_block(info, blocked) do
+ set_blocks(info, List.delete(info.blocks, blocked))
+ end
+
+ def set_domain_blocks(info, domain_blocks) do
+ params = %{domain_blocks: domain_blocks}
+
+ info
+ |> cast(params, [:domain_blocks])
+ |> validate_required([:domain_blocks])
+ end
+
+ def add_to_domain_block(info, domain_blocked) do
+ set_domain_blocks(info, Enum.uniq([domain_blocked | info.domain_blocks]))
+ end
+
+ def remove_from_domain_block(info, domain_blocked) do
+ set_domain_blocks(info, List.delete(info.domain_blocks, domain_blocked))
+ end
+
+ def set_keys(info, keys) do
+ params = %{keys: keys}
+
+ info
+ |> cast(params, [:keys])
+ |> validate_required([:keys])
+ end
+
+ def remote_user_creation(info, params) do
+ info
+ |> cast(params, [
+ :ap_enabled,
+ :source_data,
+ :banner,
+ :locked,
+ :magic_key,
+ :uri,
+ :hub,
+ :topic,
+ :salmon
+ ])
+ end
+
+ def user_upgrade(info, params) do
+ info
+ |> cast(params, [
+ :ap_enabled,
+ :source_data,
+ :banner,
+ :locked,
+ :magic_key
+ ])
+ end
+
+ def profile_update(info, params) do
+ info
+ |> cast(params, [
+ :locked,
+ :no_rich_text,
+ :default_scope,
+ :banner
+ ])
+ end
+
+ def mastodon_profile_update(info, params) do
+ info
+ |> cast(params, [
+ :locked,
+ :banner
+ ])
+ end
+
+ def set_source_data(info, source_data) do
+ params = %{source_data: source_data}
+
+ info
+ |> cast(params, [:source_data])
+ |> validate_required([:source_data])
+ end
+
+ def admin_api_update(info, params) do
+ info
+ |> cast(params, [
+ :is_moderator,
+ :is_admin
+ ])
+ end
+end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 76c15cf21..7e207c620 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -42,7 +42,7 @@ defp get_recipients(data) do
defp check_actor_is_active(actor) do
if not is_nil(actor) do
with user <- User.get_cached_by_ap_id(actor),
- false <- !!user.info["deactivated"] do
+ false <- user.info.deactivated do
:ok
else
_e -> :reject
@@ -509,8 +509,8 @@ defp restrict_recent(query, _) do
end
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
- blocks = info["blocks"] || []
- domain_blocks = info["domain_blocks"] || []
+ blocks = info.blocks || []
+ domain_blocks = info.domain_blocks || []
from(
activity in query,
@@ -676,7 +676,7 @@ def publish(actor, activity) do
remote_inboxes =
(Pleroma.Web.Salmon.remote_users(activity) ++ followers)
|> Enum.filter(fn user -> User.ap_enabled?(user) end)
- |> Enum.map(fn %{info: %{"source_data" => data}} ->
+ |> Enum.map(fn %{info: %{source_data: data}} ->
(is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
end)
|> Enum.uniq()
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 5864855b0..17b063609 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -447,7 +447,7 @@ def handle_incoming(
update_data =
new_user_data
|> Map.take([:name, :bio, :avatar])
- |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner, "locked" => locked}))
+ |> Map.put(:info, %{"banner" => banner, "locked" => locked})
actor
|> User.upgrade_changeset(update_data)
@@ -850,10 +850,6 @@ defp user_upgrade_task(user) do
def upgrade_user_from_ap_id(ap_id, async \\ true) do
with %User{local: false} = user <- User.get_by_ap_id(ap_id),
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do
- data =
- data
- |> Map.put(:info, Map.merge(user.info, data[:info]))
-
already_ap = User.ap_enabled?(user)
{:ok, user} =
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index eb335813d..aaa777602 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
# the instance itself is not a Person, but instead an Application
def render("user.json", %{user: %{nickname: nil} = user}) do
{:ok, user} = WebFinger.ensure_keys_present(user)
- {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
+ {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
@@ -40,7 +40,7 @@ def render("user.json", %{user: %{nickname: nil} = user}) do
def render("user.json", %{user: user}) do
{:ok, user} = WebFinger.ensure_keys_present(user)
- {:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
+ {:ok, _, public_key} = Salmon.keys_from_pem(user.info.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
@@ -55,7 +55,7 @@ def render("user.json", %{user: user}) do
"name" => user.name,
"summary" => user.bio,
"url" => user.ap_id,
- "manuallyApprovesFollowers" => user.info["locked"] || false,
+ "manuallyApprovesFollowers" => user.info.locked,
"publicKey" => %{
"id" => "#{user.ap_id}#main-key",
"owner" => user.ap_id,
@@ -72,7 +72,7 @@ def render("user.json", %{user: user}) do
"type" => "Image",
"url" => User.banner_url(user)
},
- "tag" => user.info["source_data"]["tag"] || []
+ "tag" => user.info.source_data["tag"] || []
}
|> Map.merge(Utils.make_json_ld_header())
end
diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex
index bcdb4ba37..2c67d9cda 100644
--- a/lib/pleroma/web/admin_api/admin_api_controller.ex
+++ b/lib/pleroma/web/admin_api/admin_api_controller.ex
@@ -45,21 +45,29 @@ def right_add(conn, %{"permission_group" => permission_group, "nickname" => nick
user = User.get_by_nickname(nickname)
info =
- user.info
+ %{}
|> Map.put("is_" <> permission_group, true)
- cng = User.info_changeset(user, %{info: info})
+ info_cng = User.Info.admin_api_update(user.info, info)
+
+ cng =
+ Ecto.Changeset.change(user)
+ |> Ecto.Changeset.put_embed(:info, info_cng)
+
{:ok, user} = User.update_and_set_cache(cng)
conn
- |> json(user.info)
+ |> json(info)
end
def right_get(conn, %{"nickname" => nickname}) do
user = User.get_by_nickname(nickname)
conn
- |> json(user.info)
+ |> json(%{
+ is_moderator: user.info.is_moderator,
+ is_admin: user.info.is_admin
+ })
end
def right_add(conn, _) do
@@ -84,14 +92,19 @@ def right_delete(
user = User.get_by_nickname(nickname)
info =
- user.info
+ %{}
|> Map.put("is_" <> permission_group, false)
- cng = User.info_changeset(user, %{info: info})
+ info_cng = User.Info.admin_api_update(user.info, info)
+
+ cng =
+ Ecto.Changeset.change(user)
+ |> Ecto.Changeset.put_embed(:info, info_cng)
+
{:ok, user} = User.update_and_set_cache(cng)
conn
- |> json(user.info)
+ |> json(info)
end
end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 77e4dbbd7..e3385310f 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.CommonAPI do
def delete(activity_id, user) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
%Object{} = object <- Object.normalize(object_id),
- true <- user.info["is_moderator"] || user.ap_id == object.data["actor"],
+ true <- user.info.is_moderator || user.ap_id == object.data["actor"],
{:ok, delete} <- ActivityPub.delete(object) do
{:ok, delete}
end
@@ -135,12 +135,13 @@ def post(user, %{"status" => status} = data) do
end
end
+ # Updates the emojis for a user based on their profile
def update(user) do
user =
with emoji <- emoji_from_profile(user),
- source_data <- (user.info["source_data"] || %{}) |> Map.put("tag", emoji),
- new_info <- Map.put(user.info, "source_data", source_data),
- change <- User.info_changeset(user, %{info: new_info}),
+ source_data <- (user.info.source_data || %{}) |> Map.put("tag", emoji),
+ info_cng <- Pleroma.User.Info.set_source_data(user.info, source_data),
+ change <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
{:ok, user} <- User.update_and_set_cache(change) do
user
else
diff --git a/lib/pleroma/web/http_signatures/http_signatures.ex b/lib/pleroma/web/http_signatures/http_signatures.ex
index 5e42a871b..0e54debd5 100644
--- a/lib/pleroma/web/http_signatures/http_signatures.ex
+++ b/lib/pleroma/web/http_signatures/http_signatures.ex
@@ -65,7 +65,7 @@ def build_signing_string(headers, used_headers) do
end
def sign(user, headers) do
- with {:ok, %{info: %{"keys" => keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user),
+ with {:ok, %{info: %{keys: keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user),
{:ok, private_key, _} = Pleroma.Web.Salmon.keys_from_pem(keys) do
sigstring = build_signing_string(headers, Map.keys(headers))
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 009be50e7..d19d55044 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -32,67 +32,55 @@ def create_app(conn, params) do
end
end
+ defp add_if_present(
+ map,
+ params,
+ params_field,
+ map_field,
+ value_function \\ fn x -> {:ok, x} end
+ ) do
+ if Map.has_key?(params, params_field) do
+ case value_function.(params[params_field]) do
+ {:ok, new_value} -> Map.put(map, map_field, new_value)
+ :error -> map
+ end
+ else
+ map
+ end
+ end
+
def update_credentials(%{assigns: %{user: user}} = conn, params) do
original_user = user
- params =
- if bio = params["note"] do
- Map.put(params, "bio", bio)
- else
- params
- end
-
- params =
- if name = params["display_name"] do
- Map.put(params, "name", name)
- else
- params
- end
-
- user =
- if avatar = params["avatar"] do
- with %Plug.Upload{} <- avatar,
- {:ok, object} <- ActivityPub.upload(avatar, type: :avatar),
- change = Ecto.Changeset.change(user, %{avatar: object.data}),
- {:ok, user} = User.update_and_set_cache(change) do
- user
+ user_params =
+ %{}
+ |> add_if_present(params, "display_name", :name)
+ |> add_if_present(params, "note", :bio)
+ |> add_if_present(params, "avatar", :avatar, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :avatar) do
+ {:ok, object.data}
else
- _e -> user
+ _ -> :error
end
- else
- user
- end
+ end)
- user =
- if banner = params["header"] do
- with %Plug.Upload{} <- banner,
- {:ok, object} <- ActivityPub.upload(banner, type: :banner),
- new_info <- Map.put(user.info, "banner", object.data),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
- user
+ info_params =
+ %{}
+ |> add_if_present(params, "locked", :locked, fn value -> {:ok, value == "true"} end)
+ |> add_if_present(params, "header", :banner, fn value ->
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: :banner) do
+ {:ok, object.data}
else
- _e -> user
+ _ -> :error
end
- else
- user
- end
+ end)
- user =
- if locked = params["locked"] do
- with locked <- locked == "true",
- new_info <- Map.put(user.info, "locked", locked),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
- user
- else
- _e -> user
- end
- else
- user
- end
+ info_cng = User.Info.mastodon_profile_update(user.info, info_params)
- with changeset <- User.update_changeset(user, params),
+ with changeset <- User.update_changeset(user, user_params),
+ changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
if original_user != user do
CommonAPI.update(user)
@@ -644,7 +632,7 @@ def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
# TODO: Use proper query
def blocks(%{assigns: %{user: user}} = conn, _) do
- with blocked_users <- user.info["blocks"] || [],
+ with blocked_users <- user.info.blocks || [],
accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
json(conn, res)
@@ -652,7 +640,7 @@ def blocks(%{assigns: %{user: user}} = conn, _) do
end
def domain_blocks(%{assigns: %{user: %{info: info}}} = conn, _) do
- json(conn, info["domain_blocks"] || [])
+ json(conn, info.domain_blocks || [])
end
def block_domain(%{assigns: %{user: blocker}} = conn, %{"domain" => domain}) do
@@ -900,11 +888,11 @@ def index(%{assigns: %{user: user}} = conn, _params) do
max_toot_chars: limit
},
rights: %{
- delete_others_notice: !!user.info["is_moderator"]
+ delete_others_notice: !!user.info.is_moderator
},
compose: %{
me: "#{user.id}",
- default_privacy: user.info["default_scope"] || "public",
+ default_privacy: user.info.default_scope,
default_sensitive: false
},
media_attachments: %{
@@ -924,7 +912,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
]
},
settings:
- Map.get(user.info, "settings") ||
+ Map.get(user.info, :settings) ||
%{
onboarded: true,
home: %{
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index b68845e16..bcfa8836e 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -14,10 +14,10 @@ def render("account.json", %{user: user} = opts) do
image = User.avatar_url(user) |> MediaProxy.url()
header = User.banner_url(user) |> MediaProxy.url()
user_info = User.user_info(user)
- bot = (user.info["source_data"]["type"] || "Person") in ["Application", "Service"]
+ bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"]
emojis =
- (user.info["source_data"]["tag"] || [])
+ (user.info.source_data["tag"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
%{
@@ -29,7 +29,7 @@ def render("account.json", %{user: user} = opts) do
end)
fields =
- (user.info["source_data"]["attachment"] || [])
+ (user.info.source_data["attachment"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index 1d0019d3b..6a27f1730 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -226,25 +226,21 @@ def maybe_update_ostatus(doc, user) do
old_data = %{
avatar: user.avatar,
bio: user.bio,
- name: user.name,
- info: user.info
+ name: user.name
}
with false <- user.local,
avatar <- make_avatar_object(doc),
bio <- string_from_xpath("//author[1]/summary", doc),
name <- string_from_xpath("//author[1]/poco:displayName", doc),
- info <-
- Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
new_data <- %{
avatar: avatar || old_data.avatar,
name: name || old_data.name,
- bio: bio || old_data.bio,
- info: info || old_data.info
+ bio: bio || old_data.bio
},
false <- new_data == old_data do
change = Ecto.Changeset.change(user, new_data)
- Repo.update(change)
+ User.update_and_set_cache(change)
else
_ ->
{:ok, user}
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 09265954a..d6a9d5779 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -297,12 +297,6 @@ defmodule Pleroma.Web.Router do
post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner)
post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background)
- post(
- "/account/most_recent_notification",
- TwitterAPI.Controller,
- :update_most_recent_notification
- )
-
get("/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline)
get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline)
get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline)
diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex
index 562ec3d9c..b98ece6c9 100644
--- a/lib/pleroma/web/salmon/salmon.ex
+++ b/lib/pleroma/web/salmon/salmon.ex
@@ -157,7 +157,7 @@ def remote_users(%{data: %{"to" => to} = data}) do
|> Enum.filter(fn user -> user && !user.local end)
end
- defp send_to_user(%{info: %{"salmon" => salmon}}, feed, poster) do
+ defp send_to_user(%{info: %{salmon: salmon}}, feed, poster) do
with {:ok, %{status_code: code}} <-
poster.(
salmon,
@@ -185,7 +185,7 @@ defp send_to_user(_, _, _), do: nil
]
def publish(user, activity, poster \\ &@httpoison.post/4)
- def publish(%{info: %{"keys" => keys}} = user, %{data: %{"type" => type}} = activity, poster)
+ def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity, poster)
when type in @supported_activities do
feed = ActivityRepresenter.to_simple_form(activity, user, true)
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index 306598157..99b8b7063 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -188,7 +188,7 @@ def push_to_socket(topics, topic, %Activity{data: %{"type" => "Announce"}} = ite
# Get the current user so we have up-to-date blocks etc.
if socket.assigns[:user] do
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
- blocks = user.info["blocks"] || []
+ blocks = user.info.blocks || []
parent = Object.normalize(item.data["object"])
@@ -206,7 +206,7 @@ def push_to_socket(topics, topic, item) do
# Get the current user so we have up-to-date blocks etc.
if socket.assigns[:user] do
user = User.get_cached_by_ap_id(socket.assigns[:user].ap_id)
- blocks = user.info["blocks"] || []
+ blocks = user.info.blocks || []
unless item.actor in blocks do
send(socket.transport_pid, {:text, represent_update(item, user)})
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 6223580e1..39a2974bb 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -148,7 +148,7 @@ def register_user(params) do
cond do
registrations_open || (!is_nil(token) && !token.used) ->
- changeset = User.register_changeset(%User{}, params)
+ changeset = User.register_changeset(%User{info: %{}}, params)
with {:ok, user} <- Repo.insert(changeset) do
!registrations_open && UserInviteToken.mark_as_used(token.token)
@@ -279,14 +279,6 @@ def conversation_id_to_context(id) do
def get_external_profile(for_user, uri) do
with %User{} = user <- User.get_or_fetch(uri) do
- spawn(fn ->
- with url <- user.info["topic"],
- {:ok, %{body: body}} <-
- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
- OStatus.handle_incoming(body)
- end
- end)
-
{:ok, UserView.render("show.json", %{user: user, for: for_user})}
else
_e ->
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index 064730867..ff644dd79 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -300,9 +300,10 @@ def update_avatar(%{assigns: %{user: user}} = conn, params) do
def update_banner(%{assigns: %{user: user}} = conn, params) do
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
- new_info <- Map.put(user.info, "banner", object.data),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
+ new_info <- %{"banner" => object.data},
+ info_cng <- User.Info.profile_update(user.info, new_info),
+ changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
+ {:ok, user} <- User.update_and_set_cache(changeset) do
CommonAPI.update(user)
%{"url" => [%{"href" => href} | _]} = object.data
response = %{url: href} |> Jason.encode!()
@@ -314,9 +315,10 @@ def update_banner(%{assigns: %{user: user}} = conn, params) do
def update_background(%{assigns: %{user: user}} = conn, params) do
with {:ok, object} <- ActivityPub.upload(params, type: :background),
- new_info <- Map.put(user.info, "background", object.data),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, _user} <- User.update_and_set_cache(change) do
+ new_info <- %{"background" => object.data},
+ info_cng <- User.Info.profile_update(user.info, new_info),
+ changeset <- Ecto.Changeset.change(user) |> Ecto.Changeset.put_embed(:info, info_cng),
+ {:ok, _user} <- User.update_and_set_cache(changeset) do
%{"url" => [%{"href" => href} | _]} = object.data
response = %{url: href} |> Jason.encode!()
@@ -338,20 +340,6 @@ def external_profile(%{assigns: %{user: current_user}} = conn, %{"profileurl" =>
end
end
- def update_most_recent_notification(%{assigns: %{user: user}} = conn, %{"id" => id}) do
- with id when is_number(id) <- String.to_integer(id),
- info <- user.info,
- mrn <- max(id, user.info["most_recent_notification"] || 0),
- updated_info <- Map.put(info, "most_recent_notification", mrn),
- changeset <- User.info_changeset(user, %{info: updated_info}),
- {:ok, _user} <- User.update_and_set_cache(changeset) do
- conn
- |> json_reply(200, Jason.encode!(mrn))
- else
- _e -> bad_request_reply(conn, "Can't update.")
- end
- end
-
def followers(conn, params) do
with {:ok, user} <- TwitterAPI.get_user(conn.assigns[:user], params),
{:ok, followers} <- User.get_followers(user) do
@@ -439,67 +427,52 @@ def raw_empty_array(conn, _params) do
json(conn, [])
end
+ defp build_info_cng(user, params) do
+ info_params =
+ ["no_rich_text", "locked"]
+ |> Enum.reduce(%{}, fn key, res ->
+ if value = params[key] do
+ Map.put(res, key, value == "true")
+ else
+ res
+ end
+ end)
+
+ info_params =
+ if value = params["default_scope"] do
+ Map.put(info_params, "default_scope", value)
+ else
+ info_params
+ end
+
+ User.Info.profile_update(user.info, info_params)
+ end
+
+ defp add_profile_emoji(user, params) do
+ if bio = params["description"] do
+ mentions = Formatter.parse_mentions(bio)
+ tags = Formatter.parse_tags(bio)
+
+ emoji =
+ (user.info.source_data["tag"] || [])
+ |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
+ |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
+ {String.trim(name, ":"), url}
+ end)
+
+ bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
+ Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
+ else
+ params
+ end
+ end
+
def update_profile(%{assigns: %{user: user}} = conn, params) do
- params =
- if bio = params["description"] do
- mentions = Formatter.parse_mentions(bio)
- tags = Formatter.parse_tags(bio)
-
- emoji =
- (user.info["source_data"]["tag"] || [])
- |> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
- |> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
- {String.trim(name, ":"), url}
- end)
-
- bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
- Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
- else
- params
- end
-
- user =
- if locked = params["locked"] do
- with locked <- locked == "true",
- new_info <- Map.put(user.info, "locked", locked),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
- user
- else
- _e -> user
- end
- else
- user
- end
-
- user =
- if no_rich_text = params["no_rich_text"] do
- with no_rich_text <- no_rich_text == "true",
- new_info <- Map.put(user.info, "no_rich_text", no_rich_text),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
- user
- else
- _e -> user
- end
- else
- user
- end
-
- user =
- if default_scope = params["default_scope"] do
- with new_info <- Map.put(user.info, "default_scope", default_scope),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
- user
- else
- _e -> user
- end
- else
- user
- end
+ params = add_profile_emoji(user, params)
+ info_cng = build_info_cng(user, params)
with changeset <- User.update_changeset(user, params),
+ changeset <- Ecto.Changeset.put_embed(changeset, :info, info_cng),
{:ok, user} <- User.update_and_set_cache(changeset) do
CommonAPI.update(user)
render(conn, UserView, "user.json", %{user: user, for: user})
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
index a100a1127..b78024ed7 100644
--- a/lib/pleroma/web/twitter_api/views/user_view.ex
+++ b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -31,7 +31,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do
user_info = User.get_cached_user_info(user)
emoji =
- (user.info["source_data"]["tag"] || [])
+ (user.info.source_data["tag"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
{String.trim(name, ":"), url}
@@ -40,7 +40,7 @@ def render("user.json", %{user: user = %User{}} = assigns) do
# ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``.
# For example: [{"name": "Pronoun", "value": "she/her"}, …]
fields =
- (user.info["source_data"]["attachment"] || [])
+ (user.info.source_data["attachment"] || [])
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
@@ -66,17 +66,17 @@ def render("user.json", %{user: user = %User{}} = assigns) do
"profile_image_url_profile_size" => image,
"profile_image_url_original" => image,
"rights" => %{
- "delete_others_notice" => !!user.info["is_moderator"]
+ "delete_others_notice" => !!user.info.is_moderator
},
"screen_name" => user.nickname,
"statuses_count" => user_info[:note_count],
"statusnet_profile_url" => user.ap_id,
"cover_photo" => User.banner_url(user) |> MediaProxy.url(),
- "background_image" => image_url(user.info["background"]) |> MediaProxy.url(),
+ "background_image" => image_url(user.info.background) |> MediaProxy.url(),
"is_local" => user.local,
- "locked" => !!user.info["locked"],
- "default_scope" => user.info["default_scope"] || "public",
- "no_rich_text" => user.info["no_rich_text"] || false,
+ "locked" => user.info.locked,
+ "default_scope" => user.info.default_scope,
+ "no_rich_text" => user.info.no_rich_text,
"fields" => fields
}
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 9f554d286..eaee3a8c6 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -45,7 +45,7 @@ def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do
def represent_user(user, "JSON") do
{:ok, user} = ensure_keys_present(user)
- {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
+ {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys)
magic_key = Salmon.encode_key(public)
%{
@@ -83,7 +83,7 @@ def represent_user(user, "JSON") do
def represent_user(user, "XML") do
{:ok, user} = ensure_keys_present(user)
- {:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
+ {:ok, _private, public} = Salmon.keys_from_pem(user.info.keys)
magic_key = Salmon.encode_key(public)
{
@@ -113,16 +113,22 @@ def represent_user(user, "XML") do
# This seems a better fit in Salmon
def ensure_keys_present(user) do
- info = user.info || %{}
+ info = user.info
- if info["keys"] do
+ if info.keys do
{:ok, user}
else
{:ok, pem} = Salmon.generate_rsa_pem()
- info = Map.put(info, "keys", pem)
- Ecto.Changeset.change(user, info: info)
- |> User.update_and_set_cache()
+ info_cng =
+ info
+ |> Pleroma.User.Info.set_keys(pem)
+
+ cng =
+ Ecto.Changeset.change(user)
+ |> Ecto.Changeset.put_embed(:info, info_cng)
+
+ User.update_and_set_cache(cng)
end
end
diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex
index 396dcf045..905d8d658 100644
--- a/lib/pleroma/web/websub/websub.ex
+++ b/lib/pleroma/web/websub/websub.ex
@@ -146,7 +146,7 @@ defp valid_topic(%{"hub.topic" => topic}, user) do
end
def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
- topic = subscribed.info["topic"]
+ topic = subscribed.info.topic
# FIXME: Race condition, use transactions
{:ok, subscription} =
with subscription when not is_nil(subscription) <-
@@ -158,7 +158,7 @@ def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
_e ->
subscription = %WebsubClientSubscription{
topic: topic,
- hub: subscribed.info["hub"],
+ hub: subscribed.info.hub,
subscribers: [subscriber.ap_id],
state: "requested",
secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64(),
diff --git a/priv/repo/migrations/20181201104428_add_uuid_extension.exs b/priv/repo/migrations/20181201104428_add_uuid_extension.exs
new file mode 100644
index 000000000..2509e558d
--- /dev/null
+++ b/priv/repo/migrations/20181201104428_add_uuid_extension.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.AddUUIDExtension do
+ use Ecto.Migration
+
+ def change do
+ execute("create extension if not exists \"uuid-ossp\"")
+ end
+end
diff --git a/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs b/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs
new file mode 100644
index 000000000..9571a1e4d
--- /dev/null
+++ b/priv/repo/migrations/20181201105617_add_uui_ds_to_user_info.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.AddUUIDsToUserInfo do
+ use Ecto.Migration
+
+ def change do
+ execute("update users set info = jsonb_set(info, '{\"id\"}', to_jsonb(uuid_generate_v4()))")
+ end
+end
diff --git a/test/formatter_test.exs b/test/formatter_test.exs
index 13084baa7..e4da84c10 100644
--- a/test/formatter_test.exs
+++ b/test/formatter_test.exs
@@ -110,7 +110,7 @@ test "gives a replacement for user links" do
archaeme =
insert(:user, %{
nickname: "archaeme",
- info: %{"source_data" => %{"url" => "https://archeme/@archaeme"}}
+ info: %Pleroma.User.Info{source_data: %{"url" => "https://archeme/@archaeme"}}
})
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs
index ee4f72ccf..eeb167933 100644
--- a/test/plugs/user_enabled_plug_test.exs
+++ b/test/plugs/user_enabled_plug_test.exs
@@ -13,7 +13,7 @@ test "doesn't do anything if the user isn't set", %{conn: conn} do
end
test "with a user that is deactivated, it removes that user", %{conn: conn} do
- user = insert(:user, info: %{"deactivated" => true})
+ user = insert(:user, info: %{deactivated: true})
conn =
conn
diff --git a/test/plugs/user_is_admin_plug_test.exs b/test/plugs/user_is_admin_plug_test.exs
index ddf9eb139..031b2f466 100644
--- a/test/plugs/user_is_admin_plug_test.exs
+++ b/test/plugs/user_is_admin_plug_test.exs
@@ -5,7 +5,7 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
import Pleroma.Factory
test "accepts a user that is admin", %{conn: conn} do
- user = insert(:user, info: %{"is_admin" => true})
+ user = insert(:user, info: %{is_admin: true})
conn =
build_conn()
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 4f5060abf..2889d8977 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -7,7 +7,8 @@ def user_factory do
email: sequence(:email, &"user#{&1}@example.com"),
nickname: sequence(:nickname, &"nick#{&1}"),
password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
- bio: sequence(:bio, &"Tester Number #{&1}")
+ bio: sequence(:bio, &"Tester Number #{&1}"),
+ info: %{}
}
%{
diff --git a/test/user_test.exs b/test/user_test.exs
index 231f1d94d..62104df90 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -34,14 +34,14 @@ test "follow takes a user and another user" do
user = Repo.get(User, user.id)
followed = User.get_by_ap_id(followed.ap_id)
- assert followed.info["follower_count"] == 1
+ assert followed.info.follower_count == 1
assert User.ap_followers(followed) in user.following
end
test "can't follow a deactivated users" do
user = insert(:user)
- followed = insert(:user, info: %{"deactivated" => true})
+ followed = insert(:user, info: %{deactivated: true})
{:error, _} = User.follow(user, followed)
end
@@ -56,8 +56,8 @@ test "can't follow a user who blocked us" do
end
test "local users do not automatically follow local locked accounts" do
- follower = insert(:user, info: %{"locked" => true})
- followed = insert(:user, info: %{"locked" => true})
+ follower = insert(:user, info: %{locked: true})
+ followed = insert(:user, info: %{locked: true})
{:ok, follower} = User.maybe_direct_follow(follower, followed)
@@ -185,12 +185,14 @@ test "updates an existing user, if stale" do
local: false,
nickname: "admin@mastodon.example.org",
ap_id: "http://mastodon.example.org/users/admin",
- last_refreshed_at: a_week_ago
+ last_refreshed_at: a_week_ago,
+ info: %{}
)
assert orig_user.last_refreshed_at == a_week_ago
user = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
+ assert user.info.source_data["endpoints"]
refute user.last_refreshed_at == orig_user.last_refreshed_at
end
@@ -311,45 +313,45 @@ test "it sets the info->note_count property" do
user = User.get_by_ap_id(note.data["actor"])
- assert user.info["note_count"] == nil
+ assert user.info.note_count == 0
{:ok, user} = User.update_note_count(user)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
end
test "it increases the info->note_count property" do
note = insert(:note)
user = User.get_by_ap_id(note.data["actor"])
- assert user.info["note_count"] == nil
+ assert user.info.note_count == 0
{:ok, user} = User.increase_note_count(user)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
{:ok, user} = User.increase_note_count(user)
- assert user.info["note_count"] == 2
+ assert user.info.note_count == 2
end
test "it decreases the info->note_count property" do
note = insert(:note)
user = User.get_by_ap_id(note.data["actor"])
- assert user.info["note_count"] == nil
+ assert user.info.note_count == 0
{:ok, user} = User.increase_note_count(user)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
{:ok, user} = User.decrease_note_count(user)
- assert user.info["note_count"] == 0
+ assert user.info.note_count == 0
{:ok, user} = User.decrease_note_count(user)
- assert user.info["note_count"] == 0
+ assert user.info.note_count == 0
end
test "it sets the info->follower_count property" do
@@ -358,11 +360,11 @@ test "it sets the info->follower_count property" do
User.follow(follower, user)
- assert user.info["follower_count"] == nil
+ assert user.info.follower_count == 0
{:ok, user} = User.update_follower_count(user)
- assert user.info["follower_count"] == 1
+ assert user.info.follower_count == 1
end
end
@@ -489,11 +491,11 @@ test "get recipients from activity" do
test ".deactivate can de-activate then re-activate a user" do
user = insert(:user)
- assert false == !!user.info["deactivated"]
+ assert false == user.info.deactivated
{:ok, user} = User.deactivate(user)
- assert true == user.info["deactivated"]
+ assert true == user.info.deactivated
{:ok, user} = User.deactivate(user, false)
- assert false == !!user.info["deactivated"]
+ assert false == user.info.deactivated
end
test ".delete deactivates a user, all follow relationships and all create activities" do
@@ -517,7 +519,7 @@ test ".delete deactivates a user, all follow relationships and all create activi
follower = Repo.get(User, follower.id)
user = Repo.get(User, user.id)
- assert user.info["deactivated"]
+ assert user.info.deactivated
refute User.following?(user, followed)
refute User.following?(followed, follower)
@@ -546,7 +548,7 @@ test "html_filter_policy returns nil when rich-text is enabled" do
end
test "html_filter_policy returns TwitterText scrubber when rich-text is disabled" do
- user = insert(:user, %{info: %{"no_rich_text" => true}})
+ user = insert(:user, %{info: %{no_rich_text: true}})
assert Pleroma.HTML.Scrubber.TwitterText == User.html_filter_policy(user)
end
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index 35c381ac3..1d561d38d 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -14,8 +14,8 @@ test "it returns a user" do
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.ap_id == user_id
assert user.nickname == "admin@mastodon.example.org"
- assert user.info["source_data"]
- assert user.info["ap_enabled"]
+ assert user.info.source_data
+ assert user.info.ap_enabled
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
end
end
diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs
index 829da0a65..e74b8f9a1 100644
--- a/test/web/activity_pub/transmogrifier_test.exs
+++ b/test/web/activity_pub/transmogrifier_test.exs
@@ -92,7 +92,7 @@ test "it works for incoming notices" do
user = User.get_by_ap_id(object["actor"])
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
end
test "it works for incoming notices with hashtags" do
@@ -307,7 +307,7 @@ test "it works for incoming update activities" do
}
]
- assert user.info["banner"]["url"] == [
+ assert user.info.banner["url"] == [
%{
"href" =>
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
@@ -337,7 +337,7 @@ test "it works for incoming update activities which lock the account" do
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(update_data)
user = User.get_cached_by_ap_id(data["actor"])
- assert user.info["locked"] == true
+ assert user.info.locked == true
end
test "it works for incoming deletes" do
@@ -543,7 +543,7 @@ test "it works for incoming accepts which were pre-accepted" do
test "it works for incoming accepts which were orphaned" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
@@ -565,7 +565,7 @@ test "it works for incoming accepts which were orphaned" do
test "it works for incoming accepts which are referenced by IRI only" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
@@ -585,7 +585,7 @@ test "it works for incoming accepts which are referenced by IRI only" do
test "it fails for incoming accepts which cannot be correlated" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
@@ -604,7 +604,7 @@ test "it fails for incoming accepts which cannot be correlated" do
test "it fails for incoming rejects which cannot be correlated" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
accept_data =
File.read!("test/fixtures/mastodon-reject-activity.json")
@@ -623,7 +623,7 @@ test "it fails for incoming rejects which cannot be correlated" do
test "it works for incoming rejects which are orphaned" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
{:ok, follower} = User.follow(follower, followed)
{:ok, _follow_activity} = ActivityPub.follow(follower, followed)
@@ -648,7 +648,7 @@ test "it works for incoming rejects which are orphaned" do
test "it works for incoming rejects which are referenced by IRI only" do
follower = insert(:user)
- followed = insert(:user, %{info: %{"locked" => true}})
+ followed = insert(:user, %{info: %User.Info{locked: true}})
{:ok, follower} = User.follow(follower, followed)
{:ok, follow_activity} = ActivityPub.follow(follower, followed)
@@ -815,18 +815,18 @@ test "it upgrades a user to activitypub" do
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
user = Repo.get(User, user.id)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
- assert user.info["ap_enabled"]
- assert user.info["note_count"] == 1
+ assert user.info.ap_enabled
+ assert user.info.note_count == 1
assert user.follower_address == "https://niu.moe/users/rye/followers"
# Wait for the background task
:timer.sleep(1000)
user = Repo.get(User, user.id)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
activity = Repo.get(Activity, activity.id)
assert user.follower_address in activity.recipients
@@ -847,7 +847,7 @@ test "it upgrades a user to activitypub" do
"https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
}
]
- } = user.info["banner"]
+ } = user.info.banner
refute "..." in activity.recipients
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index fa0cb71bf..9634ad7c5 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
describe "/api/pleroma/admin/user" do
test "Delete" do
- admin = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
conn =
@@ -21,7 +21,7 @@ test "Delete" do
end
test "Create" do
- admin = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
conn =
build_conn()
@@ -39,7 +39,7 @@ test "Create" do
describe "/api/pleroma/admin/permission_group" do
test "GET is giving user_info" do
- admin = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
conn =
build_conn()
@@ -47,33 +47,30 @@ test "GET is giving user_info" do
|> put_req_header("accept", "application/json")
|> get("/api/pleroma/admin/permission_group/#{admin.nickname}")
- assert json_response(conn, 200) == admin.info
+ assert json_response(conn, 200) == %{
+ "is_admin" => true,
+ "is_moderator" => false
+ }
end
test "/:right POST, can add to a permission group" do
- admin = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
user = insert(:user)
- user_info =
- user.info
- |> Map.put("is_admin", true)
-
conn =
build_conn()
|> assign(:user, admin)
|> put_req_header("accept", "application/json")
|> post("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
- assert json_response(conn, 200) == user_info
+ assert json_response(conn, 200) == %{
+ "is_admin" => true
+ }
end
test "/:right DELETE, can remove from a permission group" do
- admin = insert(:user, info: %{"is_admin" => true})
- user = insert(:user, info: %{"is_admin" => true})
-
- user_info =
- user.info
- |> Map.put("is_admin", false)
+ admin = insert(:user, info: %{is_admin: true})
+ user = insert(:user, info: %{is_admin: true})
conn =
build_conn()
@@ -81,12 +78,14 @@ test "/:right DELETE, can remove from a permission group" do
|> put_req_header("accept", "application/json")
|> delete("/api/pleroma/admin/permission_group/#{user.nickname}/admin")
- assert json_response(conn, 200) == user_info
+ assert json_response(conn, 200) == %{
+ "is_admin" => false
+ }
end
end
test "/api/pleroma/admin/invite_token" do
- admin = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
conn =
build_conn()
@@ -98,8 +97,8 @@ test "/api/pleroma/admin/invite_token" do
end
test "/api/pleroma/admin/password_reset" do
- admin = insert(:user, info: %{"is_admin" => true})
- user = insert(:user, info: %{"is_admin" => true})
+ admin = insert(:user, info: %{is_admin: true})
+ user = insert(:user)
conn =
build_conn()
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index cd36e409c..8fc65f4c0 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -17,7 +17,7 @@ test "it adds emoji when updating profiles" do
CommonAPI.update(user)
user = User.get_cached_by_ap_id(user.ap_id)
- [karjalanpiirakka] = user.info["source_data"]["tag"]
+ [karjalanpiirakka] = user.info.source_data["tag"]
assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
end
diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs
index dc52b92bc..a2d3a2547 100644
--- a/test/web/mastodon_api/account_view_test.exs
+++ b/test/web/mastodon_api/account_view_test.exs
@@ -17,7 +17,7 @@ test "Represent a user account" do
user =
insert(:user, %{
- info: %{"note_count" => 5, "follower_count" => 3, "source_data" => source_data},
+ info: %{note_count: 5, follower_count: 3, source_data: source_data},
nickname: "shp@shitposter.club",
name: ":karjalanpiirakka: shp",
bio: "valid html",
@@ -63,7 +63,7 @@ test "Represent a user account" do
test "Represent a Service(bot) account" do
user =
insert(:user, %{
- info: %{"note_count" => 5, "follower_count" => 3, "source_data" => %{"type" => "Service"}},
+ info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}},
nickname: "shp@shitposter.club",
inserted_at: ~N[2017-08-15 15:47:06.597036]
})
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index ad67cae6b..7042a6ace 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -252,7 +252,7 @@ test "verify_credentials", %{conn: conn} do
end
test "verify_credentials default scope unlisted", %{conn: conn} do
- user = insert(:user, %{info: %{"default_scope" => "unlisted"}})
+ user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "unlisted"}})
conn =
conn
@@ -845,7 +845,7 @@ test "returns the relationships for the current user", %{conn: conn} do
describe "locked accounts" do
test "/api/v1/follow_requests works" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
other_user = insert(:user)
{:ok, activity} = ActivityPub.follow(other_user, user)
@@ -865,7 +865,7 @@ test "/api/v1/follow_requests works" do
end
test "/api/v1/follow_requests/:id/authorize works" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
other_user = insert(:user)
{:ok, activity} = ActivityPub.follow(other_user, user)
@@ -890,7 +890,7 @@ test "/api/v1/follow_requests/:id/authorize works" do
end
test "verify_credentials", %{conn: conn} do
- user = insert(:user, %{info: %{"default_scope" => "private"}})
+ user = insert(:user, %{info: %Pleroma.User.Info{default_scope: "private"}})
conn =
conn
@@ -902,7 +902,7 @@ test "verify_credentials", %{conn: conn} do
end
test "/api/v1/follow_requests/:id/reject works" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user, %{info: %Pleroma.User.Info{locked: true}})
other_user = insert(:user)
{:ok, activity} = ActivityPub.follow(other_user, user)
@@ -1105,7 +1105,7 @@ test "blocking / unblocking a domain", %{conn: conn} do
refute User.blocks?(user, other_user)
end
- test "getting a list of domain blocks" do
+ test "getting a list of domain blocks", %{conn: conn} do
user = insert(:user)
{:ok, user} = User.block_domain(user, "bad.site")
@@ -1263,6 +1263,18 @@ test "updates the user's bio", %{conn: conn} do
assert user["note"] == "I drink #cofe"
end
+ test "updates the user's locking status", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> patch("/api/v1/accounts/update_credentials", %{locked: "true"})
+
+ assert user = json_response(conn, 200)
+ assert user["locked"] == true
+ end
+
test "updates the user's name", %{conn: conn} do
user = insert(:user)
@@ -1289,8 +1301,8 @@ test "updates the user's avatar", %{conn: conn} do
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
- assert user = json_response(conn, 200)
- assert user["avatar"] != "https://placehold.it/48x48"
+ assert user_response = json_response(conn, 200)
+ assert user_response["avatar"] != User.avatar_url(user)
end
test "updates the user's banner", %{conn: conn} do
@@ -1307,8 +1319,8 @@ test "updates the user's banner", %{conn: conn} do
|> assign(:user, user)
|> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
- assert user = json_response(conn, 200)
- assert user["header"] != "https://placehold.it/700x335"
+ assert user_response = json_response(conn, 200)
+ assert user_response["header"] != User.banner_url(user)
end
end
diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs
index a6376453c..a5b0b7869 100644
--- a/test/web/node_info_test.exs
+++ b/test/web/node_info_test.exs
@@ -4,7 +4,7 @@ defmodule Pleroma.Web.NodeInfoTest do
import Pleroma.Factory
test "nodeinfo shows staff accounts", %{conn: conn} do
- user = insert(:user, %{local: true, info: %{"is_moderator" => true}})
+ user = insert(:user, %{local: true, info: %{is_moderator: true}})
conn =
conn
@@ -15,7 +15,7 @@ test "nodeinfo shows staff accounts", %{conn: conn} do
assert user.ap_id in result["metadata"]["staffAccounts"]
end
- test "returns 404 when federation is disabled" do
+ test "returns 404 when federation is disabled", %{conn: conn} do
instance =
Application.get_env(:pleroma, :instance)
|> Keyword.put(:federating, false)
@@ -37,7 +37,7 @@ test "returns 404 when federation is disabled" do
Application.put_env(:pleroma, :instance, instance)
end
- test "returns 200 when federation is enabled" do
+ test "returns 200 when federation is enabled", %{conn: conn} do
conn
|> get("/.well-known/nodeinfo")
|> json_response(200)
diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs
index 371c835c0..e81adde68 100644
--- a/test/web/ostatus/ostatus_controller_test.exs
+++ b/test/web/ostatus/ostatus_controller_test.exs
@@ -31,14 +31,16 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do
# Set a wrong magic-key for a user so it has to refetch
salmon_user = User.get_by_ap_id("http://gs.example.org:4040/index.php/user/1")
# Wrong key
- info =
- salmon_user.info
- |> Map.put(
- "magic_key",
- "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
- )
+ info_cng =
+ User.Info.remote_user_creation(salmon_user.info, %{
+ magic_key:
+ "RSA.pu0s-halox4tu7wmES1FVSx6u-4wc0YrUFXcqWXZG4-27UmbCOpMQftRCldNRfyA-qLbz-eqiwrong1EwUvjsD4cYbAHNGHwTvDOyx5AKthQUP44ykPv7kjKGh3DWKySJvcs9tlUG87hlo7AvnMo9pwRS_Zz2CacQ-MKaXyDepk=.AQAB"
+ })
- Repo.update(User.info_changeset(salmon_user, %{info: info}))
+ cng =
+ Ecto.Changeset.change(salmon_user)
+ |> Ecto.Changeset.put_embed(:info, info_cng)
+ |> Repo.update()
conn =
build_conn()
diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs
index f95da8b0a..baa8cac72 100644
--- a/test/web/ostatus/ostatus_test.exs
+++ b/test/web/ostatus/ostatus_test.exs
@@ -17,7 +17,7 @@ test "handle incoming note - GS, Salmon" do
{:ok, [activity]} = OStatus.handle_incoming(incoming)
user = User.get_by_ap_id(activity.data["actor"])
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
assert activity.data["type"] == "Create"
assert activity.data["object"]["type"] == "Note"
@@ -319,7 +319,7 @@ test "tries to use the information in poco fields" do
assert user.name == "Constance Variable"
assert user.nickname == "lambadalambda@social.heldscal.la"
assert user.local == false
- assert user.info["uri"] == uri
+ assert user.info.uri == uri
assert user.ap_id == uri
assert user.bio == "Call me Deacon Blues."
assert user.avatar["type"] == "Image"
@@ -329,6 +329,38 @@ test "tries to use the information in poco fields" do
assert user == user_again
end
+ test "find_or_make_user sets all the nessary input fields" do
+ uri = "https://social.heldscal.la/user/23211"
+ {:ok, user} = OStatus.find_or_make_user(uri)
+
+ assert user.info ==
+ %Pleroma.User.Info{
+ id: user.info.id,
+ ap_enabled: false,
+ background: nil,
+ banner: %{},
+ blocks: [],
+ deactivated: false,
+ default_scope: "public",
+ domain_blocks: [],
+ follower_count: 0,
+ is_admin: false,
+ is_moderator: false,
+ keys: nil,
+ locked: false,
+ no_rich_text: false,
+ note_count: 0,
+ settings: nil,
+ source_data: %{},
+ hub: "https://social.heldscal.la/main/push/hub",
+ magic_key:
+ "RSA.uzg6r1peZU0vXGADWxGJ0PE34WvmhjUmydbX5YYdOiXfODVLwCMi1umGoqUDm-mRu4vNEdFBVJU1CpFA7dKzWgIsqsa501i2XqElmEveXRLvNRWFB6nG03Q5OUY2as8eE54BJm0p20GkMfIJGwP6TSFb-ICp3QjzbatuSPJ6xCE=.AQAB",
+ salmon: "https://social.heldscal.la/main/salmon/user/23211",
+ topic: "https://social.heldscal.la/api/statuses/user_timeline/23211.atom",
+ uri: "https://social.heldscal.la/user/23211"
+ }
+ end
+
test "find_make_or_update_user takes an author element and returns an updated user" do
uri = "https://social.heldscal.la/user/23211"
@@ -447,7 +479,7 @@ test "it works for atom notes, too" do
end
end
- test "it doesn't add nil in the do field" do
+ test "it doesn't add nil in the to field" do
incoming = File.read!("test/fixtures/nil_mention_entry.xml")
{:ok, [activity]} = OStatus.handle_incoming(incoming)
diff --git a/test/web/ostatus/user_representer_test.exs b/test/web/ostatus/user_representer_test.exs
index e41dfeb3d..82fb8e793 100644
--- a/test/web/ostatus/user_representer_test.exs
+++ b/test/web/ostatus/user_representer_test.exs
@@ -6,7 +6,7 @@ defmodule Pleroma.Web.OStatus.UserRepresenterTest do
alias Pleroma.User
test "returns a user with id, uri, name and link" do
- user = build(:user, nickname: "レイン")
+ user = insert(:user, %{nickname: "レイン"})
tuple = UserRepresenter.to_simple_form(user)
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> to_string
diff --git a/test/web/twitter_api/representers/activity_representer_test.exs b/test/web/twitter_api/representers/activity_representer_test.exs
index 291fd5237..7cae4e4a1 100644
--- a/test/web/twitter_api/representers/activity_representer_test.exs
+++ b/test/web/twitter_api/representers/activity_representer_test.exs
@@ -58,7 +58,7 @@ test "a like activity" do
end
test "an activity" do
- {:ok, user} = UserBuilder.insert()
+ user = insert(:user)
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
mentioned_user = insert(:user, %{nickname: "shp"})
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index 6bdcb4fd8..89c176da7 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -12,6 +12,36 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
import Pleroma.Factory
+ describe "POST /api/account/update_profile_banner" do
+ test "it updates the banner", %{conn: conn} do
+ user = insert(:user)
+
+ new_banner =
+ "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
+
+ response =
+ conn
+ |> assign(:user, user)
+ |> post(authenticated_twitter_api__path(conn, :update_banner), %{"banner" => new_banner})
+ |> json_response(200)
+ end
+ end
+
+ describe "POST /api/qvitter/update_background_image" do
+ test "it updates the background", %{conn: conn} do
+ user = insert(:user)
+
+ new_bg =
+ "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
+
+ response =
+ conn
+ |> assign(:user, user)
+ |> post(authenticated_twitter_api__path(conn, :update_background), %{"img" => new_bg})
+ |> json_response(200)
+ end
+ end
+
describe "POST /api/account/verify_credentials" do
setup [:valid_user]
@@ -31,26 +61,6 @@ test "with credentials", %{conn: conn, user: user} do
end
end
- describe "POST /api/account/most_recent_notification" do
- setup [:valid_user]
-
- test "without valid credentials", %{conn: conn} do
- conn = post(conn, "/api/account/most_recent_notification.json")
- assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
- end
-
- test "with credentials", %{conn: conn, user: user} do
- conn =
- conn
- |> with_credentials(user.nickname, "test")
- |> post("/api/account/most_recent_notification.json", %{id: "200"})
-
- assert json_response(conn, 200)
- user = User.get_by_nickname(user.nickname)
- assert user.info["most_recent_notification"] == 200
- end
- end
-
describe "POST /statuses/update.json" do
setup [:valid_user]
@@ -87,7 +97,7 @@ test "with credentials", %{conn: conn, user: user} do
describe "GET /statuses/public_timeline.json" do
test "returns statuses", %{conn: conn} do
- {:ok, user} = UserBuilder.insert()
+ user = insert(:user)
activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
ActivityBuilder.insert_list(10, %{}, %{user: user})
since_id = List.last(activities).id
@@ -591,7 +601,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> post("/api/blocks/destroy.json", %{user_id: blocked.id})
current_user = Repo.get(User, current_user.id)
- assert current_user.info["blocks"] == []
+ assert current_user.info.blocks == []
assert json_response(conn, 200) ==
UserView.render("show.json", %{user: blocked, for: current_user})
@@ -966,7 +976,7 @@ test "it locks an account", %{conn: conn} do
})
user = Repo.get!(User, user.id)
- assert user.info["locked"] == true
+ assert user.info.locked == true
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end
@@ -982,7 +992,7 @@ test "it unlocks an account", %{conn: conn} do
})
user = Repo.get!(User, user.id)
- assert user.info["locked"] == false
+ assert user.info.locked == false
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end
@@ -1153,10 +1163,10 @@ test "with credentials and valid password", %{conn: conn, user: current_user} do
describe "GET /api/pleroma/friend_requests" do
test "it lists friend requests" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user)
other_user = insert(:user)
- {:ok, activity} = ActivityPub.follow(other_user, user)
+ {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id)
other_user = Repo.get(User, other_user.id)
@@ -1175,10 +1185,10 @@ test "it lists friend requests" do
describe "POST /api/pleroma/friendships/approve" do
test "it approves a friend request" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user)
other_user = insert(:user)
- {:ok, activity} = ActivityPub.follow(other_user, user)
+ {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id)
other_user = Repo.get(User, other_user.id)
@@ -1198,10 +1208,10 @@ test "it approves a friend request" do
describe "POST /api/pleroma/friendships/deny" do
test "it denies a friend request" do
- user = insert(:user, %{info: %{"locked" => true}})
+ user = insert(:user)
other_user = insert(:user)
- {:ok, activity} = ActivityPub.follow(other_user, user)
+ {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id)
other_user = Repo.get(User, other_user.id)
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index 8b9920bd9..ec13b89d4 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -10,7 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
test "create a status" do
user = insert(:user)
- _mentioned_user = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
+ _mentioned_user = insert(:user, %{nickname: "shp", ap_id: "shp"})
object_data = %{
"type" => "Image",
@@ -67,7 +67,7 @@ test "create a status" do
user = User.get_by_ap_id(user.ap_id)
- assert user.info["note_count"] == 1
+ assert user.info.note_count == 1
end
test "create a status that is a reply" do
@@ -116,7 +116,7 @@ test "Follow another user using screen_name" do
assert User.ap_followers(followed) in user.following
followed = User.get_by_ap_id(followed.ap_id)
- assert followed.info["follower_count"] == 1
+ assert followed.info.follower_count == 1
{:error, msg} = TwitterAPI.follow(user, %{"screen_name" => followed.nickname})
assert msg == "Could not follow user: #{followed.nickname} is already on your list."
@@ -169,7 +169,7 @@ test "Unblock another user using user_id" do
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"user_id" => unblocked.id})
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"user_id" => unblocked.id})
- assert user.info["blocks"] == []
+ assert user.info.blocks == []
end
test "Unblock another user using screen_name" do
@@ -178,7 +178,7 @@ test "Unblock another user using screen_name" do
{:ok, user, _unblocked} = TwitterAPI.block(user, %{"screen_name" => unblocked.nickname})
{:ok, user, _unblocked} = TwitterAPI.unblock(user, %{"screen_name" => unblocked.nickname})
- assert user.info["blocks"] == []
+ assert user.info.blocks == []
end
test "upload a file" do
diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs
index 2c583c0d3..e69ca24a9 100644
--- a/test/web/twitter_api/views/user_view_test.exs
+++ b/test/web/twitter_api/views/user_view_test.exs
@@ -31,10 +31,10 @@ test "A user with emoji in username", %{user: user} do
expected =
" man"
- user = %{
- user
- | info: %{
- "source_data" => %{
+ user =
+ insert(:user, %{
+ info: %{
+ source_data: %{
"tag" => [
%{
"type" => "Emoji",
@@ -43,10 +43,10 @@ test "A user with emoji in username", %{user: user} do
}
]
}
- }
- }
+ },
+ name: ":karjalanpiirakka: man"
+ })
- user = %{user | name: ":karjalanpiirakka: man"}
represented = UserView.render("show.json", %{user: user})
assert represented["name_html"] == expected
end
@@ -103,7 +103,7 @@ test "A user" do
end
test "A user for a given other follower", %{user: user} do
- {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
+ follower = insert(:user, %{following: [User.ap_followers(user)]})
{:ok, user} = User.update_follower_count(user)
image = "http://localhost:4001/images/avi.png"
banner = "http://localhost:4001/images/banner.png"
@@ -186,7 +186,7 @@ test "A user that follows you", %{user: user} do
end
test "a user that is a moderator" do
- user = insert(:user, %{info: %{"is_moderator" => true}})
+ user = insert(:user, %{info: %{is_moderator: true}})
represented = UserView.render("show.json", %{user: user, for: user})
assert represented["rights"]["delete_others_notice"]
@@ -250,7 +250,7 @@ test "a user with mastodon fields" do
user =
insert(:user, %{
info: %{
- "source_data" => %{
+ source_data: %{
"attachment" =>
Enum.map(fields, fn field -> Map.put(field, "type", "PropertyValue") end)
}
diff --git a/test/web/web_finger/web_finger_test.exs b/test/web/web_finger/web_finger_test.exs
index 99bf210ea..28d429565 100644
--- a/test/web/web_finger/web_finger_test.exs
+++ b/test/web/web_finger/web_finger_test.exs
@@ -99,15 +99,15 @@ test "it gets the xrd endpoint for statusnet" do
describe "ensure_keys_present" do
test "it creates keys for a user and stores them in info" do
user = insert(:user)
- refute is_binary(user.info["keys"])
+ refute is_binary(user.info.keys)
{:ok, user} = WebFinger.ensure_keys_present(user)
- assert is_binary(user.info["keys"])
+ assert is_binary(user.info.keys)
end
test "it doesn't create keys if there already are some" do
- user = insert(:user, %{info: %{"keys" => "xxx"}})
+ user = insert(:user, %{info: %{keys: "xxx"}})
{:ok, user} = WebFinger.ensure_keys_present(user)
- assert user.info["keys"] == "xxx"
+ assert user.info.keys == "xxx"
end
end
end
diff --git a/test/web/websub/websub_test.exs b/test/web/websub/websub_test.exs
index 5914a37fc..da7bc9112 100644
--- a/test/web/websub/websub_test.exs
+++ b/test/web/websub/websub_test.exs
@@ -99,7 +99,7 @@ def accepting_verifier(subscription) do
test "initiate a subscription for a given user and topic" do
subscriber = insert(:user)
- user = insert(:user, %{info: %{"topic" => "some_topic", "hub" => "some_hub"}})
+ user = insert(:user, %{info: %Pleroma.User.Info{topic: "some_topic", hub: "some_hub"}})
{:ok, websub} = Websub.subscribe(subscriber, user, &accepting_verifier/1)
assert websub.subscribers == [subscriber.ap_id]