Closed ulbrich closed 7 months ago
Here’s the API definition including the authorization (and the requests work if I set authorize?
to false
):
defmodule Ticker.Api do
use Ash.Api,
extensions: [
AshGraphql.Api,
AshJsonApi.Api
]
graphql do
authorize?(true)
end
json_api do
authorize?(true)
router(TickerWeb.Api.Router)
end
resources do
registry(Ticker.Api.Registry)
end
end
Here are the routes:
json_api do
type("user")
routes do
base("/users")
index(:read_filtered)
get(:read_by_extid) do
route("/:extid")
end
post(:upsert_user) do
route("/")
end
end
end
Maybe worth mentioning: The problem remains even when allowing very permissive access.
policies do
policy always() do
authorize_if always()
end
end
This appears to be something failing in our new field policy authorization code. I think this should be a relatively straightforward fix.
Hello Zach, at least the exception goes away in the JSAN-API as well as in the GraphQL implementation if I add this:
field_policies do
field_policy :* do
authorize_if always()
end
end
That doesn’t fix some other same looking models, though. I added the same field policy and checked all other conditions but while the User
model works now, others still fail. Yes, I forced a rebuild of everything.
Hey @ulbrich would you mind trying main
? I believe I've fixed this by handling empty field policy lists better.
Hi @zachdaniel, thanks for the fast reply: For the original User
model that works now (with our without the field_policy
above). For my Event
model, I now get a different exception if (and only if) I add that field_policy
and it works fine without:
[info] GET /api/eventhub/events/618
[debug] Processing with TickerWeb.Api.Router
Parameters: %{}
Pipelines: [:api]
[info] Sent 500 in 181ms
[error] #PID<0.2213.0> running TickerWeb.Endpoint (connection #PID<0.2141.0>, stream id 8) terminated
Server: localhost:4000 (http)
Request: GET /api/eventhub/events/618
** (exit) an exception was raised:
** (ArgumentError) comparison with nil is forbidden as it is unsafe. If you want to check if a value is nil, use is_nil/1 instead
(ecto 3.10.3) lib/ecto/query/builder.ex:1048: Ecto.Query.Builder.not_nil!/1
(ash_postgres 1.3.41) lib/expr.ex:612: anonymous fn/3 in AshPostgres.Expr.do_dynamic_expr/5
(ecto 3.10.3) lib/ecto/query/builder/dynamic.ex:76: Ecto.Query.Builder.Dynamic.expand/3
(ecto 3.10.3) lib/ecto/query/builder/dynamic.ex:46: Ecto.Query.Builder.Dynamic.fully_expand/2
(ecto 3.10.3) lib/ecto/query/builder/filter.ex:133: Ecto.Query.Builder.Filter.filter!/7
(elixir 1.15.3) lib/enum.ex:2510: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash_postgres 1.3.41) lib/data_layer.ex:2175: AshPostgres.DataLayer.filter/4
(ash 2.14.0) lib/ash/actions/read.ex:1365: anonymous fn/4 in Ash.Actions.Read.data_field/3
(ash 2.14.0) lib/ash/engine/engine.ex:537: anonymous fn/2 in Ash.Engine.run_iteration/1
(ash 2.14.0) lib/ash/engine/engine.ex:558: anonymous fn/4 in Ash.Engine.async/2
(elixir 1.15.3) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
(elixir 1.15.3) lib/task/supervised.ex:36: Task.Supervised.reply/4
(ash 2.14.0) lib/ash/engine/engine.ex:552: Ash.Engine.async/2
(elixir 1.15.3) lib/enum.ex:1693: Enum."-map/2-lists^map/1-1-"/2
(ash 2.14.0) lib/ash/engine/engine.ex:702: Ash.Engine.start_pending_tasks/1
(ash 2.14.0) lib/ash/engine/engine.ex:323: Ash.Engine.run_to_completion/1
(ash 2.14.0) lib/ash/engine/engine.ex:252: Ash.Engine.do_run/2
(ash 2.14.0) lib/ash/engine/engine.ex:148: Ash.Engine.run/2
(ash 2.14.0) lib/ash/actions/read.ex:173: Ash.Actions.Read.do_run/3
(ash 2.14.0) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
🤔 It seems strange that you'd be getting that error only for one resource and not the other. Is there anything special about that resource? Any special extensions its using?
With the User
model, I do not have a lookup by id
, but a custom one by extid
(also not a UUID, but a unique string). The same is for the Alarm
model. All other models have a classic integer id
as lookup and only these models run into that exception. But again: If I leave out the field_properties
block, it works fine.
Actions for these models:
actions do
read :read do
primary?(true)
end
end
Example JSON-API for these models:
json_api do
type("event")
routes do
base("/events")
index(:read_filtered)
get(:read) do
route("/:id")
end
end
end
I must have dropped the ball on this. Are you still experiencing this issue?
Looks good now. I guess, you can close the ticket.
Hi, I’m not sure whether this really is a bug, but for two JSON-API read-requests I get different resolution of the policies — one
index
and oneget
, but both share the same policy. I debugged along the stack trace (see below and can’t find the reason, why the policies of the same actor stay empty in the one and are populated with what I would expect in the other case.Both share this policy:
This one runs into an exception:
While this one works (deliberatly halted with an exception in
match?
to get the stack trace):Versions are most recent as of this writing (and both queries run nicely in production with older versions of the framework):