X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=lib%2Fpleroma%2Fuser.ex;h=5e8dfc669ded609bd871d51e24a86395f0abf4a0;hb=97b35e00b049c8f908484163b5ffdbcb55db7867;hp=3878e4efa0b05dc2cdbf2e5cca6664a4473ad68a;hpb=f62019983605dd9af9017351a59b52807bb74ba1;p=akkoma diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 3878e4efa..5e8dfc669 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -8,21 +8,21 @@ defmodule Pleroma.User do import Ecto.Changeset import Ecto.Query + alias Comeonin.Pbkdf2 + alias Pleroma.Activity + alias Pleroma.Formatter + alias Pleroma.Notification + alias Pleroma.Object alias Pleroma.Repo alias Pleroma.User - alias Pleroma.Object alias Pleroma.Web - alias Pleroma.Activity - alias Pleroma.Notification - alias Comeonin.Pbkdf2 - alias Pleroma.Formatter + alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Utils alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils - alias Pleroma.Web.OStatus - alias Pleroma.Web.Websub alias Pleroma.Web.OAuth - alias Pleroma.Web.ActivityPub.Utils - alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.OStatus alias Pleroma.Web.RelMe + alias Pleroma.Web.Websub require Logger @@ -30,6 +30,7 @@ defmodule Pleroma.User do @primary_key {:id, Pleroma.FlakeId, autogenerate: true} + # credo:disable-for-next-line Credo.Check.Readability.MaxLineLength @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])?)*$/ @strict_local_nickname_regex ~r/^[a-zA-Z\d]+$/ @@ -285,7 +286,7 @@ defmodule Pleroma.User do def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true def needs_update?(%User{local: false} = user) do - NaiveDateTime.diff(NaiveDateTime.utc_now(), user.last_refreshed_at) >= 86400 + NaiveDateTime.diff(NaiveDateTime.utc_now(), user.last_refreshed_at) >= 86_400 end def needs_update?(_), do: true @@ -410,7 +411,7 @@ defmodule Pleroma.User do Enum.map( followed_identifiers, fn followed_identifier -> - with %User{} = followed <- get_or_fetch(followed_identifier), + with {:ok, %User{} = followed} <- get_or_fetch(followed_identifier), {:ok, follower} <- maybe_direct_follow(follower, followed), {:ok, _} <- ActivityPub.follow(follower, followed) do followed @@ -435,7 +436,8 @@ defmodule Pleroma.User do Repo.get_by(User, ap_id: ap_id) end - # This is mostly an SPC migration fix. This guesses the user nickname (by taking the last part of the ap_id and the domain) and tries to get that user + # This is mostly an SPC migration fix. This guesses the user nickname by taking the last part + # of the ap_id and the domain and tries to get that user def get_by_guessed_nickname(ap_id) do domain = URI.parse(ap_id).host name = List.last(String.split(ap_id, "/")) @@ -490,7 +492,15 @@ defmodule Pleroma.User do def get_cached_by_nickname(nickname) do key = "nickname:#{nickname}" - Cachex.fetch!(:user_cache, key, fn _ -> get_or_fetch_by_nickname(nickname) end) + + Cachex.fetch!(:user_cache, key, fn -> + user_result = get_or_fetch_by_nickname(nickname) + + case user_result do + {:ok, user} -> {:commit, user} + {:error, error} -> {:ignore, error} + end + end) end def get_cached_by_nickname_or_id(nickname_or_id) do @@ -527,18 +537,33 @@ defmodule Pleroma.User do def get_or_fetch_by_nickname(nickname) do with %User{} = user <- get_by_nickname(nickname) do - user + {:ok, user} else _e -> with [_nick, _domain] <- String.split(nickname, "@"), {:ok, user} <- fetch_by_nickname(nickname) do - user + if Pleroma.Config.get([:fetch_initial_posts, :enabled]) do + {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) + end + + {:ok, user} else - _e -> nil + e -> {:error, e} end end end + @doc "Fetch some posts when the user has just been federated with" + def fetch_initial_posts(user) do + pages = Pleroma.Config.get!([:fetch_initial_posts, :pages]) + + Enum.each( + # Insert all the posts in reverse order, so they're in the right order on the timeline + Enum.reverse(Utils.fetch_ordered_collection(user.info.source_data["outbox"], pages)), + &Pleroma.Web.Federator.incoming_ap_doc/1 + ) + end + def get_followers_query(%User{id: id, follower_address: follower_address}, nil) do from( u in User, @@ -922,7 +947,7 @@ defmodule Pleroma.User do Enum.map( blocked_identifiers, fn blocked_identifier -> - with %User{} = blocked <- get_or_fetch(blocked_identifier), + with {:ok, %User{} = blocked} <- get_or_fetch(blocked_identifier), {:ok, blocker} <- block(blocker, blocked), {:ok, _} <- ActivityPub.block(blocker, blocked) do blocked @@ -1121,23 +1146,35 @@ defmodule Pleroma.User do def html_filter_policy(_), do: @default_scrubbers + def fetch_by_ap_id(ap_id) do + ap_try = ActivityPub.make_user_from_ap_id(ap_id) + + case ap_try do + {:ok, user} -> + user + + _ -> + case OStatus.make_user(ap_id) do + {:ok, user} -> user + _ -> {:error, "Could not fetch by AP id"} + end + end + end + def get_or_fetch_by_ap_id(ap_id) do user = get_by_ap_id(ap_id) if !is_nil(user) and !User.needs_update?(user) do - user + {:ok, user} else - ap_try = ActivityPub.make_user_from_ap_id(ap_id) - - case ap_try do - {:ok, user} -> - user + with %User{} = user <- fetch_by_ap_id(ap_id) do + if Pleroma.Config.get([:fetch_initial_posts, :enabled]) do + {:ok, _} = Task.start(__MODULE__, :fetch_initial_posts, [user]) + end - _ -> - case OStatus.make_user(ap_id) do - {:ok, user} -> user - _ -> {:error, "Could not fetch by AP id"} - end + {:ok, user} + else + _ -> {:error, "Could not fetch by AP id"} end end end @@ -1180,7 +1217,7 @@ defmodule Pleroma.User do end def get_public_key_for_ap_id(ap_id) do - with %User{} = user <- get_or_fetch_by_ap_id(ap_id), + with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id), {:ok, public_key} <- public_key_from_info(user.info) do {:ok, public_key} else @@ -1313,7 +1350,7 @@ defmodule Pleroma.User do |> Enum.map(&String.downcase(&1)) end - defp local_nickname_regex() do + defp local_nickname_regex do if Pleroma.Config.get([:instance, :extended_nickname_format]) do @extended_local_nickname_regex else