mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
fix: don't allow get! to return nil
fix: don't do db filters on creation
This commit is contained in:
parent
64ec412e5d
commit
97e08f7b92
4 changed files with 62 additions and 6 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -31,3 +31,5 @@ ash-*.tar
|
|||
/Mnesia.*
|
||||
|
||||
.DS_Store
|
||||
|
||||
.vscode
|
||||
|
|
|
@ -41,6 +41,8 @@ defmodule Ash.Api do
|
|||
NoSuchResource
|
||||
}
|
||||
|
||||
alias Ash.Error.Query.NotFound
|
||||
|
||||
alias Ash.Dsl.Extension
|
||||
|
||||
require Ash.Query
|
||||
|
@ -477,7 +479,7 @@ defmodule Ash.Api do
|
|||
|
||||
@doc false
|
||||
@spec get(Ash.Api.t(), Ash.Resource.t(), term(), Keyword.t()) ::
|
||||
{:ok, Ash.Resource.record() | nil} | {:error, term}
|
||||
{:ok, Ash.Resource.record()} | {:error, term}
|
||||
def get(api, resource, id, opts) do
|
||||
with {:ok, opts} <- Ash.OptionsHelpers.validate(opts, @get_opts_schema),
|
||||
{:ok, resource} <- Ash.Api.resource(api, resource),
|
||||
|
@ -504,7 +506,11 @@ defmodule Ash.Api do
|
|||
{:ok, single_result}
|
||||
|
||||
{:ok, %{results: []}} ->
|
||||
{:ok, nil}
|
||||
{:error,
|
||||
NotFound.exception(
|
||||
primary_key: filter,
|
||||
resource: resource
|
||||
)}
|
||||
|
||||
{:ok, %{results: results}} ->
|
||||
{:error,
|
||||
|
|
|
@ -743,6 +743,35 @@ defmodule Ash.Engine.Request do
|
|||
end
|
||||
end
|
||||
|
||||
defp do_runtime_filter(%{action: %{type: :create}, changeset: changeset} = request, filter) do
|
||||
{:ok, fake_result} = Ash.Changeset.apply_attributes(changeset, force?: true)
|
||||
|
||||
case Ash.Filter.parse(request.resource, filter) do
|
||||
{:ok, filter} ->
|
||||
case Ash.Filter.Runtime.do_match(fake_result, filter) do
|
||||
{:ok, true} ->
|
||||
{:ok, request}
|
||||
|
||||
{:ok, false} ->
|
||||
{:error, Ash.Error.Forbidden.exception([])}
|
||||
|
||||
:unknown ->
|
||||
Logger.error("""
|
||||
Could not apply filter policy because it cannot be checked using Ash.Filter.Runtime: #{inspect(filter)}.
|
||||
|
||||
If you are using ash_policy_authorizer policy must include a filter like this, try setting the access_type to `:runtime`"
|
||||
|
||||
Otherwise, please report this issue: https://github.com/ash-project/ash_policy_authorizer/issues/new?assignees=&labels=bug%2C+needs+review&template=bug_report.md&title=
|
||||
""")
|
||||
|
||||
{:error, Ash.Error.Forbidden.exception([])}
|
||||
end
|
||||
|
||||
{:error, error} ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
|
||||
defp do_runtime_filter(request, filter) do
|
||||
pkey = Ash.Resource.Info.primary_key(request.resource)
|
||||
|
||||
|
@ -771,6 +800,13 @@ defmodule Ash.Engine.Request do
|
|||
{:error, error} ->
|
||||
{:error, error}
|
||||
end
|
||||
rescue
|
||||
e ->
|
||||
Logger.error(
|
||||
"Exception while running authorization query: #{inspect(Exception.message(e))}"
|
||||
)
|
||||
|
||||
{:error, Ash.Error.Forbidden.exception([])}
|
||||
end
|
||||
|
||||
defp try_resolve(request, deps, internal?) do
|
||||
|
|
|
@ -21,10 +21,22 @@ defmodule Ash.Error.Query.NotFound do
|
|||
|
||||
def stacktrace(_), do: nil
|
||||
|
||||
defp id_string(map) do
|
||||
defp id_string(%Ash.Filter{} = filter) do
|
||||
inspect(filter)
|
||||
end
|
||||
|
||||
defp id_string(map) when is_map(map) do
|
||||
if Map.has_key?(map, :__struct__) do
|
||||
inspect(map)
|
||||
else
|
||||
Enum.map_join(map, " | ", fn {key, value} ->
|
||||
"#{key}: #{inspect(value)}"
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defp id_string(other) do
|
||||
inspect(other)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue