mirror of
https://github.com/team-alembic/ash_authentication.git
synced 2024-09-19 21:03:23 +12:00
improvement: move subject_name uniqueness validation to compile time.
This commit is contained in:
parent
13d3f0d2ab
commit
aa638e0230
2 changed files with 39 additions and 25 deletions
|
@ -69,9 +69,10 @@ defmodule AshAuthentication.Plug do
|
|||
do useful things like session and query param fetching.
|
||||
"""
|
||||
|
||||
alias Ash.{Changeset, Resource}
|
||||
alias Ash.{Api, Changeset, Resource}
|
||||
alias AshAuthentication.Plug.Helpers
|
||||
alias Plug.Conn
|
||||
alias Spark.Dsl.Extension
|
||||
|
||||
@type authenticator_config :: %{
|
||||
api: module,
|
||||
|
@ -110,9 +111,44 @@ defmodule AshAuthentication.Plug do
|
|||
|> Keyword.fetch!(:otp_app)
|
||||
|> Macro.expand_once(__CALLER__)
|
||||
|
||||
AshAuthentication.Validations.validate_unique_subject_names(otp_app)
|
||||
|
||||
quote do
|
||||
require Ash.Api.Info
|
||||
|
||||
unquote(otp_app)
|
||||
|> Application.compile_env(:ash_apis, [])
|
||||
|> Stream.flat_map(&Api.Info.depend_on_resources(&1))
|
||||
|> Stream.map(&{&1, Extension.get_persisted(&1, :authentication)})
|
||||
|> Stream.reject(&(elem(&1, 1) == nil))
|
||||
|> Stream.map(&{elem(&1, 0), elem(&1, 1).subject_name})
|
||||
|> Enum.group_by(&elem(&1, 1), &elem(&1, 0))
|
||||
|> Enum.reject(&(length(elem(&1, 1)) < 2))
|
||||
|> case do
|
||||
[] ->
|
||||
nil
|
||||
|
||||
duplicates ->
|
||||
import AshAuthentication.Utils, only: [to_sentence: 2]
|
||||
|
||||
duplicates =
|
||||
duplicates
|
||||
|> Enum.map(fn {subject_name, resources} ->
|
||||
resources =
|
||||
resources
|
||||
|> Enum.map(&"`#{inspect(&1)}`")
|
||||
|> to_sentence(final: "and")
|
||||
|
||||
" `#{subject_name}`: #{resources}\n"
|
||||
end)
|
||||
|
||||
raise """
|
||||
Error: There are multiple resources configured with the same subject name.
|
||||
|
||||
This is bad because we will be unable to correctly convert between subjects and resources.
|
||||
|
||||
#{duplicates}
|
||||
"""
|
||||
end
|
||||
|
||||
@behaviour AshAuthentication.Plug
|
||||
import Plug.Conn
|
||||
|
||||
|
|
|
@ -49,28 +49,6 @@ defmodule AshAuthentication.Validations do
|
|||
{:error, "Expected `#{inspect(field)}` to be present and contain one of #{values}"}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Validates the uniqueness of all subject names per otp app.
|
||||
"""
|
||||
@spec validate_unique_subject_names(module) :: :ok | no_return
|
||||
def validate_unique_subject_names(otp_app) do
|
||||
otp_app
|
||||
|> AshAuthentication.authenticated_resources()
|
||||
|> Enum.group_by(& &1.subject_name)
|
||||
|> Enum.each(fn
|
||||
{subject_name, configs} when length(configs) > 1 ->
|
||||
resources =
|
||||
configs
|
||||
|> Enum.map(&"`#{inspect(&1.resource)}`")
|
||||
|> AshAuthentication.Utils.to_sentence()
|
||||
|
||||
raise "Error: multiple resources use the `#{subject_name}` subject name: #{resources}"
|
||||
|
||||
_ ->
|
||||
:ok
|
||||
end)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Find and return a named attribute in the DSL state.
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue