aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/pleroma/application.ex18
-rw-r--r--lib/pleroma/config.ex41
-rw-r--r--lib/pleroma/upload/filter/exiftool.ex12
-rw-r--r--lib/pleroma/upload/filter/mogrifun.ex11
-rw-r--r--lib/pleroma/upload/filter/mogrify.ex12
-rw-r--r--lib/pleroma/utils.ex15
-rw-r--r--lib/pleroma/web/templates/layout/app.html.eex2
-rw-r--r--mix.exs6
-rw-r--r--priv/repo/migrations/20200802170532_fix_legacy_tags.exs37
-rw-r--r--priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs19
-rw-r--r--priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs7
-rw-r--r--test/config_test.exs46
-rw-r--r--test/migrations/20200802170532_fix_legacy_tags_test.exs24
-rw-r--r--test/support/helpers.ex14
-rw-r--r--test/upload/filter/exiftool_test.exs2
-rw-r--r--test/web/oauth/app_test.exs11
16 files changed, 251 insertions, 26 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 0ffb55358..c0b5db9f1 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -47,6 +47,7 @@ defmodule Pleroma.Application do
Pleroma.ApplicationRequirements.verify!()
setup_instrumenters()
load_custom_modules()
+ check_system_commands()
Pleroma.Docs.JSON.compile()
adapter = Application.get_env(:tesla, :adapter)
@@ -249,4 +250,21 @@ defmodule Pleroma.Application do
end
defp http_children(_, _), do: []
+
+ defp check_system_commands do
+ filters = Config.get([Pleroma.Upload, :filters])
+
+ check_filter = fn filter, command_required ->
+ with true <- filter in filters,
+ false <- Pleroma.Utils.command_available?(command_required) do
+ Logger.error(
+ "#{filter} is specified in list of Pleroma.Upload filters, but the #{command_required} command is not found"
+ )
+ end
+ end
+
+ check_filter.(Pleroma.Upload.Filters.Exiftool, "exiftool")
+ check_filter.(Pleroma.Upload.Filters.Mogrify, "mogrify")
+ check_filter.(Pleroma.Upload.Filters.Mogrifun, "mogrify")
+ end
end
diff --git a/lib/pleroma/config.ex b/lib/pleroma/config.ex
index cc80deff5..a8329cc1e 100644
--- a/lib/pleroma/config.ex
+++ b/lib/pleroma/config.ex
@@ -11,12 +11,10 @@ defmodule Pleroma.Config do
def get([key], default), do: get(key, default)
- def get([parent_key | keys], default) do
- case :pleroma
- |> Application.get_env(parent_key)
- |> get_in(keys) do
- nil -> default
- any -> any
+ def get([_ | _] = path, default) do
+ case fetch(path) do
+ {:ok, value} -> value
+ :error -> default
end
end
@@ -34,6 +32,24 @@ defmodule Pleroma.Config do
end
end
+ def fetch(key) when is_atom(key), do: fetch([key])
+
+ def fetch([root_key | keys]) do
+ Enum.reduce_while(keys, Application.fetch_env(:pleroma, root_key), fn
+ key, {:ok, config} when is_map(config) or is_list(config) ->
+ case Access.fetch(config, key) do
+ :error ->
+ {:halt, :error}
+
+ value ->
+ {:cont, value}
+ end
+
+ _key, _config ->
+ {:halt, :error}
+ end)
+ end
+
def put([key], value), do: put(key, value)
def put([parent_key | keys], value) do
@@ -50,12 +66,15 @@ defmodule Pleroma.Config do
def delete([key]), do: delete(key)
- def delete([parent_key | keys]) do
- {_, parent} =
- Application.get_env(:pleroma, parent_key)
- |> get_and_update_in(keys, fn _ -> :pop end)
+ def delete([parent_key | keys] = path) do
+ with {:ok, _} <- fetch(path) do
+ {_, parent} =
+ parent_key
+ |> get()
+ |> get_and_update_in(keys, fn _ -> :pop end)
- Application.put_env(:pleroma, parent_key, parent)
+ Application.put_env(:pleroma, parent_key, parent)
+ end
end
def delete(key) do
diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex
index c7fb6aefa..ea8798fe3 100644
--- a/lib/pleroma/upload/filter/exiftool.ex
+++ b/lib/pleroma/upload/filter/exiftool.ex
@@ -9,9 +9,17 @@ defmodule Pleroma.Upload.Filter.Exiftool do
"""
@behaviour Pleroma.Upload.Filter
+ @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
- System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true)
- :ok
+ try do
+ case System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) do
+ {_response, 0} -> :ok
+ {error, 1} -> {:error, error}
+ end
+ rescue
+ _e in ErlangError ->
+ {:error, "exiftool command not found"}
+ end
end
def filter(_), do: :ok
diff --git a/lib/pleroma/upload/filter/mogrifun.ex b/lib/pleroma/upload/filter/mogrifun.ex
index 7d95577a4..a8503ac24 100644
--- a/lib/pleroma/upload/filter/mogrifun.ex
+++ b/lib/pleroma/upload/filter/mogrifun.ex
@@ -34,10 +34,15 @@ defmodule Pleroma.Upload.Filter.Mogrifun do
[{"fill", "yellow"}, {"tint", "40"}]
]
+ @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
- Filter.Mogrify.do_filter(file, [Enum.random(@filters)])
-
- :ok
+ try do
+ Filter.Mogrify.do_filter(file, [Enum.random(@filters)])
+ :ok
+ rescue
+ _e in ErlangError ->
+ {:error, "mogrify command not found"}
+ end
end
def filter(_), do: :ok
diff --git a/lib/pleroma/upload/filter/mogrify.ex b/lib/pleroma/upload/filter/mogrify.ex
index 2eb758006..7a45add5a 100644
--- a/lib/pleroma/upload/filter/mogrify.ex
+++ b/lib/pleroma/upload/filter/mogrify.ex
@@ -8,11 +8,15 @@ defmodule Pleroma.Upload.Filter.Mogrify do
@type conversion :: action :: String.t() | {action :: String.t(), opts :: String.t()}
@type conversions :: conversion() | [conversion()]
+ @spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
- filters = Pleroma.Config.get!([__MODULE__, :args])
-
- do_filter(file, filters)
- :ok
+ try do
+ do_filter(file, Pleroma.Config.get!([__MODULE__, :args]))
+ :ok
+ rescue
+ _e in ErlangError ->
+ {:error, "mogrify command not found"}
+ end
end
def filter(_), do: :ok
diff --git a/lib/pleroma/utils.ex b/lib/pleroma/utils.ex
index 6b8e3accf..21d1159be 100644
--- a/lib/pleroma/utils.ex
+++ b/lib/pleroma/utils.ex
@@ -9,4 +9,19 @@ defmodule Pleroma.Utils do
|> Enum.map(&Path.join(dir, &1))
|> Kernel.ParallelCompiler.compile()
end
+
+ @doc """
+ POSIX-compliant check if command is available in the system
+
+ ## Examples
+ iex> command_available?("git")
+ true
+ iex> command_available?("wrongcmd")
+ false
+
+ """
+ @spec command_available?(String.t()) :: boolean()
+ def command_available?(command) do
+ match?({_output, 0}, System.cmd("sh", ["-c", "command -v #{command}"]))
+ end
end
diff --git a/lib/pleroma/web/templates/layout/app.html.eex b/lib/pleroma/web/templates/layout/app.html.eex
index 5836ec1e0..51603fe0c 100644
--- a/lib/pleroma/web/templates/layout/app.html.eex
+++ b/lib/pleroma/web/templates/layout/app.html.eex
@@ -37,7 +37,7 @@
}
a {
- color: color: #d8a070;
+ color: #d8a070;
text-decoration: none;
}
diff --git a/mix.exs b/mix.exs
index 63142dee7..aab833c5e 100644
--- a/mix.exs
+++ b/mix.exs
@@ -229,10 +229,10 @@ defmodule Pleroma.Mixfile do
defp version(version) do
identifier_filter = ~r/[^0-9a-z\-]+/i
- {_cmdgit, cmdgit_err} = System.cmd("sh", ["-c", "command -v git"])
+ git_available? = match?({_output, 0}, System.cmd("sh", ["-c", "command -v git"]))
git_pre_release =
- if cmdgit_err == 0 do
+ if git_available? do
{tag, tag_err} =
System.cmd("git", ["describe", "--tags", "--abbrev=0"], stderr_to_stdout: true)
@@ -258,7 +258,7 @@ defmodule Pleroma.Mixfile do
# Branch name as pre-release version component, denoted with a dot
branch_name =
- with 0 <- cmdgit_err,
+ with true <- git_available?,
{branch_name, 0} <- System.cmd("git", ["rev-parse", "--abbrev-ref", "HEAD"]),
branch_name <- String.trim(branch_name),
branch_name <- System.get_env("PLEROMA_BUILD_BRANCH") || branch_name,
diff --git a/priv/repo/migrations/20200802170532_fix_legacy_tags.exs b/priv/repo/migrations/20200802170532_fix_legacy_tags.exs
new file mode 100644
index 000000000..f7274b44e
--- /dev/null
+++ b/priv/repo/migrations/20200802170532_fix_legacy_tags.exs
@@ -0,0 +1,37 @@
+# Fix legacy tags set by AdminFE that don't align with TagPolicy MRF
+
+defmodule Pleroma.Repo.Migrations.FixLegacyTags do
+ use Ecto.Migration
+ alias Pleroma.Repo
+ alias Pleroma.User
+ import Ecto.Query
+
+ @old_new_map %{
+ "force_nsfw" => "mrf_tag:media-force-nsfw",
+ "strip_media" => "mrf_tag:media-strip",
+ "force_unlisted" => "mrf_tag:force-unlisted",
+ "sandbox" => "mrf_tag:sandbox",
+ "disable_remote_subscription" => "mrf_tag:disable-remote-subscription",
+ "disable_any_subscription" => "mrf_tag:disable-any-subscription"
+ }
+
+ def change do
+ legacy_tags = Map.keys(@old_new_map)
+
+ from(u in User, where: fragment("? && ?", u.tags, ^legacy_tags))
+ |> Repo.all()
+ |> Enum.each(fn user ->
+ fix_tags_changeset(user)
+ |> Repo.update()
+ end)
+ end
+
+ defp fix_tags_changeset(%User{tags: tags} = user) do
+ new_tags =
+ Enum.map(tags, fn tag ->
+ Map.get(@old_new_map, tag, tag)
+ end)
+
+ Ecto.Changeset.change(user, tags: new_tags)
+ end
+end
diff --git a/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
new file mode 100644
index 000000000..389935f0d
--- /dev/null
+++ b/priv/repo/migrations/20200804180322_remove_nonlocal_expirations.exs
@@ -0,0 +1,19 @@
+defmodule Pleroma.Repo.Migrations.RemoveNonlocalExpirations do
+ use Ecto.Migration
+
+ def up do
+ statement = """
+ DELETE FROM
+ activity_expirations A USING activities B
+ WHERE
+ A.activity_id = B.id
+ AND B.local = false;
+ """
+
+ execute(statement)
+ end
+
+ def down do
+ :ok
+ end
+end
diff --git a/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
new file mode 100644
index 000000000..83de18096
--- /dev/null
+++ b/priv/repo/migrations/20200804183107_add_unique_index_to_app_client_id.exs
@@ -0,0 +1,7 @@
+defmodule Pleroma.Repo.Migrations.AddUniqueIndexToAppClientId do
+ use Ecto.Migration
+
+ def change do
+ create(unique_index(:apps, [:client_id]))
+ end
+end
diff --git a/test/config_test.exs b/test/config_test.exs
index a46ab4302..1556e4237 100644
--- a/test/config_test.exs
+++ b/test/config_test.exs
@@ -28,6 +28,34 @@ defmodule Pleroma.ConfigTest do
assert Pleroma.Config.get([:azerty, :uiop], true) == true
end
+ describe "nil values" do
+ setup do
+ Pleroma.Config.put(:lorem, nil)
+ Pleroma.Config.put(:ipsum, %{dolor: [sit: nil]})
+ Pleroma.Config.put(:dolor, sit: %{amet: nil})
+
+ on_exit(fn -> Enum.each(~w(lorem ipsum dolor)a, &Pleroma.Config.delete/1) end)
+ end
+
+ test "get/1 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem) == nil
+ end
+
+ test "get/2 with an atom for nil value" do
+ assert Pleroma.Config.get(:lorem, true) == nil
+ end
+
+ test "get/1 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit]) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet]) == nil
+ end
+
+ test "get/2 with a list of keys for nil value" do
+ assert Pleroma.Config.get([:ipsum, :dolor, :sit], true) == nil
+ assert Pleroma.Config.get([:dolor, :sit, :amet], true) == nil
+ end
+ end
+
test "get/1 when value is false" do
Pleroma.Config.put([:instance, :false_test], false)
Pleroma.Config.put([:instance, :nested], [])
@@ -89,5 +117,23 @@ defmodule Pleroma.ConfigTest do
Pleroma.Config.put([:delete_me, :delete_me], hello: "world", world: "Hello")
Pleroma.Config.delete([:delete_me, :delete_me, :world])
assert Pleroma.Config.get([:delete_me, :delete_me]) == [hello: "world"]
+
+ assert Pleroma.Config.delete([:this_key_does_not_exist])
+ assert Pleroma.Config.delete([:non, :existing, :key])
+ end
+
+ test "fetch/1" do
+ Pleroma.Config.put([:lorem], :ipsum)
+ Pleroma.Config.put([:ipsum], dolor: :sit)
+
+ assert Pleroma.Config.fetch([:lorem]) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch(:lorem) == {:ok, :ipsum}
+ assert Pleroma.Config.fetch([:ipsum, :dolor]) == {:ok, :sit}
+ assert Pleroma.Config.fetch([:lorem, :ipsum]) == :error
+ assert Pleroma.Config.fetch([:loremipsum]) == :error
+ assert Pleroma.Config.fetch(:loremipsum) == :error
+
+ Pleroma.Config.delete([:lorem])
+ Pleroma.Config.delete([:ipsum])
end
end
diff --git a/test/migrations/20200802170532_fix_legacy_tags_test.exs b/test/migrations/20200802170532_fix_legacy_tags_test.exs
new file mode 100644
index 000000000..3b4dee407
--- /dev/null
+++ b/test/migrations/20200802170532_fix_legacy_tags_test.exs
@@ -0,0 +1,24 @@
+defmodule Pleroma.Repo.Migrations.FixLegacyTagsTest do
+ alias Pleroma.User
+ use Pleroma.DataCase
+ import Pleroma.Factory
+ import Pleroma.Tests.Helpers
+
+ setup_all do: require_migration("20200802170532_fix_legacy_tags")
+
+ test "change/0 converts legacy user tags into correct values", %{migration: migration} do
+ user = insert(:user, tags: ["force_nsfw", "force_unlisted", "verified"])
+ user2 = insert(:user)
+
+ assert :ok == migration.change()
+
+ fixed_user = User.get_by_id(user.id)
+ fixed_user2 = User.get_by_id(user2.id)
+
+ assert fixed_user.tags == ["mrf_tag:media-force-nsfw", "mrf_tag:force-unlisted", "verified"]
+ assert fixed_user2.tags == []
+
+ # user2 should not have been updated
+ assert fixed_user2.updated_at == fixed_user2.inserted_at
+ end
+end
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index 5cbf2e291..ecd4b1e18 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -17,9 +17,19 @@ defmodule Pleroma.Tests.Helpers do
defmacro clear_config(config_path, do: yield) do
quote do
- initial_setting = Config.get(unquote(config_path))
+ initial_setting = Config.fetch(unquote(config_path))
unquote(yield)
- on_exit(fn -> Config.put(unquote(config_path), initial_setting) end)
+
+ on_exit(fn ->
+ case initial_setting do
+ :error ->
+ Config.delete(unquote(config_path))
+
+ {:ok, value} ->
+ Config.put(unquote(config_path), value)
+ end
+ end)
+
:ok
end
end
diff --git a/test/upload/filter/exiftool_test.exs b/test/upload/filter/exiftool_test.exs
index a1b7e46cd..8ed7d650b 100644
--- a/test/upload/filter/exiftool_test.exs
+++ b/test/upload/filter/exiftool_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.Upload.Filter.ExiftoolTest do
alias Pleroma.Upload.Filter
test "apply exiftool filter" do
+ assert Pleroma.Utils.command_available?("exiftool")
+
File.cp!(
"test/fixtures/DSCN0010.jpg",
"test/fixtures/DSCN0010_tmp.jpg"
diff --git a/test/web/oauth/app_test.exs b/test/web/oauth/app_test.exs
index 899af648e..993a490e0 100644
--- a/test/web/oauth/app_test.exs
+++ b/test/web/oauth/app_test.exs
@@ -29,5 +29,16 @@ defmodule Pleroma.Web.OAuth.AppTest do
assert exist_app.id == app.id
assert exist_app.scopes == ["read", "write", "follow", "push"]
end
+
+ test "has unique client_id" do
+ insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop")
+
+ error =
+ catch_error(insert(:oauth_app, client_name: "", redirect_uris: "", client_id: "boop"))
+
+ assert %Ecto.ConstraintError{} = error
+ assert error.constraint == "apps_client_id_index"
+ assert error.type == :unique
+ end
end
end