X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fuser.ex;h=c5b1ddc5da0991b15d4ba93a44a693c00b927b74;hb=292c69481b6baff7511e28e25f51dbd723308241;hp=f1565ade7b94fe9550620c505fa296c3ec449eee;hpb=9ca91cbb8764ef4f8fe5303705dd98984e4e90c0;p=akkoma diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index f1565ade7..c5b1ddc5d 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -10,9 +10,11 @@ defmodule Pleroma.User do alias Comeonin.Pbkdf2 alias Pleroma.Activity + alias Pleroma.Bookmark alias Pleroma.Formatter alias Pleroma.Notification alias Pleroma.Object + alias Pleroma.Registration alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web @@ -52,9 +54,10 @@ defmodule Pleroma.User do field(:search_rank, :float, virtual: true) field(:search_type, :integer, virtual: true) field(:tags, {:array, :string}, default: []) - field(:bookmarks, {:array, :string}, default: []) field(:last_refreshed_at, :naive_datetime_usec) + has_many(:bookmarks, Bookmark) has_many(:notifications, Notification) + has_many(:registrations, Registration) embeds_one(:info, Pleroma.User.Info) timestamps() @@ -216,7 +219,7 @@ defmodule Pleroma.User do changeset = struct |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation]) - |> validate_required([:email, :name, :nickname, :password, :password_confirmation]) + |> validate_required([:name, :nickname, :password, :password_confirmation]) |> validate_confirmation(:password) |> unique_constraint(:email) |> unique_constraint(:nickname) @@ -227,6 +230,13 @@ defmodule Pleroma.User do |> validate_length(:name, min: 1, max: 100) |> put_change(:info, info_change) + changeset = + if opts[:external] do + changeset + else + validate_required(changeset, [:email]) + end + if changeset.valid? do hashed = Pbkdf2.hashpwsalt(changeset.changes[:password]) ap_id = User.ap_id(%User{nickname: changeset.changes[:nickname]}) @@ -260,6 +270,7 @@ defmodule Pleroma.User do def register(%Ecto.Changeset{} = changeset) do with {:ok, user} <- Repo.insert(changeset), {:ok, user} <- autofollow_users(user), + {:ok, user} <- set_cache(user), {:ok, _} <- Pleroma.User.WelcomeMessage.post_welcome_message_to_user(user), {:ok, _} <- try_send_confirmation_email(user) do {:ok, user} @@ -270,8 +281,10 @@ defmodule Pleroma.User do if user.info.confirmation_pending && Pleroma.Config.get([:instance, :account_activation_required]) do user - |> Pleroma.UserEmail.account_confirmation_email() - |> Pleroma.Mailer.deliver_async() + |> Pleroma.Emails.UserEmail.account_confirmation_email() + |> Pleroma.Emails.Mailer.deliver_async() + + {:ok, :enqueued} else {:ok, :noop} end @@ -442,10 +455,13 @@ defmodule Pleroma.User do name = List.last(String.split(ap_id, "/")) nickname = "#{name}@#{domain}" - get_by_nickname(nickname) + get_cached_by_nickname(nickname) end - def set_cache(user) do + def set_cache({:ok, user}), do: set_cache(user) + def set_cache({:error, err}), do: {:error, err} + + def set_cache(%User{} = user) do Cachex.put(:user_cache, "ap_id:#{user.ap_id}", user) Cachex.put(:user_cache, "nickname:#{user.nickname}", user) Cachex.put(:user_cache, "user_info:#{user.id}", user_info(user)) @@ -505,11 +521,10 @@ defmodule Pleroma.User do end end + def get_by_email(email), do: Repo.get_by(User, email: email) + def get_by_nickname_or_email(nickname_or_email) do - case user = Repo.get_by(User, nickname: nickname_or_email) do - %User{} -> user - nil -> Repo.get_by(User, email: nickname_or_email) - end + get_by_nickname(nickname_or_email) || get_by_email(nickname_or_email) end def get_cached_user_info(user) do @@ -534,6 +549,7 @@ defmodule Pleroma.User do with [_nick, _domain] <- String.split(nickname, "@"), {:ok, user} <- fetch_by_nickname(nickname) do if Pleroma.Config.get([:fetch_initial_posts, :enabled]) do + # TODO turn into job {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) end @@ -924,19 +940,27 @@ defmodule Pleroma.User do end def subscribe(subscriber, %{ap_id: ap_id}) do - with %User{} = user <- get_or_fetch_by_ap_id(ap_id) do - info_cng = - user.info - |> User.Info.add_to_subscribers(subscriber.ap_id) + deny_follow_blocked = Pleroma.Config.get([:user, :deny_follow_blocked]) - change(user) - |> put_embed(:info, info_cng) - |> update_and_set_cache() + with %User{} = subscribed <- get_cached_by_ap_id(ap_id) do + blocked = blocks?(subscribed, subscriber) and deny_follow_blocked + + if blocked do + {:error, "Could not subscribe: #{subscribed.nickname} is blocking you"} + else + info_cng = + subscribed.info + |> User.Info.add_to_subscribers(subscriber.ap_id) + + change(subscribed) + |> put_embed(:info, info_cng) + |> update_and_set_cache() + end end end def unsubscribe(unsubscriber, %{ap_id: ap_id}) do - with %User{} = user <- get_or_fetch_by_ap_id(ap_id) do + with %User{} = user <- get_cached_by_ap_id(ap_id) do info_cng = user.info |> User.Info.remove_from_subscribers(unsubscriber.ap_id) @@ -957,10 +981,20 @@ defmodule Pleroma.User do blocker end + blocker = + if subscribed_to?(blocked, blocker) do + {:ok, blocker} = unsubscribe(blocked, blocker) + blocker + else + blocker + end + if following?(blocked, blocker) do unfollow(blocked, blocker) end + {:ok, blocker} = update_follower_count(blocker) + info_cng = blocker.info |> User.Info.add_to_block(ap_id) @@ -974,7 +1008,7 @@ defmodule Pleroma.User do # helper to handle the block given only an actor's AP id def block(blocker, %{ap_id: ap_id}) do - block(blocker, User.get_by_ap_id(ap_id)) + block(blocker, get_cached_by_ap_id(ap_id)) end def unblock(blocker, %{ap_id: ap_id}) do @@ -1004,7 +1038,7 @@ defmodule Pleroma.User do end def subscribed_to?(user, %{ap_id: ap_id}) do - with %User{} = target <- User.get_by_ap_id(ap_id) do + with %User{} = target <- get_cached_by_ap_id(ap_id) do Enum.member?(target.info.subscribers, user.ap_id) end end @@ -1115,6 +1149,14 @@ defmodule Pleroma.User do update_and_set_cache(cng) end + def update_notification_settings(%User{} = user, settings \\ %{}) do + info_changeset = User.Info.update_notification_settings(user.info, settings) + + change(user) + |> put_embed(:info, info_changeset) + |> update_and_set_cache() + end + def delete(%User{} = user) do {:ok, user} = User.deactivate(user) @@ -1171,7 +1213,7 @@ defmodule Pleroma.User do end def get_or_fetch_by_ap_id(ap_id) do - user = get_by_ap_id(ap_id) + user = get_cached_by_ap_id(ap_id) if !is_nil(user) and !User.needs_update?(user) do user @@ -1194,7 +1236,7 @@ defmodule Pleroma.User do def get_or_create_instance_user do relay_uri = "#{Pleroma.Web.Endpoint.url()}/relay" - if user = get_by_ap_id(relay_uri) do + if user = get_cached_by_ap_id(relay_uri) do user else changes = @@ -1241,13 +1283,11 @@ defmodule Pleroma.User do defp blank?(n), do: n def insert_or_update_user(data) do - data = - data - |> Map.put(:name, blank?(data[:name]) || data[:nickname]) - - cs = User.remote_user_creation(data) - - Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname) + data + |> Map.put(:name, blank?(data[:name]) || data[:nickname]) + |> remote_user_creation() + |> Repo.insert(on_conflict: :replace_all, conflict_target: :nickname) + |> set_cache() end def ap_enabled?(%User{local: true}), do: true @@ -1263,8 +1303,8 @@ defmodule Pleroma.User do # this is because we have synchronous follow APIs and need to simulate them # with an async handshake def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do - with %User{} = a <- User.get_by_id(a.id), - %User{} = b <- User.get_by_id(b.id) do + with %User{} = a <- User.get_cached_by_id(a.id), + %User{} = b <- User.get_cached_by_id(b.id) do {:ok, a, b} else _e -> @@ -1274,8 +1314,8 @@ defmodule Pleroma.User do def wait_and_refresh(timeout, %User{} = a, %User{} = b) do with :ok <- :timer.sleep(timeout), - %User{} = a <- User.get_by_id(a.id), - %User{} = b <- User.get_by_id(b.id) do + %User{} = a <- User.get_cached_by_id(a.id), + %User{} = b <- User.get_cached_by_id(b.id) do {:ok, a, b} else _e -> @@ -1314,7 +1354,7 @@ defmodule Pleroma.User do end def tag(nickname, tags) when is_binary(nickname), - do: tag(User.get_by_nickname(nickname), tags) + do: tag(get_by_nickname(nickname), tags) def tag(%User{} = user, tags), do: update_tags(user, Enum.uniq((user.tags || []) ++ normalize_tags(tags))) @@ -1326,7 +1366,7 @@ defmodule Pleroma.User do end def untag(nickname, tags) when is_binary(nickname), - do: untag(User.get_by_nickname(nickname), tags) + do: untag(get_by_nickname(nickname), tags) def untag(%User{} = user, tags), do: update_tags(user, (user.tags || []) -- normalize_tags(tags)) @@ -1340,22 +1380,6 @@ defmodule Pleroma.User do updated_user end - def bookmark(%User{} = user, status_id) do - bookmarks = Enum.uniq(user.bookmarks ++ [status_id]) - update_bookmarks(user, bookmarks) - end - - def unbookmark(%User{} = user, status_id) do - bookmarks = Enum.uniq(user.bookmarks -- [status_id]) - update_bookmarks(user, bookmarks) - end - - def update_bookmarks(%User{} = user, bookmarks) do - user - |> change(%{bookmarks: bookmarks}) - |> update_and_set_cache - end - defp normalize_tags(tags) do [tags] |> List.flatten()