diff --git a/.dialyzer_ignore.exs b/.dialyzer_ignore.exs deleted file mode 100644 index 833c446..0000000 --- a/.dialyzer_ignore.exs +++ /dev/null @@ -1,3 +0,0 @@ -[ - { "lib/phoenix/router.ex", :pattern_match, 402 } - ] \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 28fd5aa..bf2e5d4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,8 +18,8 @@ jobs: strategy: matrix: - elixir: [1.11] - otp: [23.1] + elixir: [1.12] + otp: [24.0] steps: - uses: actions/checkout@v2 @@ -54,8 +54,8 @@ jobs: strategy: matrix: - elixir: [1.11] - otp: [23.1] + elixir: [1.12] + otp: [24.0] steps: - uses: actions/checkout@v2 @@ -86,8 +86,8 @@ jobs: strategy: matrix: - elixir: [1.11] - otp: [23.1] + elixir: [1.12] + otp: [24.0] steps: - uses: actions/checkout@v2 @@ -110,7 +110,7 @@ jobs: id: plt-cache with: path: dializer/plts/ - key: ${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-plts-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + key: plt-${{ runner.os }}-${{ matrix.otp }}-${{ matrix.elixir }}-plts-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} - name: Generate PLT if: steps.plt-cache.outputs.cache-hit != 'true' @@ -119,7 +119,7 @@ jobs: mix dialyzer --plt - name: Run dialyzer - run: mix dialyzer --no-check --halt-exit-status + run: mix dialyzer --no-check tests: name: Tests @@ -128,8 +128,8 @@ jobs: strategy: matrix: - elixir: [1.11] - otp: [23.1] + elixir: [1.12] + otp: [24.0] services: postgres: diff --git a/.gitignore b/.gitignore index bbb0852..b9f4072 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ /cover/ # The directory where the files will be saved on every build. -/dialyzer/ +/dialyzer/plts/ # The directory Mix downloads your dependencies sources to. /deps/ diff --git a/.tool-versions b/.tool-versions index 0db5286..29940d1 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -elixir 1.11.4-otp-23 -erlang 23.1 +elixir 1.12.2-otp-24 +erlang 24.0 diff --git a/apps/authenticator/coveralls.json b/apps/authenticator/coveralls.json index 86f6730..89444c6 100644 --- a/apps/authenticator/coveralls.json +++ b/apps/authenticator/coveralls.json @@ -7,6 +7,7 @@ "skip_files": [ "test/support/data_case.ex", "test/support/factory.ex", + "lib/ports/resource_manager.ex", "lib/sign_in/commands/behaviour.ex", "lib/sessions/cache.ex", "lib/authenticator.ex", diff --git a/apps/authenticator/mix.exs b/apps/authenticator/mix.exs index 82a958b..f8b1c79 100644 --- a/apps/authenticator/mix.exs +++ b/apps/authenticator/mix.exs @@ -12,7 +12,7 @@ defmodule Authenticator.MixProject do elixirc_paths: elixirc_paths(Mix.env()), deps_path: "../../deps", lockfile: "../../mix.lock", - elixir: "~> 1.11", + elixir: "~> 1.12", start_permanent: Mix.env() == :prod, deps: deps(), aliases: aliases(), diff --git a/apps/authorizer/coveralls.json b/apps/authorizer/coveralls.json new file mode 100644 index 0000000..ce7927a --- /dev/null +++ b/apps/authorizer/coveralls.json @@ -0,0 +1,12 @@ +{ + "coverage_options": { + "treat_no_relevant_lines_as_covered": true, + "output_dir": "cover/", + "minimum_coverage": 80 + }, + "skip_files": [ + "test/support/data_case.ex", + "test/support/factory.ex", + "lib/ports/resource_manager.ex" + ] +} \ No newline at end of file diff --git a/apps/authorizer/mix.exs b/apps/authorizer/mix.exs index 078a21e..bc52fa3 100644 --- a/apps/authorizer/mix.exs +++ b/apps/authorizer/mix.exs @@ -12,7 +12,7 @@ defmodule Authorizer.MixProject do elixirc_paths: elixirc_paths(Mix.env()), deps_path: "../../deps", lockfile: "../../mix.lock", - elixir: "~> 1.11", + elixir: "~> 1.12", start_permanent: Mix.env() == :prod, deps: deps(), test_coverage: [tool: ExCoveralls] diff --git a/apps/resource_manager/coveralls.json b/apps/resource_manager/coveralls.json index 6d00107..65c538f 100644 --- a/apps/resource_manager/coveralls.json +++ b/apps/resource_manager/coveralls.json @@ -7,6 +7,7 @@ "skip_files": [ "test/support/data_case.ex", "test/support/factory.ex", + "lib/ports/authenticator.ex", "lib/resource_manager.ex", "lib/credentials/ports/*", "lib/application.ex", diff --git a/apps/resource_manager/lib/credentials/schemas/password.ex b/apps/resource_manager/lib/credentials/schemas/password.ex index 38bbbe0..cdd7c86 100644 --- a/apps/resource_manager/lib/credentials/schemas/password.ex +++ b/apps/resource_manager/lib/credentials/schemas/password.ex @@ -26,8 +26,8 @@ defmodule ResourceManager.Credentials.Schemas.Password do password_hash: String.t(), algorithm: String.t(), salt: integer(), - inserted_at: Datetime.t(), - updated_at: Datetime.t() + inserted_at: NaiveDatetime.t(), + updated_at: NaiveDatetime.t() } # Changeset validation arguments @@ -51,7 +51,7 @@ defmodule ResourceManager.Credentials.Schemas.Password do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @optional_fields) diff --git a/apps/resource_manager/lib/credentials/schemas/public_key.ex b/apps/resource_manager/lib/credentials/schemas/public_key.ex index 669d919..d102326 100644 --- a/apps/resource_manager/lib/credentials/schemas/public_key.ex +++ b/apps/resource_manager/lib/credentials/schemas/public_key.ex @@ -44,7 +44,7 @@ defmodule ResourceManager.Credentials.Schemas.PublicKey do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required_fields ++ @optional_fields) diff --git a/apps/resource_manager/lib/domain.ex b/apps/resource_manager/lib/domain.ex index 01ad45e..f8c8804 100644 --- a/apps/resource_manager/lib/domain.ex +++ b/apps/resource_manager/lib/domain.ex @@ -7,6 +7,8 @@ defmodule ResourceManager.Domain do quote do alias ResourceManager.Repo + require Logger + @schema unquote(opts[:schema_model]) @typedoc "Possible response types" @@ -18,6 +20,15 @@ defmodule ResourceManager.Domain do params |> @schema.changeset() |> Repo.insert() + |> case do + {:ok, _model} = response -> + Logger.debug("#{inspect(@schema)} created with success") + response + + {:error, reason} = response -> + Logger.debug("#{inspect(@schema)} creation failed because #{inspect(reason)}") + response + end end @doc "Updates a #{@schema} with the given params" @@ -26,11 +37,32 @@ defmodule ResourceManager.Domain do model |> @schema.changeset(params) |> Repo.update() + |> case do + {:ok, _model} = response -> + Logger.debug("#{inspect(@schema)} updated with success") + response + + {:error, reason} = response -> + Logger.debug("#{inspect(@schema)} update failed because #{inspect(reason)}") + response + end end @doc "Deletes a #{@schema} from the database" @spec delete(model :: @schema.t()) :: {:ok, @schema.t()} - def delete(%@schema{} = model), do: Repo.delete(model) + def delete(%@schema{} = model) do + model + |> Repo.delete() + |> case do + {:ok, _model} = response -> + Logger.debug("#{inspect(@schema)} deleted with success") + response + + {:error, reason} = response -> + Logger.debug("#{inspect(@schema)} delete failed because #{inspect(reason)}") + response + end + end @doc "Checks if a #{@schema} exists with the given fields" @spec exists?(fields :: Keyword.t()) :: boolean() diff --git a/apps/resource_manager/lib/identities/commands/create_client_application.ex b/apps/resource_manager/lib/identities/commands/create_client_application.ex index 61cf2e0..2d2360e 100644 --- a/apps/resource_manager/lib/identities/commands/create_client_application.ex +++ b/apps/resource_manager/lib/identities/commands/create_client_application.ex @@ -47,8 +47,8 @@ defmodule ResourceManager.Identities.Commands.CreateClientApplication do |> ClientApplications.create() end - defp create_permission(client_application, %{scopes: scopes}), + defp create_permission(client_application, %{scopes: scopes}) when is_list(scopes), do: ConsentScope.execute(client_application, scopes) - defp create_permission(_client_application, _), do: {:ok, :ignore} + defp create_permission(_client_application, _permission), do: {:ok, :ignore} end diff --git a/apps/resource_manager/lib/identities/commands/create_user.ex b/apps/resource_manager/lib/identities/commands/create_user.ex index 46a657f..961a4ba 100644 --- a/apps/resource_manager/lib/identities/commands/create_user.ex +++ b/apps/resource_manager/lib/identities/commands/create_user.ex @@ -47,6 +47,8 @@ defmodule ResourceManager.Identities.Commands.CreateUser do |> Users.create() end - defp create_permission(user, %{scopes: scopes}), do: ConsentScope.execute(user, scopes) - defp create_permission(_user, _), do: {:ok, :ignore} + defp create_permission(user, %{scopes: scopes}) when is_list(scopes), + do: ConsentScope.execute(user, scopes) + + defp create_permission(_user, _permission), do: {:ok, :ignore} end diff --git a/apps/resource_manager/lib/identities/schemas/client_application.ex b/apps/resource_manager/lib/identities/schemas/client_application.ex index 27dae10..8c0d1f2 100644 --- a/apps/resource_manager/lib/identities/schemas/client_application.ex +++ b/apps/resource_manager/lib/identities/schemas/client_application.ex @@ -61,7 +61,7 @@ defmodule ResourceManager.Identities.Schemas.ClientApplication do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required_fields ++ @optional_fields) diff --git a/apps/resource_manager/lib/identities/schemas/user.ex b/apps/resource_manager/lib/identities/schemas/user.ex index 46924c8..4523f97 100644 --- a/apps/resource_manager/lib/identities/schemas/user.ex +++ b/apps/resource_manager/lib/identities/schemas/user.ex @@ -47,7 +47,7 @@ defmodule ResourceManager.Identities.Schemas.User do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required_fields ++ @optional_fields) diff --git a/apps/resource_manager/lib/permissions/commands/remove_scope.ex b/apps/resource_manager/lib/permissions/commands/remove_scope.ex index 37591c2..4ef54c8 100644 --- a/apps/resource_manager/lib/permissions/commands/remove_scope.ex +++ b/apps/resource_manager/lib/permissions/commands/remove_scope.ex @@ -9,14 +9,8 @@ defmodule ResourceManager.Permissions.Commands.RemoveScope do alias ResourceManager.Permissions.Schemas.{ClientApplicationScope, UserScope} alias ResourceManager.Repo - @typedoc "All possible identities" - @type identities :: User.t() | ClientApplication.t() - - @typedoc "All possible responses" - @type possible_response :: {:ok, list(identities())} | {:error, Ecto.Changeset.t()} - @doc "Remove scopes from the identity" - @spec execute(identity :: identities(), scopes :: list(String.t())) :: possible_response() + @spec execute(identity :: User.t() | ClientApplication.t(), scopes :: list(String.t())) :: :ok def execute(%User{} = user, scopes) when is_list(scopes) do Logger.debug("Removing scopes from user #{user.id}") diff --git a/apps/resource_manager/lib/permissions/schema/client_application_scope.ex b/apps/resource_manager/lib/permissions/schemas/client_application_scope.ex similarity index 95% rename from apps/resource_manager/lib/permissions/schema/client_application_scope.ex rename to apps/resource_manager/lib/permissions/schemas/client_application_scope.ex index 4d4c145..f4eb2c9 100644 --- a/apps/resource_manager/lib/permissions/schema/client_application_scope.ex +++ b/apps/resource_manager/lib/permissions/schemas/client_application_scope.ex @@ -37,7 +37,7 @@ defmodule ResourceManager.Permissions.Schemas.ClientApplicationScope do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required_fields) diff --git a/apps/resource_manager/lib/permissions/schema/scope.ex b/apps/resource_manager/lib/permissions/schemas/scope.ex similarity index 93% rename from apps/resource_manager/lib/permissions/schema/scope.ex rename to apps/resource_manager/lib/permissions/schemas/scope.ex index 07b4710..c42bfc5 100644 --- a/apps/resource_manager/lib/permissions/schema/scope.ex +++ b/apps/resource_manager/lib/permissions/schemas/scope.ex @@ -34,7 +34,7 @@ defmodule ResourceManager.Permissions.Schemas.Scope do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required ++ @optional) diff --git a/apps/resource_manager/lib/permissions/schema/user_scope.ex b/apps/resource_manager/lib/permissions/schemas/user_scope.ex similarity index 95% rename from apps/resource_manager/lib/permissions/schema/user_scope.ex rename to apps/resource_manager/lib/permissions/schemas/user_scope.ex index b45a145..8fbf685 100644 --- a/apps/resource_manager/lib/permissions/schema/user_scope.ex +++ b/apps/resource_manager/lib/permissions/schemas/user_scope.ex @@ -37,7 +37,7 @@ defmodule ResourceManager.Permissions.Schemas.UserScope do def changeset(params) when is_map(params), do: changeset(%__MODULE__{}, params) @doc "Generates an `%Ecto.Changeset to be used in update operations." - @spec changeset(model :: __MODULE__.t(), params :: map()) :: Ecto.Changeset.t() + @spec changeset(model :: %__MODULE__{}, params :: map()) :: Ecto.Changeset.t() def changeset(%__MODULE__{} = model, params) when is_map(params) do model |> cast(params, @required_fields) diff --git a/apps/resource_manager/mix.exs b/apps/resource_manager/mix.exs index ed8452b..ad6d173 100644 --- a/apps/resource_manager/mix.exs +++ b/apps/resource_manager/mix.exs @@ -12,7 +12,7 @@ defmodule ResourceManager.MixProject do elixirc_paths: elixirc_paths(Mix.env()), deps_path: "../../deps", lockfile: "../../mix.lock", - elixir: "~> 1.11", + elixir: "~> 1.12", start_permanent: Mix.env() == :prod, aliases: aliases(), deps: deps(), diff --git a/apps/rest_api/coveralls.json b/apps/rest_api/coveralls.json index abb7dbe..ed160cb 100644 --- a/apps/rest_api/coveralls.json +++ b/apps/rest_api/coveralls.json @@ -6,6 +6,9 @@ }, "skip_files": [ "test/support/conn_case.ex", + "lib/ports/authenticator.ex", + "lib/ports/authorizer.ex", + "lib/ports/resource_manager.ex", "lib/application.ex", "lib/controller.ex", "lib/telemetry.ex", diff --git a/apps/rest_api/lib/plugs/tracker.ex b/apps/rest_api/lib/plugs/tracker.ex index e1ac57d..ee9b97d 100644 --- a/apps/rest_api/lib/plugs/tracker.ex +++ b/apps/rest_api/lib/plugs/tracker.ex @@ -20,9 +20,7 @@ defmodule RestAPI.Plugs.Tracker do "request_id" => get_request_id(conn) } - Logger.metadata(traking_data) - - put_private(conn, :tracking, traking_data) + append_tracking_data(conn, traking_data) end defp get_remote_ip(conn) do @@ -48,4 +46,12 @@ defmodule RestAPI.Plugs.Tracker do [request_id | _] -> request_id end end + + defp append_tracking_data(conn, traking_data) do + traking_data + |> Enum.map(fn {key, value} -> {String.to_atom(key), value} end) + |> Logger.metadata() + + put_private(conn, :tracking, traking_data) + end end diff --git a/apps/rest_api/mix.exs b/apps/rest_api/mix.exs index 808e56f..f170165 100644 --- a/apps/rest_api/mix.exs +++ b/apps/rest_api/mix.exs @@ -11,7 +11,7 @@ defmodule RestAPI.MixProject do config_path: "../../config/config.exs", deps_path: "../../deps", lockfile: "../../mix.lock", - elixir: "~> 1.11", + elixir: "~> 1.12", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, diff --git a/dialyzer/ignore-warnings.exs b/dialyzer/ignore-warnings.exs new file mode 100644 index 0000000..45d0a33 --- /dev/null +++ b/dialyzer/ignore-warnings.exs @@ -0,0 +1,33 @@ +[ + {"lib/identities/users.ex", :no_return}, + {"lib/identities/users.ex", :unknown_type}, + {"lib/identities/client_applications.ex", :no_return}, + {"lib/identities/client_applications.ex", :unknown_type}, + {"lib/identities/schemas/user.ex", :no_return}, + {"lib/identities/schemas/user.ex", :unknown_type}, + {"lib/identities/schemas/client_application.ex", :no_return}, + {"lib/identities/schemas/client_application.ex", :unknown_type}, + {"lib/identities/commands/create_user.ex", :unknown_type}, + {"lib/identities/commands/create_client_application.ex", :unknown_type}, + {"lib/identities/commands/get_identity.ex", :unknown_type}, + {"lib/credentials/passwords.ex", :no_return}, + {"lib/credentials/passwords.ex", :unknown_type}, + {"lib/credentials/public_keys.ex", :no_return}, + {"lib/credentials/public_keys.ex", :unknown_type}, + {"lib/credentials/schemas/password.ex", :no_return}, + {"lib/credentials/schemas/password.ex", :unknown_type}, + {"lib/credentials/schemas/public_key.ex", :no_return}, + {"lib/credentials/schemas/public_key.ex", :unknown_type}, + {"lib/credentials/passwords.ex", :unknown_type}, + {"lib/permissions/scopes.ex", :no_return}, + {"lib/permissions/scopes.ex", :unknown_type}, + {"lib/permissions/schemas/scope.ex", :no_return}, + {"lib/permissions/schemas/scope.ex", :unknown_type}, + {"lib/permissions/schemas/user_scope.ex", :no_return}, + {"lib/permissions/schemas/user_scope.ex", :unknown_type}, + {"lib/permissions/schemas/client_application_scope.ex", :no_return}, + {"lib/permissions/schemas/client_application_scope.ex", :unknown_type}, + {"lib/permissions/commands/consent_scope.ex", :unknown_type}, + {"lib/permissions/commands/remove_scope.ex", :unknown_type}, + {"lib/phoenix/router.ex", :pattern_match, 402} +] diff --git a/mix.exs b/mix.exs index 0c60ada..7c94948 100644 --- a/mix.exs +++ b/mix.exs @@ -36,7 +36,7 @@ defmodule WatcherEx.MixProject do # Tools {:junit_formatter, "~> 3.2", only: [:test]}, {:dialyxir, "~> 1.1", only: [:dev, :test], runtime: false}, - {:credo, "~> 1.5", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.5", only: [:dev, :test], runtime: true}, {:ex_doc, "~> 0.24", only: :dev, runtime: false}, {:excoveralls, "~> 0.14", only: :test}, {:mox, "~> 0.5", only: :test} @@ -69,8 +69,8 @@ defmodule WatcherEx.MixProject do [ plt_add_apps: [:ex_unit], plt_core_path: "dialyzer/plts/", - plt_file: {:no_warn, "dialyzer/plts/watcher_ex.plt"}, - ignore_warnings: "dialyzer.ignore-warnings" + plt_file: {:no_warn, "dialyzer/plts/dialyzer.plt"}, + ignore_warnings: "dialyzer/ignore-warnings.exs" ] end