fix: don't allow get! to return nil

fix: don't do db filters on creation
This commit is contained in:
Zach Daniel 2021-09-08 23:57:45 -04:00
parent 64ec412e5d
commit 97e08f7b92
4 changed files with 62 additions and 6 deletions

2
.gitignore vendored
View file

@ -31,3 +31,5 @@ ash-*.tar
/Mnesia.*
.DS_Store
.vscode

View file

@ -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,

View file

@ -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

View file

@ -21,10 +21,22 @@ defmodule Ash.Error.Query.NotFound do
def stacktrace(_), do: nil
defp id_string(map) do
Enum.map_join(map, " | ", fn {key, value} ->
"#{key}: #{inspect(value)}"
end)
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