Merge branch 'dialyzer-fixes' into 'develop'

Dialyzer fixes

See merge request pleroma/pleroma!4035
This commit is contained in:
feld 2024-01-21 00:54:25 +00:00
commit 1edfce4322
34 changed files with 141 additions and 120 deletions

View file

View file

@ -79,6 +79,10 @@ IO.puts("RUM enabled: #{rum_enabled}")
config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
config :pleroma, Pleroma.Application,
background_migrators: false,
streamer_registry: false
if File.exists?("./config/benchmark.secret.exs") do if File.exists?("./config/benchmark.secret.exs") do
import_config "benchmark.secret.exs" import_config "benchmark.secret.exs"
else else

View file

@ -904,6 +904,13 @@ config :pleroma, Pleroma.Search.Meilisearch,
private_key: nil, private_key: nil,
initial_indexing_chunk_size: 100_000 initial_indexing_chunk_size: 100_000
config :pleroma, Pleroma.Application,
background_migrators: true,
internal_fetch: true,
load_custom_modules: true,
max_restarts: 3,
streamer_registry: true
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{Mix.env()}.exs"

View file

@ -162,6 +162,14 @@ peer_module =
config :pleroma, Pleroma.Cluster, peer_module: peer_module config :pleroma, Pleroma.Cluster, peer_module: peer_module
config :pleroma, Pleroma.Application,
background_migrators: false,
internal_fetch: false,
load_custom_modules: false,
max_restarts: 100,
streamer_registry: false,
test_http_pools: true
if File.exists?("./config/test.secret.exs") do if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs" import_config "test.secret.exs"
else else

View file

@ -352,6 +352,4 @@ defmodule Mix.Tasks.Pleroma.Instance do
enabled_filters enabled_filters
end end
defp upload_filters(_), do: []
end end

View file

@ -9,7 +9,7 @@ defmodule Pleroma.Activity.Queries do
import Ecto.Query, only: [from: 2, where: 3] import Ecto.Query, only: [from: 2, where: 3]
@type query :: Ecto.Queryable.t() | Activity.t() @type query :: Ecto.Queryable.t() | Pleroma.Activity.t()
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User alias Pleroma.User

View file

@ -14,7 +14,6 @@ defmodule Pleroma.Application do
@name Mix.Project.config()[:name] @name Mix.Project.config()[:name]
@version Mix.Project.config()[:version] @version Mix.Project.config()[:version]
@repository Mix.Project.config()[:source_url] @repository Mix.Project.config()[:source_url]
@mix_env Mix.env()
def name, do: @name def name, do: @name
def version, do: @version def version, do: @version
@ -98,7 +97,7 @@ defmodule Pleroma.Application do
{Task.Supervisor, name: Pleroma.TaskSupervisor} {Task.Supervisor, name: Pleroma.TaskSupervisor}
] ++ ] ++
cachex_children() ++ cachex_children() ++
http_children(adapter, @mix_env) ++ http_children(adapter) ++
[ [
Pleroma.Stats, Pleroma.Stats,
Pleroma.JobQueueMonitor, Pleroma.JobQueueMonitor,
@ -106,8 +105,9 @@ defmodule Pleroma.Application do
{Oban, Config.get(Oban)}, {Oban, Config.get(Oban)},
Pleroma.Web.Endpoint Pleroma.Web.Endpoint
] ++ ] ++
task_children(@mix_env) ++ task_children() ++
dont_run_in_test(@mix_env) ++ streamer_registry() ++
background_migrators() ++
shout_child(shout_enabled?()) ++ shout_child(shout_enabled?()) ++
[Pleroma.Gopher.Server] [Pleroma.Gopher.Server]
@ -116,12 +116,7 @@ defmodule Pleroma.Application do
# If we have a lot of caches, default max_restarts can cause test # If we have a lot of caches, default max_restarts can cause test
# resets to fail. # resets to fail.
# Go for the default 3 unless we're in test # Go for the default 3 unless we're in test
max_restarts = max_restarts = Application.get_env(:pleroma, __MODULE__)[:max_restarts]
if @mix_env == :test do
100
else
3
end
opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts] opts = [strategy: :one_for_one, name: Pleroma.Supervisor, max_restarts: max_restarts]
result = Supervisor.start_link(children, opts) result = Supervisor.start_link(children, opts)
@ -159,7 +154,7 @@ defmodule Pleroma.Application do
raise "Invalid custom modules" raise "Invalid custom modules"
{:ok, modules, _warnings} -> {:ok, modules, _warnings} ->
if @mix_env != :test do if Application.get_env(:pleroma, __MODULE__)[:load_custom_modules] do
Enum.each(modules, fn mod -> Enum.each(modules, fn mod ->
Logger.info("Custom module loaded: #{inspect(mod)}") Logger.info("Custom module loaded: #{inspect(mod)}")
end) end)
@ -213,24 +208,30 @@ defmodule Pleroma.Application do
defp shout_enabled?, do: Config.get([:shout, :enabled]) defp shout_enabled?, do: Config.get([:shout, :enabled])
defp dont_run_in_test(env) when env in [:test, :benchmark], do: [] defp streamer_registry do
if Application.get_env(:pleroma, __MODULE__)[:streamer_registry] do
defp dont_run_in_test(_) do [
[ {Registry,
{Registry, [
[ name: Pleroma.Web.Streamer.registry(),
name: Pleroma.Web.Streamer.registry(), keys: :duplicate,
keys: :duplicate, partitions: System.schedulers_online()
partitions: System.schedulers_online() ]}
]} ]
] ++ background_migrators() else
[]
end
end end
defp background_migrators do defp background_migrators do
[ if Application.get_env(:pleroma, __MODULE__)[:background_migrators] do
Pleroma.Migrators.HashtagsTableMigrator, [
Pleroma.Migrators.ContextObjectsDeletionMigrator Pleroma.Migrators.HashtagsTableMigrator,
] Pleroma.Migrators.ContextObjectsDeletionMigrator
]
else
[]
end
end end
defp shout_child(true) do defp shout_child(true) do
@ -242,37 +243,43 @@ defmodule Pleroma.Application do
defp shout_child(_), do: [] defp shout_child(_), do: []
defp task_children(:test) do defp task_children do
[ children = [
%{ %{
id: :web_push_init, id: :web_push_init,
start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, start: {Task, :start_link, [&Pleroma.Web.Push.init/0]},
restart: :temporary restart: :temporary
} }
] ]
end
defp task_children(_) do if Application.get_env(:pleroma, __MODULE__)[:internal_fetch] do
[ children ++
%{ [
id: :web_push_init, %{
start: {Task, :start_link, [&Pleroma.Web.Push.init/0]}, id: :internal_fetch_init,
restart: :temporary start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]},
}, restart: :temporary
%{ }
id: :internal_fetch_init, ]
start: {Task, :start_link, [&Pleroma.Web.ActivityPub.InternalFetchActor.init/0]}, else
restart: :temporary children
} end
]
end end
# start hackney and gun pools in tests # start hackney and gun pools in tests
defp http_children(_, :test) do defp http_children(adapter) do
http_children(Tesla.Adapter.Hackney, nil) ++ http_children(Tesla.Adapter.Gun, nil) if Application.get_env(:pleroma, __MODULE__)[:test_http_pools] do
http_children_hackney() ++ http_children_gun()
else
cond do
match?(Tesla.Adapter.Hackney, adapter) -> http_children_hackney()
match?(Tesla.Adapter.Gun, adapter) -> http_children_gun()
true -> []
end
end
end end
defp http_children(Tesla.Adapter.Hackney, _) do defp http_children_hackney do
pools = [:federation, :media] pools = [:federation, :media]
pools = pools =
@ -288,13 +295,11 @@ defmodule Pleroma.Application do
end end
end end
defp http_children(Tesla.Adapter.Gun, _) do defp http_children_gun do
Pleroma.Gun.ConnectionPool.children() ++ Pleroma.Gun.ConnectionPool.children() ++
[{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}] [{Task, &Pleroma.HTTP.AdapterHelper.Gun.limiter_setup/0}]
end end
defp http_children(_, _), do: []
@spec limiters_setup() :: :ok @spec limiters_setup() :: :ok
def limiters_setup do def limiters_setup do
config = Config.get(ConcurrentLimiter, []) config = Config.get(ConcurrentLimiter, [])

View file

@ -7,7 +7,10 @@ defmodule Pleroma.ApplicationRequirements do
The module represents the collection of validations to runs before start server. The module represents the collection of validations to runs before start server.
""" """
defmodule VerifyError, do: defexception([:message]) defmodule VerifyError do
defexception([:message])
@type t :: %__MODULE__{}
end
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Helpers.MediaHelper alias Pleroma.Helpers.MediaHelper
@ -193,8 +196,6 @@ defmodule Pleroma.ApplicationRequirements do
end end
end end
defp check_system_commands!(result), do: result
defp check_repo_pool_size!(:ok) do defp check_repo_pool_size!(:ok) do
if Pleroma.Config.get([Pleroma.Repo, :pool_size], 10) != 10 and if Pleroma.Config.get([Pleroma.Repo, :pool_size], 10) != 10 and
not Pleroma.Config.get([:dangerzone, :override_repo_pool_size], false) do not Pleroma.Config.get([:dangerzone, :override_repo_pool_size], false) do

View file

@ -22,8 +22,8 @@ defmodule Pleroma.Bookmark do
timestamps() timestamps()
end end
@spec create(FlakeId.Ecto.CompatType.t(), FlakeId.Ecto.CompatType.t()) :: @spec create(Ecto.UUID.t(), Ecto.UUID.t()) ::
{:ok, Bookmark.t()} | {:error, Changeset.t()} {:ok, Bookmark.t()} | {:error, Ecto.Changeset.t()}
def create(user_id, activity_id) do def create(user_id, activity_id) do
attrs = %{ attrs = %{
user_id: user_id, user_id: user_id,
@ -37,7 +37,7 @@ defmodule Pleroma.Bookmark do
|> Repo.insert() |> Repo.insert()
end end
@spec for_user_query(FlakeId.Ecto.CompatType.t()) :: Ecto.Query.t() @spec for_user_query(Ecto.UUID.t()) :: Ecto.Query.t()
def for_user_query(user_id) do def for_user_query(user_id) do
Bookmark Bookmark
|> where(user_id: ^user_id) |> where(user_id: ^user_id)
@ -52,8 +52,8 @@ defmodule Pleroma.Bookmark do
|> Repo.one() |> Repo.one()
end end
@spec destroy(FlakeId.Ecto.CompatType.t(), FlakeId.Ecto.CompatType.t()) :: @spec destroy(Ecto.UUID.t(), Ecto.UUID.t()) ::
{:ok, Bookmark.t()} | {:error, Changeset.t()} {:ok, Bookmark.t()} | {:error, Ecto.Changeset.t()}
def destroy(user_id, activity_id) do def destroy(user_id, activity_id) do
from(b in Bookmark, from(b in Bookmark,
where: b.user_id == ^user_id, where: b.user_id == ^user_id,

View file

@ -42,7 +42,7 @@ defmodule Pleroma.Chat do
|> unique_constraint(:user_id, name: :chats_user_id_recipient_index) |> unique_constraint(:user_id, name: :chats_user_id_recipient_index)
end end
@spec get_by_user_and_id(User.t(), FlakeId.Ecto.CompatType.t()) :: @spec get_by_user_and_id(User.t(), Ecto.UUID.t()) ::
{:ok, t()} | {:error, :not_found} {:ok, t()} | {:error, :not_found}
def get_by_user_and_id(%User{id: user_id}, id) do def get_by_user_and_id(%User{id: user_id}, id) do
from(c in __MODULE__, from(c in __MODULE__,
@ -52,17 +52,17 @@ defmodule Pleroma.Chat do
|> Repo.find_resource() |> Repo.find_resource()
end end
@spec get_by_id(FlakeId.Ecto.CompatType.t()) :: t() | nil @spec get_by_id(Ecto.UUID.t()) :: t() | nil
def get_by_id(id) do def get_by_id(id) do
Repo.get(__MODULE__, id) Repo.get(__MODULE__, id)
end end
@spec get(FlakeId.Ecto.CompatType.t(), String.t()) :: t() | nil @spec get(Ecto.UUID.t(), String.t()) :: t() | nil
def get(user_id, recipient) do def get(user_id, recipient) do
Repo.get_by(__MODULE__, user_id: user_id, recipient: recipient) Repo.get_by(__MODULE__, user_id: user_id, recipient: recipient)
end end
@spec get_or_create(FlakeId.Ecto.CompatType.t(), String.t()) :: @spec get_or_create(Ecto.UUID.t(), String.t()) ::
{:ok, t()} | {:error, Ecto.Changeset.t()} {:ok, t()} | {:error, Ecto.Changeset.t()}
def get_or_create(user_id, recipient) do def get_or_create(user_id, recipient) do
%__MODULE__{} %__MODULE__{}
@ -75,7 +75,7 @@ defmodule Pleroma.Chat do
) )
end end
@spec bump_or_create(FlakeId.Ecto.CompatType.t(), String.t()) :: @spec bump_or_create(Ecto.UUID.t(), String.t()) ::
{:ok, t()} | {:error, Ecto.Changeset.t()} {:ok, t()} | {:error, Ecto.Changeset.t()}
def bump_or_create(user_id, recipient) do def bump_or_create(user_id, recipient) do
%__MODULE__{} %__MODULE__{}
@ -87,7 +87,7 @@ defmodule Pleroma.Chat do
) )
end end
@spec for_user_query(FlakeId.Ecto.CompatType.t()) :: Ecto.Query.t() @spec for_user_query(Ecto.UUID.t()) :: Ecto.Query.t()
def for_user_query(user_id) do def for_user_query(user_id) do
from(c in Chat, from(c in Chat,
where: c.user_id == ^user_id, where: c.user_id == ^user_id,

View file

@ -54,7 +54,7 @@ defmodule Pleroma.ConfigDB do
@spec get_by_params(map()) :: ConfigDB.t() | nil @spec get_by_params(map()) :: ConfigDB.t() | nil
def get_by_params(%{group: _, key: _} = params), do: Repo.get_by(ConfigDB, params) def get_by_params(%{group: _, key: _} = params), do: Repo.get_by(ConfigDB, params)
@spec changeset(ConfigDB.t(), map()) :: Changeset.t() @spec changeset(ConfigDB.t(), map()) :: Ecto.Changeset.t()
def changeset(config, params \\ %{}) do def changeset(config, params \\ %{}) do
config config
|> cast(params, [:key, :group, :value]) |> cast(params, [:key, :group, :value])
@ -138,7 +138,7 @@ defmodule Pleroma.ConfigDB do
end end
end end
@spec update_or_create(map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()} @spec update_or_create(map()) :: {:ok, ConfigDB.t()} | {:error, Ecto.Changeset.t()}
def update_or_create(params) do def update_or_create(params) do
params = Map.put(params, :value, to_elixir_types(params[:value])) params = Map.put(params, :value, to_elixir_types(params[:value]))
search_opts = Map.take(params, [:group, :key]) search_opts = Map.take(params, [:group, :key])
@ -175,7 +175,7 @@ defmodule Pleroma.ConfigDB do
end) end)
end end
@spec delete(ConfigDB.t() | map()) :: {:ok, ConfigDB.t()} | {:error, Changeset.t()} @spec delete(ConfigDB.t() | map()) :: {:ok, ConfigDB.t()} | {:error, Ecto.Changeset.t()}
def delete(%ConfigDB{} = config), do: Repo.delete(config) def delete(%ConfigDB{} = config), do: Repo.delete(config)
def delete(params) do def delete(params) do

View file

@ -18,7 +18,7 @@ defmodule Pleroma.Docs.JSON do
:persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(descriptions)) :persistent_term.put(@term, Pleroma.Docs.Generator.convert_to_strings(descriptions))
end end
@spec compiled_descriptions :: Map.t() @spec compiled_descriptions :: map()
def compiled_descriptions do def compiled_descriptions do
:persistent_term.get(@term) :persistent_term.get(@term)
end end

View file

@ -8,10 +8,12 @@ defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri do
def type, do: :string def type, do: :string
def cast(uri) when is_binary(uri) do def cast(uri) when is_binary(uri) do
case URI.parse(uri) do parsed = URI.parse(uri)
%URI{scheme: nil} -> :error
%URI{} -> {:ok, uri} if is_nil(parsed.scheme) do
_ -> :error :error
else
{:ok, uri}
end end
end end

View file

@ -24,6 +24,8 @@ defmodule Pleroma.Emoji do
defstruct [:code, :file, :tags, :safe_code, :safe_file] defstruct [:code, :file, :tags, :safe_code, :safe_file]
@type t :: %__MODULE__{}
@doc "Build emoji struct" @doc "Build emoji struct"
def build({code, file, tags}) do def build({code, file, tags}) do
%__MODULE__{ %__MODULE__{

View file

@ -100,7 +100,7 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
|> where([_o, hashtags_objects], is_nil(hashtags_objects.object_id)) |> where([_o, hashtags_objects], is_nil(hashtags_objects.object_id))
end end
@spec transfer_object_hashtags(Map.t()) :: {:noop | :ok | :error, integer()} @spec transfer_object_hashtags(map()) :: {:noop | :ok | :error, integer()}
defp transfer_object_hashtags(object) do defp transfer_object_hashtags(object) do
embedded_tags = if Map.has_key?(object, :tag), do: object.tag, else: object.data["tag"] embedded_tags = if Map.has_key?(object, :tag), do: object.tag, else: object.data["tag"]
hashtags = Object.object_data_hashtags(%{"tag" => embedded_tags}) hashtags = Object.object_data_hashtags(%{"tag" => embedded_tags})

View file

@ -55,12 +55,6 @@ defmodule Pleroma.ReleaseTasks do
{:error, term} when is_binary(term) -> {:error, term} when is_binary(term) ->
IO.puts(:stderr, "The database for #{inspect(@repo)} couldn't be created: #{term}") IO.puts(:stderr, "The database for #{inspect(@repo)} couldn't be created: #{term}")
{:error, term} ->
IO.puts(
:stderr,
"The database for #{inspect(@repo)} couldn't be created: #{inspect(term)}"
)
end end
end end
end end

View file

@ -23,8 +23,8 @@ defmodule Pleroma.ReportNote do
timestamps() timestamps()
end end
@spec create(FlakeId.Ecto.CompatType.t(), FlakeId.Ecto.CompatType.t(), String.t()) :: @spec create(Ecto.UUID.t(), Ecto.UUID.t(), String.t()) ::
{:ok, ReportNote.t()} | {:error, Changeset.t()} {:ok, ReportNote.t()} | {:error, Ecto.Changeset.t()}
def create(user_id, activity_id, content) do def create(user_id, activity_id, content) do
attrs = %{ attrs = %{
user_id: user_id, user_id: user_id,
@ -38,8 +38,8 @@ defmodule Pleroma.ReportNote do
|> Repo.insert() |> Repo.insert()
end end
@spec destroy(FlakeId.Ecto.CompatType.t()) :: @spec destroy(Ecto.UUID.t()) ::
{:ok, ReportNote.t()} | {:error, Changeset.t()} {:ok, ReportNote.t()} | {:error, Ecto.Changeset.t()}
def destroy(id) do def destroy(id) do
from(r in ReportNote, where: r.id == ^id) from(r in ReportNote, where: r.id == ^id)
|> Repo.one() |> Repo.one()

View file

@ -81,9 +81,9 @@ defmodule Pleroma.ReverseProxy do
import Plug.Conn import Plug.Conn
@type option() :: @type option() ::
{:max_read_duration, :timer.time() | :infinity} {:max_read_duration, non_neg_integer() | :infinity}
| {:max_body_length, non_neg_integer() | :infinity} | {:max_body_length, non_neg_integer() | :infinity}
| {:failed_request_ttl, :timer.time() | :infinity} | {:failed_request_ttl, non_neg_integer() | :infinity}
| {:http, []} | {:http, []}
| {:req_headers, [{String.t(), String.t()}]} | {:req_headers, [{String.t(), String.t()}]}
| {:resp_headers, [{String.t(), String.t()}]} | {:resp_headers, [{String.t(), String.t()}]}

View file

@ -86,7 +86,7 @@ defmodule Pleroma.Upload do
end end
end end
@spec store(source, options :: [option()]) :: {:ok, Map.t()} | {:error, any()} @spec store(source, options :: [option()]) :: {:ok, map()} | {:error, any()}
@doc "Store a file. If using a `Plug.Upload{}` as the source, be sure to use `Majic.Plug` to ensure its content_type and filename is correct." @doc "Store a file. If using a `Plug.Upload{}` as the source, be sure to use `Majic.Plug` to ensure its content_type and filename is correct."
def store(upload, opts \\ []) do def store(upload, opts \\ []) do
opts = get_opts(opts) opts = get_opts(opts)

View file

@ -40,7 +40,7 @@ defmodule Pleroma.Uploaders.Uploader do
@callback delete_file(file :: String.t()) :: :ok | {:error, String.t()} @callback delete_file(file :: String.t()) :: :ok | {:error, String.t()}
@callback http_callback(Plug.Conn.t(), Map.t()) :: @callback http_callback(Plug.Conn.t(), map()) ::
{:ok, Plug.Conn.t()} {:ok, Plug.Conn.t()}
| {:ok, Plug.Conn.t(), file_spec()} | {:ok, Plug.Conn.t(), file_spec()}
| {:error, Plug.Conn.t(), String.t()} | {:error, Plug.Conn.t(), String.t()}

View file

@ -672,7 +672,7 @@ defmodule Pleroma.User do
|> validate_inclusion(:actor_type, ["Person", "Service"]) |> validate_inclusion(:actor_type, ["Person", "Service"])
end end
@spec update_as_admin(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec update_as_admin(User.t(), map()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def update_as_admin(user, params) do def update_as_admin(user, params) do
params = Map.put(params, "password_confirmation", params["password"]) params = Map.put(params, "password_confirmation", params["password"])
changeset = update_as_admin_changeset(user, params) changeset = update_as_admin_changeset(user, params)
@ -693,7 +693,7 @@ defmodule Pleroma.User do
|> put_change(:password_reset_pending, false) |> put_change(:password_reset_pending, false)
end end
@spec reset_password(User.t(), map()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec reset_password(User.t(), map()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def reset_password(%User{} = user, params) do def reset_password(%User{} = user, params) do
reset_password(user, user, params) reset_password(user, user, params)
end end
@ -1011,7 +1011,7 @@ defmodule Pleroma.User do
def maybe_send_confirmation_email(_), do: {:ok, :noop} def maybe_send_confirmation_email(_), do: {:ok, :noop}
@spec send_confirmation_email(Uset.t()) :: User.t() @spec send_confirmation_email(User.t()) :: User.t()
def send_confirmation_email(%User{} = user) do def send_confirmation_email(%User{} = user) do
user user
|> Pleroma.Emails.UserEmail.account_confirmation_email() |> Pleroma.Emails.UserEmail.account_confirmation_email()
@ -1048,7 +1048,8 @@ defmodule Pleroma.User do
def needs_update?(_), do: true def needs_update?(_), do: true
@spec maybe_direct_follow(User.t(), User.t()) :: {:ok, User.t()} | {:error, String.t()} @spec maybe_direct_follow(User.t(), User.t()) ::
{:ok, User.t(), User.t()} | {:error, String.t()}
# "Locked" (self-locked) users demand explicit authorization of follow requests # "Locked" (self-locked) users demand explicit authorization of follow requests
def maybe_direct_follow(%User{} = follower, %User{local: true, is_locked: true} = followed) do def maybe_direct_follow(%User{} = follower, %User{local: true, is_locked: true} = followed) do
@ -1783,14 +1784,14 @@ defmodule Pleroma.User do
BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status}) BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status})
end end
@spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def set_activation(users, status) when is_list(users) do def set_activation(users, status) when is_list(users) do
Repo.transaction(fn -> Repo.transaction(fn ->
for user <- users, do: set_activation(user, status) for user <- users, do: set_activation(user, status)
end) end)
end end
@spec set_activation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec set_activation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def set_activation(%User{} = user, status) do def set_activation(%User{} = user, status) do
with {:ok, user} <- set_activation_status(user, status) do with {:ok, user} <- set_activation_status(user, status) do
user user
@ -1868,7 +1869,7 @@ defmodule Pleroma.User do
|> update_and_set_cache() |> update_and_set_cache()
end end
@spec purge_user_changeset(User.t()) :: Changeset.t() @spec purge_user_changeset(User.t()) :: Ecto.Changeset.t()
def purge_user_changeset(user) do def purge_user_changeset(user) do
# "Right to be forgotten" # "Right to be forgotten"
# https://gdpr.eu/right-to-be-forgotten/ # https://gdpr.eu/right-to-be-forgotten/
@ -2359,7 +2360,7 @@ defmodule Pleroma.User do
updated_user updated_user
end end
@spec set_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()} @spec set_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Ecto.Changeset.t()}
def set_confirmation(%User{} = user, bool) do def set_confirmation(%User{} = user, bool) do
user user
|> confirmation_changeset(set_confirmation: bool) |> confirmation_changeset(set_confirmation: bool)
@ -2537,7 +2538,7 @@ defmodule Pleroma.User do
|> update_and_set_cache() |> update_and_set_cache()
end end
@spec confirmation_changeset(User.t(), keyword()) :: Changeset.t() @spec confirmation_changeset(User.t(), keyword()) :: Ecto.Changeset.t()
def confirmation_changeset(user, set_confirmation: confirmed?) do def confirmation_changeset(user, set_confirmation: confirmed?) do
params = params =
if confirmed? do if confirmed? do
@ -2555,7 +2556,7 @@ defmodule Pleroma.User do
cast(user, params, [:is_confirmed, :confirmation_token]) cast(user, params, [:is_confirmed, :confirmation_token])
end end
@spec approval_changeset(User.t(), keyword()) :: Changeset.t() @spec approval_changeset(User.t(), keyword()) :: Ecto.Changeset.t()
def approval_changeset(user, set_approval: approved?) do def approval_changeset(user, set_approval: approved?) do
cast(user, %{is_approved: approved?}, [:is_approved]) cast(user, %{is_approved: approved?}, [:is_approved])
end end

View file

@ -64,7 +64,7 @@ defmodule Pleroma.UserInviteToken do
end end
@spec update_invite(UserInviteToken.t(), map()) :: @spec update_invite(UserInviteToken.t(), map()) ::
{:ok, UserInviteToken.t()} | {:error, Changeset.t()} {:ok, UserInviteToken.t()} | {:error, Ecto.Changeset.t()}
def update_invite(invite, changes) do def update_invite(invite, changes) do
change(invite, changes) |> Repo.update() change(invite, changes) |> Repo.update()
end end

View file

@ -499,7 +499,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end end
@spec fetch_latest_direct_activity_id_for_context(String.t(), keyword() | map()) :: @spec fetch_latest_direct_activity_id_for_context(String.t(), keyword() | map()) ::
FlakeId.Ecto.CompatType.t() | nil Ecto.UUID.t() | nil
def fetch_latest_direct_activity_id_for_context(context, opts \\ %{}) do def fetch_latest_direct_activity_id_for_context(context, opts \\ %{}) do
context context
|> fetch_activities_for_context_query(Map.merge(%{skip_preload: true}, opts)) |> fetch_activities_for_context_query(Map.merge(%{skip_preload: true}, opts))

View file

@ -56,8 +56,6 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiFollowbotPolicy do
nick_score + name_score + actor_type_score nick_score + name_score + actor_type_score
end end
defp determine_if_followbot(_), do: 0.0
defp bot_allowed?(%{"object" => target}, bot_actor) do defp bot_allowed?(%{"object" => target}, bot_actor) do
%User{} = user = normalize_by_ap_id(target) %User{} = user = normalize_by_ap_id(target)

View file

@ -3,8 +3,8 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.Policy do defmodule Pleroma.Web.ActivityPub.MRF.Policy do
@callback filter(Map.t()) :: {:ok | :reject, Map.t()} @callback filter(map()) :: {:ok | :reject, map()}
@callback describe() :: {:ok | :error, Map.t()} @callback describe() :: {:ok | :error, map()}
@callback config_description() :: %{ @callback config_description() :: %{
optional(:children) => [map()], optional(:children) => [map()],
key: atom(), key: atom(),

View file

@ -28,7 +28,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
@doc """ @doc """
Enqueue publishing a single activity. Enqueue publishing a single activity.
""" """
@spec enqueue_one(Map.t(), Keyword.t()) :: {:ok, %Oban.Job{}} @spec enqueue_one(map(), Keyword.t()) :: {:ok, %Oban.Job{}}
def enqueue_one(%{} = params, worker_args \\ []) do def enqueue_one(%{} = params, worker_args \\ []) do
PublisherWorker.enqueue( PublisherWorker.enqueue(
"publish_one", "publish_one",

View file

@ -5,7 +5,7 @@
defmodule Pleroma.Web.Auth.Authenticator do defmodule Pleroma.Web.Auth.Authenticator do
@callback get_user(Plug.Conn.t()) :: {:ok, user :: struct()} | {:error, any()} @callback get_user(Plug.Conn.t()) :: {:ok, user :: struct()} | {:error, any()}
@callback create_from_registration(Plug.Conn.t(), registration :: struct()) :: @callback create_from_registration(Plug.Conn.t(), registration :: struct()) ::
{:ok, User.t()} | {:error, any()} {:ok, Pleroma.User.t()} | {:error, any()}
@callback get_registration(Plug.Conn.t()) :: {:ok, registration :: struct()} | {:error, any()} @callback get_registration(Plug.Conn.t()) :: {:ok, registration :: struct()} | {:error, any()}
@callback handle_error(Plug.Conn.t(), any()) :: any() @callback handle_error(Plug.Conn.t(), any()) :: any()
@callback auth_template() :: String.t() | nil @callback auth_template() :: String.t() | nil

View file

@ -132,7 +132,7 @@ defmodule Pleroma.Web.Feed.FeedView do
|> safe_to_string() |> safe_to_string()
end end
@spec to_rfc3339(String.t() | NativeDateTime.t()) :: String.t() @spec to_rfc3339(String.t() | NaiveDateTime.t()) :: String.t()
def to_rfc3339(date) when is_binary(date) do def to_rfc3339(date) when is_binary(date) do
date date
|> Timex.parse!("{ISO:Extended}") |> Timex.parse!("{ISO:Extended}")
@ -145,7 +145,7 @@ defmodule Pleroma.Web.Feed.FeedView do
|> Timex.format!("{RFC3339}") |> Timex.format!("{RFC3339}")
end end
@spec to_rfc2822(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t() @spec to_rfc2822(String.t() | DateTime.t() | NaiveDateTime.t()) :: String.t()
def to_rfc2822(datestr) when is_binary(datestr) do def to_rfc2822(datestr) when is_binary(datestr) do
datestr datestr
|> Timex.parse!("{ISO:Extended}") |> Timex.parse!("{ISO:Extended}")

View file

@ -28,7 +28,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
end end
@spec create_authorization(App.t(), User.t() | %{}, [String.t()] | nil) :: @spec create_authorization(App.t(), User.t() | %{}, [String.t()] | nil) ::
{:ok, Authorization.t()} | {:error, Changeset.t()} {:ok, Authorization.t()} | {:error, Ecto.Changeset.t()}
def create_authorization(%App{} = app, %User{} = user, scopes \\ nil) do def create_authorization(%App{} = app, %User{} = user, scopes \\ nil) do
%{ %{
scopes: scopes || app.scopes, scopes: scopes || app.scopes,
@ -39,7 +39,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
|> Repo.insert() |> Repo.insert()
end end
@spec create_changeset(map()) :: Changeset.t() @spec create_changeset(map()) :: Ecto.Changeset.t()
def create_changeset(attrs \\ %{}) do def create_changeset(attrs \\ %{}) do
%Authorization{} %Authorization{}
|> cast(attrs, [:user_id, :app_id, :scopes, :valid_until]) |> cast(attrs, [:user_id, :app_id, :scopes, :valid_until])
@ -58,7 +58,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
put_change(changeset, :valid_until, NaiveDateTime.add(NaiveDateTime.utc_now(), lifespan)) put_change(changeset, :valid_until, NaiveDateTime.add(NaiveDateTime.utc_now(), lifespan))
end end
@spec use_changeset(Authtorizatiton.t(), map()) :: Changeset.t() @spec use_changeset(Authorization.t(), map()) :: Ecto.Changeset.t()
def use_changeset(%Authorization{} = auth, params) do def use_changeset(%Authorization{} = auth, params) do
auth auth
|> cast(params, [:used]) |> cast(params, [:used])
@ -66,7 +66,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
end end
@spec use_token(Authorization.t()) :: @spec use_token(Authorization.t()) ::
{:ok, Authorization.t()} | {:error, Changeset.t()} | {:error, String.t()} {:ok, Authorization.t()} | {:error, Ecto.Changeset.t()} | {:error, String.t()}
def use_token(%Authorization{used: false, valid_until: valid_until} = auth) do def use_token(%Authorization{used: false, valid_until: valid_until} = auth) do
if NaiveDateTime.diff(NaiveDateTime.utc_now(), valid_until) < 0 do if NaiveDateTime.diff(NaiveDateTime.utc_now(), valid_until) < 0 do
Repo.update(use_changeset(auth, %{used: true})) Repo.update(use_changeset(auth, %{used: true}))

View file

@ -56,7 +56,8 @@ defmodule Pleroma.Web.OAuth.Token do
|> Repo.find_resource() |> Repo.find_resource()
end end
@spec exchange_token(App.t(), Authorization.t()) :: {:ok, Token.t()} | {:error, Changeset.t()} @spec exchange_token(App.t(), Authorization.t()) ::
{:ok, Token.t()} | {:error, Ecto.Changeset.t()}
def exchange_token(app, auth) do def exchange_token(app, auth) do
with {:ok, auth} <- Authorization.use_token(auth), with {:ok, auth} <- Authorization.use_token(auth),
true <- auth.app_id == app.id do true <- auth.app_id == app.id do
@ -95,7 +96,7 @@ defmodule Pleroma.Web.OAuth.Token do
|> validate_required([:valid_until]) |> validate_required([:valid_until])
end end
@spec create(App.t(), User.t(), map()) :: {:ok, Token} | {:error, Changeset.t()} @spec create(App.t(), User.t(), map()) :: {:ok, Token} | {:error, Ecto.Changeset.t()}
def create(%App{} = app, %User{} = user, attrs \\ %{}) do def create(%App{} = app, %User{} = user, attrs \\ %{}) do
with {:ok, token} <- do_create(app, user, attrs) do with {:ok, token} <- do_create(app, user, attrs) do
if Pleroma.Config.get([:oauth2, :clean_expired_tokens]) do if Pleroma.Config.get([:oauth2, :clean_expired_tokens]) do

View file

@ -9,10 +9,10 @@ defmodule Pleroma.Web.OAuth.Token.Query do
import Ecto.Query, only: [from: 2] import Ecto.Query, only: [from: 2]
@type query :: Ecto.Queryable.t() | Token.t()
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
@type query :: Ecto.Queryable.t() | Token.t()
@spec get_by_refresh_token(query, String.t()) :: query @spec get_by_refresh_token(query, String.t()) :: query
def get_by_refresh_token(query \\ Token, refresh_token) do def get_by_refresh_token(query \\ Token, refresh_token) do
from(q in query, where: q.refresh_token == ^refresh_token) from(q in query, where: q.refresh_token == ^refresh_token)

View file

@ -102,7 +102,7 @@ defmodule Pleroma.Web.RichMedia.Parser do
ttl_setters: [MyModule] ttl_setters: [MyModule]
""" """
@spec set_ttl_based_on_image(map(), String.t()) :: @spec set_ttl_based_on_image(map(), String.t()) ::
{:ok, Integer.t() | :noop} | {:error, :no_key} {:ok, integer() | :noop} | {:error, :no_key}
def set_ttl_based_on_image(data, url) do def set_ttl_based_on_image(data, url) do
case get_ttl_from_image(data, url) do case get_ttl_from_image(data, url) do
{:ok, ttl} when is_number(ttl) -> {:ok, ttl} when is_number(ttl) ->

View file

@ -3,5 +3,5 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.RichMedia.Parser.TTL do defmodule Pleroma.Web.RichMedia.Parser.TTL do
@callback ttl(Map.t(), String.t()) :: Integer.t() | nil @callback ttl(map(), String.t()) :: integer() | nil
end end

View file

@ -34,7 +34,7 @@ defmodule Pleroma.Web.Streamer do
stream :: String.t(), stream :: String.t(),
User.t() | nil, User.t() | nil,
Token.t() | nil, Token.t() | nil,
Map.t() | nil map() | nil
) :: ) ::
{:ok, topic :: String.t()} | {:error, :bad_topic} | {:error, :unauthorized} {:ok, topic :: String.t()} | {:error, :bad_topic} | {:error, :unauthorized}
def get_topic_and_add_socket(stream, user, oauth_token, params \\ %{}) do def get_topic_and_add_socket(stream, user, oauth_token, params \\ %{}) do
@ -60,7 +60,7 @@ defmodule Pleroma.Web.Streamer do
end end
@doc "Expand and authorizes a stream" @doc "Expand and authorizes a stream"
@spec get_topic(stream :: String.t() | nil, User.t() | nil, Token.t() | nil, Map.t()) :: @spec get_topic(stream :: String.t() | nil, User.t() | nil, Token.t() | nil, map()) ::
{:ok, topic :: String.t() | nil} | {:error, :bad_topic} {:ok, topic :: String.t() | nil} | {:error, :bad_topic}
def get_topic(stream, user, oauth_token, params \\ %{}) def get_topic(stream, user, oauth_token, params \\ %{})