diff --git a/.check.exs b/.check.exs new file mode 100644 index 00000000..7fda557e --- /dev/null +++ b/.check.exs @@ -0,0 +1,33 @@ +[ + ## don't run tools concurrently + # parallel: false, + + ## don't print info about skipped tools + # skipped: false, + + ## always run tools in fix mode (put it in ~/.check.exs locally, not in project config) + # fix: true, + + ## don't retry automatically even if last run resulted in failures + # retry: false, + + ## list of tools (see `mix check` docs for a list of default curated tools) + tools: [ + ## curated tools may be disabled (e.g. the check for compilation warnings) + # {:compiler, false}, + + ## ...or have command & args adjusted (e.g. enable skip comments for sobelow) + {:sobelow, "mix sobelow --config"}, + + ## ...or reordered (e.g. to see output from dialyzer before others) + # {:dialyzer, order: -1}, + + ## ...or reconfigured (e.g. disable parallel execution of ex_unit in umbrella) + # {:ex_unit, umbrella: [parallel: false]}, + + ## custom new tools may be added (Mix tasks or arbitrary commands) + # {:my_task, "mix my_task", env: %{"MIX_ENV" => "prod"}}, + # {:my_tool, ["my_tool", "arg with spaces"]} + {:credo, "mix credo --strict"} + ] +] diff --git a/.github/workflows/elixir_lib.yml b/.github/workflows/elixir_lib.yml index a3853375..1a08b39d 100644 --- a/.github/workflows/elixir_lib.yml +++ b/.github/workflows/elixir_lib.yml @@ -116,6 +116,25 @@ jobs: - uses: team-alembic/staple-actions/actions/conventional-commit@main with: mix-env: test + sobelow: + name: mix sobelow --config + runs-on: ubuntu-latest + needs: build-test + steps: + - uses: actions/checkout@v3 + - uses: team-alembic/staple-actions/actions/mix-sobelow@main + with: + mix-env: test + + unused_deps: + name: mix deps.unlock --check-unused + runs-on: ubuntu-latest + needs: build-test + steps: + - uses: actions/checkout@v3 + - uses: team-alembic/staple-actions/actions/mix-deps-unlock@main + with: + mix-env: test build-dev: name: MIX_ENV=dev mix.compile @@ -128,6 +147,8 @@ jobs: - auditor - test - dialyzer + - sobelow + - unused_deps if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} steps: - uses: actions/checkout@v3 diff --git a/.sobelow-conf b/.sobelow-conf new file mode 100644 index 00000000..de10f24b --- /dev/null +++ b/.sobelow-conf @@ -0,0 +1,12 @@ +[ + verbose: false, + private: false, + skip: true, + router: "", + exit: "low", + format: "txt", + out: "", + threshold: "low", + ignore: [], + ignore_files: [""] +] diff --git a/lib/ash_authentication/plug/helpers.ex b/lib/ash_authentication/plug/helpers.ex index 3ebc7650..92e0d06f 100644 --- a/lib/ash_authentication/plug/helpers.ex +++ b/lib/ash_authentication/plug/helpers.ex @@ -255,6 +255,7 @@ defmodule AshAuthentication.Plug.Helpers do # Dyanamically generated atoms are generally frowned upon, but in this case # the `subject_name` is a statically configured atom, so should be fine. + # sobelow_skip ["DOS.StringToAtom"] defp current_subject_name(subject_name) when is_atom(subject_name), do: String.to_atom("current_#{subject_name}") end diff --git a/lib/ash_authentication/strategies/magic_link/transformer.ex b/lib/ash_authentication/strategies/magic_link/transformer.ex index 1b3e3d85..100c613e 100644 --- a/lib/ash_authentication/strategies/magic_link/transformer.ex +++ b/lib/ash_authentication/strategies/magic_link/transformer.ex @@ -48,13 +48,15 @@ defmodule AshAuthentication.Strategy.MagicLink.Transformer do end end + # sobelow_skip ["DOS.StringToAtom"] defp maybe_set_sign_in_action_name(strategy) when is_nil(strategy.sign_in_action_name), - do: %{strategy | sign_in_action_name: :"sign_in_with_#{strategy.name}"} + do: %{strategy | sign_in_action_name: String.to_atom("sign_in_with_#{strategy.name}")} defp maybe_set_sign_in_action_name(strategy), do: strategy + # sobelow_skip ["DOS.StringToAtom"] defp maybe_set_request_action_name(strategy) when is_nil(strategy.request_action_name), - do: %{strategy | request_action_name: :"request_#{strategy.name}"} + do: %{strategy | request_action_name: String.to_atom("request_#{strategy.name}")} defp maybe_set_request_action_name(strategy), do: strategy diff --git a/lib/ash_authentication/strategies/oauth2/identity_change.ex b/lib/ash_authentication/strategies/oauth2/identity_change.ex index 5487f199..ea55ba07 100644 --- a/lib/ash_authentication/strategies/oauth2/identity_change.ex +++ b/lib/ash_authentication/strategies/oauth2/identity_change.ex @@ -26,6 +26,7 @@ defmodule AshAuthentication.Strategy.OAuth2.IdentityChange do defp do_change(changeset, strategy) when is_falsy(strategy.identity_resource), do: changeset + # sobelow_skip ["DOS.BinToAtom"] defp do_change(changeset, strategy) do changeset |> Changeset.after_action(fn changeset, user -> diff --git a/lib/ash_authentication/strategies/oauth2/plug.ex b/lib/ash_authentication/strategies/oauth2/plug.ex index 5d4039e7..516035bc 100644 --- a/lib/ash_authentication/strategies/oauth2/plug.ex +++ b/lib/ash_authentication/strategies/oauth2/plug.ex @@ -27,6 +27,7 @@ defmodule AshAuthentication.Strategy.OAuth2.Plug do user to that endpoint. """ @spec request(Conn.t(), OAuth2.t()) :: Conn.t() + # sobelow_skip ["XSS.SendResp"] def request(conn, strategy) do with {:ok, config} <- config_for(strategy), {:ok, config} <- maybe_add_nonce(config, strategy), diff --git a/lib/ash_authentication/strategies/oauth2/transformer.ex b/lib/ash_authentication/strategies/oauth2/transformer.ex index 0d0839ec..640b3711 100644 --- a/lib/ash_authentication/strategies/oauth2/transformer.ex +++ b/lib/ash_authentication/strategies/oauth2/transformer.ex @@ -48,6 +48,7 @@ defmodule AshAuthentication.Strategy.OAuth2.Transformer do end end + # sobelow_skip ["DOS.BinToAtom"] defp set_defaults(strategy) do strategy |> maybe_set_field_lazy(:register_action_name, &:"register_with_#{&1.name}") diff --git a/lib/ash_authentication/strategies/password/transformer.ex b/lib/ash_authentication/strategies/password/transformer.ex index 093d7f45..0410d3af 100644 --- a/lib/ash_authentication/strategies/password/transformer.ex +++ b/lib/ash_authentication/strategies/password/transformer.ex @@ -17,6 +17,7 @@ defmodule AshAuthentication.Strategy.Password.Transformer do @doc false @spec transform(Password.t(), map) :: {:ok, Password.t() | map} | {:error, Exception.t()} + # sobelow_skip ["DOS.BinToAtom"] def transform(strategy, dsl_state) do with :ok <- validate_identity_field(strategy.identity_field, dsl_state), :ok <- validate_hashed_password_field(strategy.hashed_password_field, dsl_state), @@ -350,6 +351,7 @@ defmodule AshAuthentication.Strategy.Password.Transformer do defp maybe_transform_resettable(dsl_state, %{resettable: []} = strategy), do: {:ok, dsl_state, strategy} + # sobelow_skip ["DOS.BinToAtom"] defp maybe_transform_resettable(dsl_state, %{resettable: [resettable]} = strategy) do with resettable <- maybe_set_field_lazy( diff --git a/lib/ash_authentication/transformer.ex b/lib/ash_authentication/transformer.ex index c0426636..fca378eb 100644 --- a/lib/ash_authentication/transformer.ex +++ b/lib/ash_authentication/transformer.ex @@ -61,6 +61,7 @@ defmodule AshAuthentication.Transformer do end end + # sobelow_skip ["DOS.StringToAtom"] defp find_or_generate_subject_name(dsl_state) do with nil <- Transformer.get_option(dsl_state, [:authentication], :subject_name), nil <- Transformer.get_option(dsl_state, [:resource], :short_name) do diff --git a/lib/ash_authentication/user_identity/transformer.ex b/lib/ash_authentication/user_identity/transformer.ex index 0c915c8f..28d10aa1 100644 --- a/lib/ash_authentication/user_identity/transformer.ex +++ b/lib/ash_authentication/user_identity/transformer.ex @@ -332,6 +332,7 @@ defmodule AshAuthentication.UserIdentity.Transformer do end) end + # sobelow_skip ["DOS.StringToAtom"] defp maybe_build_identity(dsl_state, keys) do dsl_state |> find_identity(keys) diff --git a/mix.exs b/mix.exs index 4458cc24..75494a20 100644 --- a/mix.exs +++ b/mix.exs @@ -197,11 +197,14 @@ defmodule AshAuthentication.MixProject do {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:dialyxir, "~> 1.2", only: [:dev, :test], runtime: false}, {:doctor, "~> 0.18", only: [:dev, :test]}, + {:ex_check, "~> 0.15", only: [:dev, :test]}, {:ex_doc, ">= 0.0.0", only: [:dev, :test]}, {:faker, "~> 0.17.0", only: [:dev, :test]}, {:git_ops, "~> 2.4", only: [:dev, :test], runtime: false}, {:mimic, "~> 1.7", only: [:dev, :test]}, - {:plug_cowboy, "~> 2.5", only: [:dev, :test]} + {:mix_audit, "~> 2.1", only: [:dev, :test]}, + {:plug_cowboy, "~> 2.5", only: [:dev, :test]}, + {:sobelow, "~> 0.12", only: [:dev, :test]} ] end diff --git a/mix.lock b/mix.lock index b28aed72..91b0a551 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,6 @@ "castore": {:hex, :castore, "1.0.3", "7130ba6d24c8424014194676d608cb989f62ef8039efd50ff4b3f33286d06db8", [:mix], [], "hexpm", "680ab01ef5d15b161ed6a95449fac5c6b8f60055677a8e79acf01b27baa4390b"}, "comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"}, "comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"}, - "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "conv_case": {:hex, :conv_case, "0.2.3", "c1455c27d3c1ffcdd5f17f1e91f40b8a0bc0a337805a6e8302f441af17118ed8", [:mix], [], "hexpm", "88f29a3d97d1742f9865f7e394ed3da011abb7c5e8cc104e676fdef6270d4b4a"}, "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, @@ -28,6 +27,7 @@ "elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ets": {:hex, :ets, "0.8.1", "8ff9bcda5682b98493f8878fc9dbd990e48d566cba8cce59f7c2a78130da29ea", [:mix], [], "hexpm", "6be41b50adb5bc5c43626f25ea2d0af1f4a242fb3fad8d53f0c67c20b78915cc"}, + "ex_check": {:hex, :ex_check, "0.15.0", "074b94c02de11c37bba1ca82ae5cc4926e6ccee862e57a485b6ba60fca2d8dc1", [:mix], [], "hexpm", "33848031a0c7e4209c3b4369ce154019788b5219956220c35ca5474299fb6a0e"}, "ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"}, "faker": {:hex, :faker, "0.17.0", "671019d0652f63aefd8723b72167ecdb284baf7d47ad3a82a15e9b8a6df5d1fa", [:mix], [], "hexpm", "a7d4ad84a93fd25c5f5303510753789fc2433ff241bf3b4144d3f6f291658a6a"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, @@ -44,6 +44,7 @@ "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, "mimic": {:hex, :mimic, "1.7.4", "cd2772ffbc9edefe964bc668bfd4059487fa639a5b7f1cbdf4fd22946505aa4f", [:mix], [], "hexpm", "437c61041ecf8a7fae35763ce89859e4973bb0666e6ce76d75efc789204447c3"}, "mint": {:hex, :mint, "1.5.1", "8db5239e56738552d85af398798c80648db0e90f343c8469f6c6d8898944fb6f", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "4a63e1e76a7c3956abd2c72f370a0d0aecddc3976dea5c27eccbecfa5e7d5b1e"}, + "mix_audit": {:hex, :mix_audit, "2.1.0", "3c0dafb29114dffcdb508164a3d35311a9ac2c5baeba6495c9cd5315c25902b9", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.9", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "14c57a23e0a5f652c1e7f6e8dab93f166f66d63bd0c85f97278f5972b14e2be0"}, "nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, "picosat_elixir": {:hex, :picosat_elixir, "0.2.3", "bf326d0f179fbb3b706bb2c15fbc367dacfa2517157d090fdfc32edae004c597", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f76c9db2dec9d2561ffaa9be35f65403d53e984e8cd99c832383b7ab78c16c66"}, @@ -52,10 +53,13 @@ "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"}, "postgrex": {:hex, :postgrex, "0.17.1", "01c29fd1205940ee55f7addb8f1dc25618ca63a8817e56fac4f6846fc2cddcbe", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "14b057b488e73be2beee508fb1955d8db90d6485c6466428fe9ccf1d6692a555"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, + "sobelow": {:hex, :sobelow, "0.12.2", "45f4d500e09f95fdb5a7b94c2838d6b26625828751d9f1127174055a78542cf5", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "2f0b617dce551db651145662b84c8da4f158e7abe049a76daaaae2282df01c5d"}, "sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"}, "spark": {:hex, :spark, "1.1.15", "c0db345f030c928d2c9cf8dbf7574c635664d54b3afaf64ec9c1481d20c48b66", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "bd7da17b8af5acd39e49b9dbdc98a21132cade2ff70e6283e09f37a4657362b8"}, "stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "typable": {:hex, :typable, "0.3.0", "0431e121d124cd26f312123e313d2689b9a5322b15add65d424c07779eaa3ca1", [:mix], [], "hexpm", "880a0797752da1a4c508ac48f94711e04c86156f498065a83d160eef945858f8"}, "xema": {:hex, :xema, "0.17.0", "982e397ce0af55cdf1c6bf9c5ee6e20c5ea4a24e58e5266339cfff0dadbfa01e", [:mix], [{:conv_case, "~> 0.2.2", [hex: :conv_case, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "9020afc75c5b9fba1c5875fd735a19c3c544db058cd97ef4c4675e479fc8bcbe"}, + "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, + "yaml_elixir": {:hex, :yaml_elixir, "2.9.0", "9a256da867b37b8d2c1ffd5d9de373a4fda77a32a45b452f1708508ba7bbcb53", [:mix], [{:yamerl, "~> 0.10", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "0cb0e7d4c56f5e99a6253ed1a670ed0e39c13fc45a6da054033928607ac08dfc"}, }