diff options
Diffstat (limited to 'lib')
31 files changed, 218 insertions, 94 deletions
diff --git a/lib/healthcheck.ex b/lib/healthcheck.ex new file mode 100644 index 000000000..646fb3b9d --- /dev/null +++ b/lib/healthcheck.ex @@ -0,0 +1,60 @@ +defmodule Pleroma.Healthcheck do +  @moduledoc """ +  Module collects metrics about app and assign healthy status. +  """ +  alias Pleroma.Healthcheck +  alias Pleroma.Repo + +  defstruct pool_size: 0, +            active: 0, +            idle: 0, +            memory_used: 0, +            healthy: true + +  @type t :: %__MODULE__{ +          pool_size: non_neg_integer(), +          active: non_neg_integer(), +          idle: non_neg_integer(), +          memory_used: number(), +          healthy: boolean() +        } + +  @spec system_info() :: t() +  def system_info do +    %Healthcheck{ +      memory_used: Float.round(:erlang.memory(:total) / 1024 / 1024, 2) +    } +    |> assign_db_info() +    |> check_health() +  end + +  defp assign_db_info(healthcheck) do +    database = Application.get_env(:pleroma, Repo)[:database] + +    query = +      "select state, count(pid) from pg_stat_activity where datname = '#{database}' group by state;" + +    result = Repo.query!(query) +    pool_size = Application.get_env(:pleroma, Repo)[:pool_size] + +    db_info = +      Enum.reduce(result.rows, %{active: 0, idle: 0}, fn [state, cnt], states -> +        if state == "active" do +          Map.put(states, :active, states.active + cnt) +        else +          Map.put(states, :idle, states.idle + cnt) +        end +      end) +      |> Map.put(:pool_size, pool_size) + +    Map.merge(healthcheck, db_info) +  end + +  @spec check_health(Healthcheck.t()) :: Healthcheck.t() +  def check_health(%{pool_size: pool_size, active: active} = check) +      when active >= pool_size do +    %{check | healthy: false} +  end + +  def check_health(check), do: check +end diff --git a/lib/mix/tasks/pleroma/emoji.ex b/lib/mix/tasks/pleroma/emoji.ex index 2754dd876..cced73226 100644 --- a/lib/mix/tasks/pleroma/emoji.ex +++ b/lib/mix/tasks/pleroma/emoji.ex @@ -11,7 +11,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do    ## ls-packs -  mix pleroma.emoji ls-packs [OPTION...] +      mix pleroma.emoji ls-packs [OPTION...]    Lists the emoji packs and metadata specified in the manifest. @@ -23,10 +23,10 @@ defmodule Mix.Tasks.Pleroma.Emoji do    ## get-packs -  mix pleroma.emoji get-packs [OPTION...] PACKS +      mix pleroma.emoji get-packs [OPTION...] PACKS    Fetches, verifies and installs the specified PACKS from the -  manifest into the `STATIC-DIR/emoji/PACK-NAME +  manifest into the `STATIC-DIR/emoji/PACK-NAME`    ### Options @@ -34,7 +34,7 @@ defmodule Mix.Tasks.Pleroma.Emoji do    ## gen-pack -  mix pleroma.emoji gen-pack PACK-URL +      mix pleroma.emoji gen-pack PACK-URL    Creates a new manifest entry and a file list from the specified    remote pack file. Currently, only .zip archives are recognized diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 441168df2..b396ff0de 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -162,7 +162,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["rm", nickname]) do      Common.start_pleroma() -    with %User{local: true} = user <- User.get_by_nickname(nickname) do +    with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do        User.delete(user)        Mix.shell().info("User #{nickname} deleted.")      else @@ -174,7 +174,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["toggle_activated", nickname]) do      Common.start_pleroma() -    with %User{} = user <- User.get_by_nickname(nickname) do +    with %User{} = user <- User.get_cached_by_nickname(nickname) do        {:ok, user} = User.deactivate(user, !user.info.deactivated)        Mix.shell().info( @@ -189,7 +189,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["reset_password", nickname]) do      Common.start_pleroma() -    with %User{local: true} = user <- User.get_by_nickname(nickname), +    with %User{local: true} = user <- User.get_cached_by_nickname(nickname),           {:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do        Mix.shell().info("Generated password reset token for #{user.nickname}") @@ -211,14 +211,14 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["unsubscribe", nickname]) do      Common.start_pleroma() -    with %User{} = user <- User.get_by_nickname(nickname) do +    with %User{} = user <- User.get_cached_by_nickname(nickname) do        Mix.shell().info("Deactivating #{user.nickname}")        User.deactivate(user)        {:ok, friends} = User.get_friends(user)        Enum.each(friends, fn friend -> -        user = User.get_by_id(user.id) +        user = User.get_cached_by_id(user.id)          Mix.shell().info("Unsubscribing #{friend.nickname} from #{user.nickname}")          User.unfollow(user, friend) @@ -226,7 +226,7 @@ defmodule Mix.Tasks.Pleroma.User do        :timer.sleep(500) -      user = User.get_by_id(user.id) +      user = User.get_cached_by_id(user.id)        if Enum.empty?(user.following) do          Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}") @@ -250,7 +250,7 @@ defmodule Mix.Tasks.Pleroma.User do          ]        ) -    with %User{local: true} = user <- User.get_by_nickname(nickname) do +    with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do        user =          case Keyword.get(options, :moderator) do            nil -> user @@ -277,7 +277,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["tag", nickname | tags]) do      Common.start_pleroma() -    with %User{} = user <- User.get_by_nickname(nickname) do +    with %User{} = user <- User.get_cached_by_nickname(nickname) do        user = user |> User.tag(tags)        Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}") @@ -290,7 +290,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["untag", nickname | tags]) do      Common.start_pleroma() -    with %User{} = user <- User.get_by_nickname(nickname) do +    with %User{} = user <- User.get_cached_by_nickname(nickname) do        user = user |> User.untag(tags)        Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}") @@ -379,7 +379,7 @@ defmodule Mix.Tasks.Pleroma.User do    def run(["delete_activities", nickname]) do      Common.start_pleroma() -    with %User{local: true} = user <- User.get_by_nickname(nickname) do +    with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do        User.delete_user_activities(user)        Mix.shell().info("User #{nickname} statuses deleted.")      else diff --git a/lib/pleroma/PasswordResetToken.ex b/lib/pleroma/PasswordResetToken.ex index 7afbc8751..f31ea5bc5 100644 --- a/lib/pleroma/PasswordResetToken.ex +++ b/lib/pleroma/PasswordResetToken.ex @@ -39,7 +39,7 @@ defmodule Pleroma.PasswordResetToken do    def reset_password(token, data) do      with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), -         %User{} = user <- User.get_by_id(token.user_id), +         %User{} = user <- User.get_cached_by_id(token.user_id),           {:ok, _user} <- User.reset_password(user, data),           {:ok, token} <- Repo.update(used_changeset(token)) do        {:ok, token} diff --git a/lib/pleroma/gopher/server.ex b/lib/pleroma/gopher/server.ex index 2ebc5d5f7..1d2e0785c 100644 --- a/lib/pleroma/gopher/server.ex +++ b/lib/pleroma/gopher/server.ex @@ -76,7 +76,7 @@ defmodule Pleroma.Gopher.Server.ProtocolHandler do      |> Enum.map(fn activity ->        user = User.get_cached_by_ap_id(activity.data["actor"]) -      object = Object.normalize(activity.data["object"]) +      object = Object.normalize(activity)        like_count = object["like_count"] || 0        announcement_count = object["announcement_count"] || 0 diff --git a/lib/pleroma/list.ex b/lib/pleroma/list.ex index 110be8355..a5b1cad68 100644 --- a/lib/pleroma/list.ex +++ b/lib/pleroma/list.ex @@ -80,7 +80,7 @@ defmodule Pleroma.List do    # Get lists to which the account belongs.    def get_lists_account_belongs(%User{} = owner, account_id) do -    user = User.get_by_id(account_id) +    user = User.get_cached_by_id(account_id)      query =        from( diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 585157efe..844264307 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -203,7 +203,7 @@ defmodule Pleroma.Notification do    def skip?(:follows, activity, %{info: %{notification_settings: %{"follows" => false}}} = user) do      actor = activity.data["actor"] -    followed = User.get_by_ap_id(actor) +    followed = User.get_cached_by_ap_id(actor)      User.following?(user, followed)    end diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index 138e7866f..8d4bcc95e 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -39,7 +39,7 @@ defmodule Pleroma.Object.Fetcher do            Logger.info("Couldn't get object via AP, trying out OStatus fetching...")            case OStatus.fetch_activity_from_url(id) do -            {:ok, [activity | _]} -> {:ok, Object.normalize(activity.data["object"], false)} +            {:ok, [activity | _]} -> {:ok, Object.normalize(activity, false)}              e -> e            end        end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 6aaa3244f..d103cd809 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -284,6 +284,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} @@ -468,10 +469,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)) @@ -559,6 +563,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 @@ -1021,7 +1026,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 @@ -1051,7 +1056,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 @@ -1239,7 +1244,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 @@ -1262,7 +1267,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 = @@ -1309,13 +1314,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 @@ -1331,8 +1334,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 -> @@ -1342,8 +1345,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 -> @@ -1382,7 +1385,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))) @@ -1394,7 +1397,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)) diff --git a/lib/pleroma/user/info.ex b/lib/pleroma/user/info.ex index 5afa7988c..7f22a45b5 100644 --- a/lib/pleroma/user/info.ex +++ b/lib/pleroma/user/info.ex @@ -38,6 +38,7 @@ defmodule Pleroma.User.Info do      field(:salmon, :string, default: nil)      field(:hide_followers, :boolean, default: false)      field(:hide_follows, :boolean, default: false) +    field(:hide_favorites, :boolean, default: true)      field(:pinned_activities, {:array, :string}, default: [])      field(:flavour, :string, default: nil) @@ -202,6 +203,7 @@ defmodule Pleroma.User.Info do        :banner,        :hide_follows,        :hide_followers, +      :hide_favorites,        :background,        :show_role      ]) diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index a345372e2..6bf54d1cc 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -168,7 +168,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      public = "https://www.w3.org/ns/activitystreams#Public"      if activity.data["type"] in ["Create", "Announce", "Delete"] do -      object = Object.normalize(activity.data["object"]) +      object = Object.normalize(activity)        Pleroma.Web.Streamer.stream("user", activity)        Pleroma.Web.Streamer.stream("list", activity) @@ -197,7 +197,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do          if !Enum.member?(activity.data["cc"] || [], public) &&               !Enum.member?(                 activity.data["to"], -               User.get_by_ap_id(activity.data["actor"]).follower_address +               User.get_cached_by_ap_id(activity.data["actor"]).follower_address               ),             do: Pleroma.Web.Streamer.stream("direct", activity)        end @@ -890,7 +890,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    end    def make_user_from_ap_id(ap_id) do -    if _user = User.get_by_ap_id(ap_id) do +    if _user = User.get_cached_by_ap_id(ap_id) do        Transmogrifier.upgrade_user_from_ap_id(ap_id)      else        with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id) do diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex index a80aa52c6..52666a409 100644 --- a/lib/pleroma/web/activity_pub/transmogrifier.ex +++ b/lib/pleroma/web/activity_pub/transmogrifier.ex @@ -537,7 +537,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do            data        )        when object_type in ["Person", "Application", "Service", "Organization"] do -    with %User{ap_id: ^actor_id} = actor <- User.get_by_ap_id(object["id"]) do +    with %User{ap_id: ^actor_id} = actor <- User.get_cached_by_ap_id(object["id"]) do        {:ok, new_user_data} = ActivityPub.user_data_from_user_object(object)        banner = new_user_data[:info]["banner"] @@ -964,7 +964,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do    end    def upgrade_user_from_ap_id(ap_id) do -    with %User{local: false} = user <- User.get_by_ap_id(ap_id), +    with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id),           {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id),           already_ap <- User.ap_enabled?(user),           {:ok, user} <- user |> User.upgrade_changeset(data) |> User.update_and_set_cache() do diff --git a/lib/pleroma/web/admin_api/admin_api_controller.ex b/lib/pleroma/web/admin_api/admin_api_controller.ex index c436715d5..711f233a6 100644 --- a/lib/pleroma/web/admin_api/admin_api_controller.ex +++ b/lib/pleroma/web/admin_api/admin_api_controller.ex @@ -19,7 +19,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    action_fallback(:errors)    def user_delete(conn, %{"nickname" => nickname}) do -    User.get_by_nickname(nickname) +    User.get_cached_by_nickname(nickname)      |> User.delete()      conn @@ -27,8 +27,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def user_follow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do -    with %User{} = follower <- User.get_by_nickname(follower_nick), -         %User{} = followed <- User.get_by_nickname(followed_nick) do +    with %User{} = follower <- User.get_cached_by_nickname(follower_nick), +         %User{} = followed <- User.get_cached_by_nickname(followed_nick) do        User.follow(follower, followed)      end @@ -37,8 +37,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def user_unfollow(conn, %{"follower" => follower_nick, "followed" => followed_nick}) do -    with %User{} = follower <- User.get_by_nickname(follower_nick), -         %User{} = followed <- User.get_by_nickname(followed_nick) do +    with %User{} = follower <- User.get_cached_by_nickname(follower_nick), +         %User{} = followed <- User.get_cached_by_nickname(followed_nick) do        User.unfollow(follower, followed)      end @@ -67,7 +67,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def user_show(conn, %{"nickname" => nickname}) do -    with %User{} = user <- User.get_by_nickname(nickname) do +    with %User{} = user <- User.get_cached_by_nickname(nickname) do        conn        |> json(AccountView.render("show.json", %{user: user}))      else @@ -76,7 +76,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def user_toggle_activation(conn, %{"nickname" => nickname}) do -    user = User.get_by_nickname(nickname) +    user = User.get_cached_by_nickname(nickname)      {:ok, updated_user} = User.deactivate(user, !user.info.deactivated) @@ -131,7 +131,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    def right_add(conn, %{"permission_group" => permission_group, "nickname" => nickname})        when permission_group in ["moderator", "admin"] do -    user = User.get_by_nickname(nickname) +    user = User.get_cached_by_nickname(nickname)      info =        %{} @@ -156,7 +156,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    end    def right_get(conn, %{"nickname" => nickname}) do -    user = User.get_by_nickname(nickname) +    user = User.get_cached_by_nickname(nickname)      conn      |> json(%{ @@ -178,7 +178,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do        |> put_status(403)        |> json(%{error: "You can't revoke your own admin status."})      else -      user = User.get_by_nickname(nickname) +      user = User.get_cached_by_nickname(nickname)        info =          %{} @@ -204,7 +204,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    def set_activation_status(conn, %{"nickname" => nickname, "status" => status}) do      with {:ok, status} <- Ecto.Type.cast(:boolean, status), -         %User{} = user <- User.get_by_nickname(nickname), +         %User{} = user <- User.get_cached_by_nickname(nickname),           {:ok, _} <- User.deactivate(user, !status),           do: json_response(conn, :no_content, "")    end @@ -277,7 +277,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do    @doc "Get a password reset token (base64 string) for given nickname"    def get_password_reset(conn, %{"nickname" => nickname}) do -    (%User{local: true} = user) = User.get_by_nickname(nickname) +    (%User{local: true} = user) = User.get_cached_by_nickname(nickname)      {:ok, token} = Pleroma.PasswordResetToken.create_token(user)      conn diff --git a/lib/pleroma/web/channels/user_socket.ex b/lib/pleroma/web/channels/user_socket.ex index 6503979a1..8e2759e3b 100644 --- a/lib/pleroma/web/channels/user_socket.ex +++ b/lib/pleroma/web/channels/user_socket.ex @@ -24,7 +24,7 @@ defmodule Pleroma.Web.UserSocket do    def connect(%{"token" => token}, socket) do      with true <- Pleroma.Config.get([:chat, :enabled]),           {:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600), -         %User{} = user <- Pleroma.User.get_by_id(user_id) do +         %User{} = user <- Pleroma.User.get_cached_by_id(user_id) do        {:ok, assign(socket, :user_name, user.nickname)}      else        _e -> :error diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex index 6458a3449..cfbc5dc10 100644 --- a/lib/pleroma/web/common_api/common_api.ex +++ b/lib/pleroma/web/common_api/common_api.ex @@ -284,7 +284,7 @@ defmodule Pleroma.Web.CommonAPI do    def report(user, data) do      with {:account_id, %{"account_id" => account_id}} <- {:account_id, data}, -         {:account, %User{} = account} <- {:account, User.get_by_id(account_id)}, +         {:account, %User{} = account} <- {:account, User.get_cached_by_id(account_id)},           {:ok, {content_html, _, _}} <- make_report_content_html(data["comment"]),           {:ok, statuses} <- get_report_statuses(account, data),           {:ok, activity} <- diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index 25f498fcb..887f878c4 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -226,7 +226,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do      }      if in_reply_to do -      in_reply_to_object = Object.normalize(in_reply_to.data["object"]) +      in_reply_to_object = Object.normalize(in_reply_to)        object        |> Map.put("inReplyTo", in_reply_to_object.data["id"]) @@ -284,7 +284,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do    end    def confirm_current_password(user, password) do -    with %User{local: true} = db_user <- User.get_by_id(user.id), +    with %User{local: true} = db_user <- User.get_cached_by_id(user.id),           true <- Pbkdf2.checkpw(password, db_user.password_hash) do        {:ok, db_user}      else diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index 1b4deb6dc..29e178ba9 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -186,7 +186,7 @@ defmodule Pleroma.Web.Federator do    end    def ap_enabled_actor(id) do -    user = User.get_by_ap_id(id) +    user = User.get_cached_by_ap_id(id)      if User.ap_enabled?(user) do        {:ok, user} diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index d271d3786..0ba8d9eea 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -304,7 +304,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do -    with %User{} = user <- User.get_by_id(params["id"]) do +    with %User{} = user <- User.get_cached_by_id(params["id"]) do        activities = ActivityPub.fetch_user_activities(user, reading_user, params)        conn @@ -546,7 +546,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do      with %Activity{} = activity <- Activity.get_by_id_with_object(id),           %Object{} = object <- Object.normalize(activity), -         %User{} = user <- User.get_by_nickname(user.nickname), +         %User{} = user <- User.get_cached_by_nickname(user.nickname),           true <- Visibility.visible_for_user?(activity, user),           {:ok, user} <- User.bookmark(user, object.data["id"]) do        conn @@ -558,7 +558,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do      with %Activity{} = activity <- Activity.get_by_id_with_object(id),           %Object{} = object <- Object.normalize(activity), -         %User{} = user <- User.get_by_nickname(user.nickname), +         %User{} = user <- User.get_cached_by_nickname(user.nickname),           true <- Visibility.visible_for_user?(activity, user),           {:ok, user} <- User.unbookmark(user, object.data["id"]) do        conn @@ -750,7 +750,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do -    with %User{} = user <- User.get_by_id(id), +    with %User{} = user <- User.get_cached_by_id(id),           followers <- MastodonAPI.get_followers(user, params) do        followers =          cond do @@ -767,7 +767,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def following(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do -    with %User{} = user <- User.get_by_id(id), +    with %User{} = user <- User.get_cached_by_id(id),           followers <- MastodonAPI.get_friends(user, params) do        followers =          cond do @@ -792,7 +792,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do -    with %User{} = follower <- User.get_by_id(id), +    with %User{} = follower <- User.get_cached_by_id(id),           {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do        conn        |> put_view(AccountView) @@ -806,7 +806,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do -    with %User{} = follower <- User.get_by_id(id), +    with %User{} = follower <- User.get_cached_by_id(id),           {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do        conn        |> put_view(AccountView) @@ -872,7 +872,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do -    with %User{} = muted <- User.get_by_id(id), +    with %User{} = muted <- User.get_cached_by_id(id),           {:ok, muter} <- User.mute(muter, muted) do        conn        |> put_view(AccountView) @@ -886,7 +886,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def unmute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do -    with %User{} = muted <- User.get_by_id(id), +    with %User{} = muted <- User.get_cached_by_id(id),           {:ok, muter} <- User.unmute(muter, muted) do        conn        |> put_view(AccountView) @@ -907,7 +907,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do -    with %User{} = blocked <- User.get_by_id(id), +    with %User{} = blocked <- User.get_cached_by_id(id),           {:ok, blocker} <- User.block(blocker, blocked),           {:ok, _activity} <- ActivityPub.block(blocker, blocked) do        conn @@ -922,7 +922,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    end    def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do -    with %User{} = blocked <- User.get_by_id(id), +    with %User{} = blocked <- User.get_cached_by_id(id),           {:ok, blocker} <- User.unblock(blocker, blocked),           {:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do        conn @@ -1087,8 +1087,45 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      |> render("index.json", %{activities: activities, for: user, as: :activity})    end +  def user_favourites(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do +    with %User{} = user <- User.get_by_id(id), +         false <- user.info.hide_favorites do +      params = +        params +        |> Map.put("type", "Create") +        |> Map.put("favorited_by", user.ap_id) +        |> Map.put("blocking_user", for_user) + +      recipients = +        if for_user do +          ["https://www.w3.org/ns/activitystreams#Public"] ++ +            [for_user.ap_id | for_user.following] +        else +          ["https://www.w3.org/ns/activitystreams#Public"] +        end + +      activities = +        recipients +        |> ActivityPub.fetch_activities(params) +        |> Enum.reverse() + +      conn +      |> add_link_headers(:favourites, activities) +      |> put_view(StatusView) +      |> render("index.json", %{activities: activities, for: for_user, as: :activity}) +    else +      nil -> +        {:error, :not_found} + +      true -> +        conn +        |> put_status(403) +        |> json(%{error: "Can't get favorites"}) +    end +  end +    def bookmarks(%{assigns: %{user: user}} = conn, _) do -    user = User.get_by_id(user.id) +    user = User.get_cached_by_id(user.id)      activities =        user.bookmarks @@ -1145,7 +1182,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      accounts      |> Enum.each(fn account_id ->        with %Pleroma.List{} = list <- Pleroma.List.get(id, user), -           %User{} = followed <- User.get_by_id(account_id) do +           %User{} = followed <- User.get_cached_by_id(account_id) do          Pleroma.List.follow(list, followed)        end      end) @@ -1157,7 +1194,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      accounts      |> Enum.each(fn account_id ->        with %Pleroma.List{} = list <- Pleroma.List.get(id, user), -           %User{} = followed <- Pleroma.User.get_by_id(account_id) do +           %User{} = followed <- Pleroma.User.get_cached_by_id(account_id) do          Pleroma.List.unfollow(list, followed)        end      end) @@ -1450,7 +1487,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do      Logger.debug("Unimplemented, returning unmodified relationship") -    with %User{} = target <- User.get_by_id(id) do +    with %User{} = target <- User.get_cached_by_id(id) do        conn        |> put_view(AccountView)        |> render("relationship.json", %{user: user, target: target}) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index af56c4149..d87fdb15d 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -68,7 +68,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do    defp do_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) +    user_info = User.get_cached_user_info(user)      bot = (user.info.source_data["type"] || "Person") in ["Application", "Service"]      emojis = diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 17c33080b..7dd80d708 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -31,7 +31,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do      |> Activity.create_by_object_ap_id()      |> Repo.all()      |> Enum.reduce(%{}, fn activity, acc -> -      object = Object.normalize(activity.data["object"]) +      object = Object.normalize(activity)        Map.put(acc, object.data["id"], activity)      end)    end @@ -238,6 +238,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do        pleroma: %{          local: activity.local,          conversation_id: get_context_id(activity), +        in_reply_to_account_acct: reply_to_user && reply_to_user.nickname,          content: %{"text/plain" => content_plaintext},          spoiler_text: %{"text/plain" => summary_plaintext}        } @@ -316,7 +317,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do    end    def get_reply_to(activity, %{replied_to_activities: replied_to_activities}) do -    object = Object.normalize(activity.data["object"]) +    object = Object.normalize(activity)      with nil <- replied_to_activities[object.data["inReplyTo"]] do        # If user didn't participate in the thread diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index 1b3721e2b..abfa26754 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -90,7 +90,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do    # Authenticated streams.    defp allow_request(stream, {"access_token", access_token}) when stream in @streams do      with %Token{user_id: user_id} <- Repo.get_by(Token, token: access_token), -         user = %User{} <- User.get_by_id(user_id) do +         user = %User{} <- User.get_cached_by_id(user_id) do        {:ok, user}      else        _ -> {:error, 403} diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 5ea04635d..688eaca11 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -143,7 +143,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do           fixed_token = fix_padding(params["code"]),           %Authorization{} = auth <-             Repo.get_by(Authorization, token: fixed_token, app_id: app.id), -         %User{} = user <- User.get_by_id(auth.user_id), +         %User{} = user <- User.get_cached_by_id(auth.user_id),           {:ok, token} <- Token.exchange_token(app, auth),           {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do        response = %{ diff --git a/lib/pleroma/web/oauth/token.ex b/lib/pleroma/web/oauth/token.ex index 2b5ad9b94..399140003 100644 --- a/lib/pleroma/web/oauth/token.ex +++ b/lib/pleroma/web/oauth/token.ex @@ -27,7 +27,7 @@ defmodule Pleroma.Web.OAuth.Token do    def exchange_token(app, auth) do      with {:ok, auth} <- Authorization.use_token(auth),           true <- auth.app_id == app.id do -      create_token(app, User.get_by_id(auth.user_id), auth.scopes) +      create_token(app, User.get_cached_by_id(auth.user_id), auth.scopes)      end    end diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex index b11a2b5ce..166691a09 100644 --- a/lib/pleroma/web/ostatus/activity_representer.ex +++ b/lib/pleroma/web/ostatus/activity_representer.ex @@ -84,7 +84,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do    def to_simple_form(%{data: %{"type" => "Create"}} = activity, user, with_author) do      h = fn str -> [to_charlist(str)] end -    object = Object.normalize(activity.data["object"]) +    object = Object.normalize(activity)      updated_at = object.data["published"]      inserted_at = object.data["published"] diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 9a34d7ad5..4744c6d83 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -294,7 +294,7 @@ defmodule Pleroma.Web.OStatus do        }        with false <- update, -           %User{} = user <- User.get_by_ap_id(data.ap_id) do +           %User{} = user <- User.get_cached_by_ap_id(data.ap_id) do          {:ok, user}        else          _e -> User.insert_or_update_user(data) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index f475de639..5f7617ece 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -135,6 +135,7 @@ defmodule Pleroma.Web.Router do      post("/password_reset", UtilController, :password_reset)      get("/emoji", UtilController, :emoji)      get("/captcha", UtilController, :captcha) +    get("/healthcheck", UtilController, :healthcheck)    end    scope "/api/pleroma", Pleroma.Web do @@ -395,6 +396,8 @@ defmodule Pleroma.Web.Router do        get("/accounts/:id", MastodonAPIController, :user)        get("/search", MastodonAPIController, :search) + +      get("/pleroma/accounts/:id/favourites", MastodonAPIController, :user_favourites)      end    end diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index a82109f92..72eaf2084 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -81,7 +81,7 @@ defmodule Pleroma.Web.Streamer do          _ ->            Pleroma.List.get_lists_from_activity(item)            |> Enum.filter(fn list -> -            owner = User.get_by_id(list.user_id) +            owner = User.get_cached_by_id(list.user_id)              Visibility.visible_for_user?(item, owner)            end) diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index 9b0cf2b07..6c8c2fe24 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -22,7 +22,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do    def show_password_reset(conn, %{"token" => token}) do      with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), -         %User{} = user <- User.get_by_id(token.user_id) do +         %User{} = user <- User.get_cached_by_id(token.user_id) do        render(conn, "password_reset.html", %{          token: token,          user: user @@ -113,13 +113,13 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do    def do_remote_follow(conn, %{          "authorization" => %{"name" => username, "password" => password, "id" => id}        }) do -    followee = User.get_by_id(id) +    followee = User.get_cached_by_id(id)      avatar = User.avatar_url(followee)      name = followee.nickname      with %User{} = user <- User.get_cached_by_nickname(username),           true <- Pbkdf2.checkpw(password, user.password_hash), -         %User{} = _followed <- User.get_by_id(id), +         %User{} = _followed <- User.get_cached_by_id(id),           {:ok, follower} <- User.follow(user, followee),           {:ok, _activity} <- ActivityPub.follow(follower, followee) do        conn @@ -141,7 +141,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do    end    def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do -    with %User{} = followee <- User.get_by_id(id), +    with %User{} = followee <- User.get_cached_by_id(id),           {:ok, follower} <- User.follow(user, followee),           {:ok, _activity} <- ActivityPub.follow(follower, followee) do        conn @@ -374,4 +374,22 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do    def captcha(conn, _params) do      json(conn, Pleroma.Captcha.new())    end + +  def healthcheck(conn, _params) do +    info = +      if Pleroma.Config.get([:instance, :healthcheck]) do +        Pleroma.Healthcheck.system_info() +      else +        %{} +      end + +    conn = +      if info[:healthy] do +        conn +      else +        Plug.Conn.put_status(conn, :service_unavailable) +      end + +    json(conn, info) +  end  end diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index c3f769c00..2353a95a8 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -243,7 +243,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do          end        %{"screen_name" => nickname} -> -        case User.get_by_nickname(nickname) do +        case User.get_cached_by_nickname(nickname) do            nil -> {:error, "No user with such screen_name"}            target -> {:ok, target}          end diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index a7ec9949c..79ed9dad2 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -434,7 +434,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    end    def confirm_email(conn, %{"user_id" => uid, "token" => token}) do -    with %User{} = user <- User.get_by_id(uid), +    with %User{} = user <- User.get_cached_by_id(uid),           true <- user.local,           true <- user.info.confirmation_pending,           true <- user.info.confirmation_token == token, @@ -587,7 +587,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    def approve_friend_request(conn, %{"user_id" => uid} = _params) do      with followed <- conn.assigns[:user], -         %User{} = follower <- User.get_by_id(uid), +         %User{} = follower <- User.get_cached_by_id(uid),           {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do        conn        |> put_view(UserView) @@ -599,7 +599,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    def deny_friend_request(conn, %{"user_id" => uid} = _params) do      with followed <- conn.assigns[:user], -         %User{} = follower <- User.get_by_id(uid), +         %User{} = follower <- User.get_cached_by_id(uid),           {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do        conn        |> put_view(UserView) @@ -632,7 +632,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do    defp build_info_cng(user, params) do      info_params = -      ["no_rich_text", "locked", "hide_followers", "hide_follows", "show_role"] +      ["no_rich_text", "locked", "hide_followers", "hide_follows", "hide_favorites", "show_role"]        |> Enum.reduce(%{}, fn key, res ->          if value = params[key] do            Map.put(res, key, value == "true") diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 32c3455f5..a3b0bf999 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -37,7 +37,7 @@ defmodule Pleroma.Web.WebFinger do      regex = ~r/(acct:)?(?<username>\w+)@#{host}/      with %{"username" => username} <- Regex.named_captures(regex, resource), -         %User{} = user <- User.get_by_nickname(username) do +         %User{} = user <- User.get_cached_by_nickname(username) do        {:ok, represent_user(user, fmt)}      else        _e ->  | 
