summaryrefslogtreecommitdiff
path: root/lib/pleroma/user.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/user.ex')
-rw-r--r--lib/pleroma/user.ex146
1 files changed, 127 insertions, 19 deletions
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 911dde6e2..0115abed5 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -16,6 +16,7 @@ defmodule Pleroma.User do
alias Pleroma.Conversation.Participation
alias Pleroma.Delivery
alias Pleroma.FollowingRelationship
+ alias Pleroma.Formatter
alias Pleroma.HTML
alias Pleroma.Keys
alias Pleroma.Notification
@@ -150,22 +151,26 @@ defmodule Pleroma.User do
{outgoing_relation, outgoing_relation_target},
{incoming_relation, incoming_relation_source}
]} <- @user_relationships_config do
- # Definitions of `has_many :blocker_blocks`, `has_many :muter_mutes` etc.
+ # Definitions of `has_many` relations: :blocker_blocks, :muter_mutes, :reblog_muter_mutes,
+ # :notification_muter_mutes, :subscribee_subscriptions
has_many(outgoing_relation, UserRelationship,
foreign_key: :source_id,
where: [relationship_type: relationship_type]
)
- # Definitions of `has_many :blockee_blocks`, `has_many :mutee_mutes` etc.
+ # Definitions of `has_many` relations: :blockee_blocks, :mutee_mutes, :reblog_mutee_mutes,
+ # :notification_mutee_mutes, :subscriber_subscriptions
has_many(incoming_relation, UserRelationship,
foreign_key: :target_id,
where: [relationship_type: relationship_type]
)
- # Definitions of `has_many :blocked_users`, `has_many :muted_users` etc.
+ # Definitions of `has_many` relations: :blocked_users, :muted_users, :reblog_muted_users,
+ # :notification_muted_users, :subscriber_users
has_many(outgoing_relation_target, through: [outgoing_relation, :target])
- # Definitions of `has_many :blocker_users`, `has_many :muter_users` etc.
+ # Definitions of `has_many` relations: :blocker_users, :muter_users, :reblog_muter_users,
+ # :notification_muter_users, :subscribee_users
has_many(incoming_relation_source, through: [incoming_relation, :source])
end
@@ -185,7 +190,9 @@ defmodule Pleroma.User do
for {_relationship_type, [{_outgoing_relation, outgoing_relation_target}, _]} <-
@user_relationships_config do
- # Definitions of `blocked_users_relation/1`, `muted_users_relation/1`, etc.
+ # `def blocked_users_relation/2`, `def muted_users_relation/2`,
+ # `def reblog_muted_users_relation/2`, `def notification_muted_users/2`,
+ # `def subscriber_users/2`
def unquote(:"#{outgoing_relation_target}_relation")(user, restrict_deactivated? \\ false) do
target_users_query = assoc(user, unquote(outgoing_relation_target))
@@ -196,7 +203,8 @@ defmodule Pleroma.User do
end
end
- # Definitions of `blocked_users/1`, `muted_users/1`, etc.
+ # `def blocked_users/2`, `def muted_users/2`, `def reblog_muted_users/2`,
+ # `def notification_muted_users/2`, `def subscriber_users/2`
def unquote(outgoing_relation_target)(user, restrict_deactivated? \\ false) do
__MODULE__
|> apply(unquote(:"#{outgoing_relation_target}_relation"), [
@@ -206,7 +214,8 @@ defmodule Pleroma.User do
|> Repo.all()
end
- # Definitions of `blocked_users_ap_ids/1`, `muted_users_ap_ids/1`, etc.
+ # `def blocked_users_ap_ids/2`, `def muted_users_ap_ids/2`, `def reblog_muted_users_ap_ids/2`,
+ # `def notification_muted_users_ap_ids/2`, `def subscriber_users_ap_ids/2`
def unquote(:"#{outgoing_relation_target}_ap_ids")(user, restrict_deactivated? \\ false) do
__MODULE__
|> apply(unquote(:"#{outgoing_relation_target}_relation"), [
@@ -268,16 +277,12 @@ defmodule Pleroma.User do
end
end
- def profile_url(%User{source_data: %{"url" => url}}), do: url
- def profile_url(%User{ap_id: ap_id}), do: ap_id
- def profile_url(_), do: nil
-
def ap_id(%User{nickname: nickname}), do: "#{Web.base_url()}/users/#{nickname}"
def ap_followers(%User{follower_address: fa}) when is_binary(fa), do: fa
def ap_followers(%User{} = user), do: "#{ap_id(user)}/followers"
- @spec ap_following(User.t()) :: Sring.t()
+ @spec ap_following(User.t()) :: String.t()
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
@@ -417,9 +422,61 @@ defmodule Pleroma.User do
|> validate_format(:nickname, local_nickname_regex())
|> validate_length(:bio, max: bio_limit)
|> validate_length(:name, min: 1, max: name_limit)
+ |> put_fields()
+ |> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)})
+ |> put_change_if_present(:avatar, &put_upload(&1, :avatar))
+ |> put_change_if_present(:banner, &put_upload(&1, :banner))
+ |> put_change_if_present(:background, &put_upload(&1, :background))
+ |> put_change_if_present(
+ :pleroma_settings_store,
+ &{:ok, Map.merge(struct.pleroma_settings_store, &1)}
+ )
|> validate_fields(false)
end
+ defp put_fields(changeset) do
+ if raw_fields = get_change(changeset, :raw_fields) do
+ raw_fields =
+ raw_fields
+ |> Enum.filter(fn %{"name" => n} -> n != "" end)
+
+ fields =
+ raw_fields
+ |> Enum.map(fn f -> Map.update!(f, "value", &parse_fields(&1)) end)
+
+ changeset
+ |> put_change(:raw_fields, raw_fields)
+ |> put_change(:fields, fields)
+ else
+ changeset
+ end
+ end
+
+ defp parse_fields(value) do
+ value
+ |> Formatter.linkify(mentions_format: :full)
+ |> elem(0)
+ end
+
+ defp put_change_if_present(changeset, map_field, value_function) do
+ if value = get_change(changeset, map_field) do
+ with {:ok, new_value} <- value_function.(value) do
+ put_change(changeset, map_field, new_value)
+ else
+ _ -> changeset
+ end
+ else
+ changeset
+ end
+ end
+
+ defp put_upload(value, type) do
+ with %Plug.Upload{} <- value,
+ {:ok, object} <- ActivityPub.upload(value, type: type) do
+ {:ok, object.data}
+ end
+ end
+
def upgrade_changeset(struct, params \\ %{}, remote? \\ false) do
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
@@ -463,6 +520,27 @@ defmodule Pleroma.User do
|> validate_fields(remote?)
end
+ def update_as_admin_changeset(struct, params) do
+ struct
+ |> update_changeset(params)
+ |> cast(params, [:email])
+ |> delete_change(:also_known_as)
+ |> unique_constraint(:email)
+ |> validate_format(:email, @email_regex)
+ end
+
+ @spec update_as_admin(%User{}, map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
+ def update_as_admin(user, params) do
+ params = Map.put(params, "password_confirmation", params["password"])
+ changeset = update_as_admin_changeset(user, params)
+
+ if params["password"] do
+ reset_password(user, changeset, params)
+ else
+ User.update_and_set_cache(changeset)
+ end
+ end
+
def password_update_changeset(struct, params) do
struct
|> cast(params, [:password, :password_confirmation])
@@ -473,10 +551,14 @@ defmodule Pleroma.User do
end
@spec reset_password(User.t(), map) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
- def reset_password(%User{id: user_id} = user, data) do
+ def reset_password(%User{} = user, params) do
+ reset_password(user, user, params)
+ end
+
+ def reset_password(%User{id: user_id} = user, struct, params) do
multi =
Multi.new()
- |> Multi.update(:user, password_update_changeset(user, data))
+ |> Multi.update(:user, password_update_changeset(struct, params))
|> Multi.delete_all(:tokens, OAuth.Token.Query.get_by_user(user_id))
|> Multi.delete_all(:auth, OAuth.Authorization.delete_by_user_query(user))
@@ -1214,13 +1296,15 @@ defmodule Pleroma.User do
end
@doc """
- Returns map of outgoing (blocked, muted etc.) relations' user AP IDs by relation type.
- E.g. `outgoing_relations_ap_ids(user, [:block])` -> `%{block: ["https://some.site/users/userapid"]}`
+ Returns map of outgoing (blocked, muted etc.) relationships' user AP IDs by relation type.
+ E.g. `outgoing_relationships_ap_ids(user, [:block])` -> `%{block: ["https://some.site/users/userapid"]}`
"""
- @spec outgoing_relations_ap_ids(User.t(), list(atom())) :: %{atom() => list(String.t())}
- def outgoing_relations_ap_ids(_, []), do: %{}
+ @spec outgoing_relationships_ap_ids(User.t(), list(atom())) :: %{atom() => list(String.t())}
+ def outgoing_relationships_ap_ids(_user, []), do: %{}
- def outgoing_relations_ap_ids(%User{} = user, relationship_types)
+ def outgoing_relationships_ap_ids(nil, _relationship_types), do: %{}
+
+ def outgoing_relationships_ap_ids(%User{} = user, relationship_types)
when is_list(relationship_types) do
db_result =
user
@@ -1239,6 +1323,30 @@ defmodule Pleroma.User do
)
end
+ def incoming_relationships_ungrouped_ap_ids(user, relationship_types, ap_ids \\ nil)
+
+ def incoming_relationships_ungrouped_ap_ids(_user, [], _ap_ids), do: []
+
+ def incoming_relationships_ungrouped_ap_ids(nil, _relationship_types, _ap_ids), do: []
+
+ def incoming_relationships_ungrouped_ap_ids(%User{} = user, relationship_types, ap_ids)
+ when is_list(relationship_types) do
+ user
+ |> assoc(:incoming_relationships)
+ |> join(:inner, [user_rel], u in assoc(user_rel, :source))
+ |> where([user_rel, u], user_rel.relationship_type in ^relationship_types)
+ |> maybe_filter_on_ap_id(ap_ids)
+ |> select([user_rel, u], u.ap_id)
+ |> distinct(true)
+ |> Repo.all()
+ end
+
+ defp maybe_filter_on_ap_id(query, ap_ids) when is_list(ap_ids) do
+ where(query, [user_rel, u], u.ap_id in ^ap_ids)
+ end
+
+ defp maybe_filter_on_ap_id(query, _ap_ids), do: query
+
def deactivate_async(user, status \\ true) do
BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
end