{@thread.name}
Jan Ulbrich:
Hi there, đ
I have a query like
{
alarm(filter: {id: { eq: 4711}}) {
message
events(sort: {field: ID, order: DESC}) {
id
message
}
}
}
which I need to filter with a
Ash.Query.after_action
.
The filter is called as expected, but the actor of the request (available in the outer filter with the correct value) is
nil
for this nested.
Do I manually need to forward the context in some way or might that be a bug?
This is the stack trace raising an exception from
Ash.Query.after_action
(no error, but manually raised to get the stack):
(ash_graphql 0.25.5) lib/graphql/resolver.ex:1806: AshGraphql.Graphql.Resolver.to_resolution/3
(absinthe 1.7.1) lib/absinthe/middleware/dataloader.ex:37: Absinthe.Middleware.Dataloader.get_result/2
(absinthe 1.7.1) lib/absinthe/phase/document/execution/resolution.ex:232: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
(absinthe 1.7.1) lib/absinthe/phase/document/execution/resolution.ex:187: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/3
...
(phoenix 1.6.16) lib/phoenix/router/route.ex:41: Phoenix.Router.Route.call/2
(phoenix 1.6.16) lib/phoenix/router.ex:354: Phoenix.Router.__call__/2
Jan Ulbrich:
These are the Ash-related dependencies Iâm using:
{:ash, "~> 2.9.19"},
{:ash_authentication, "~> 3.11.3"},
{:ash_graphql, "~> 0.25.5"},
{:ash_json_api, git: "https://github.com/ash-project/ash_json_api.git", build: "main"},
{:ash_postgres, "~> 1.3.28"},
zachdaniel:
Can I see what your after action hook looks like?
Jan Ulbrich:
Sorry, I missed your question earlier! Here you go:
actions do
read :read do
primary?(true)
prepare(fn query, context ->
IO.inspect(context, label: "Context") # <- actor nil
Ash.Query.after_action(query, fn _query, events ->
{:ok, patch_results_applying_actor_filters(events, context)}
end)
end)
end
In that function:
def patch_results_applying_actor_filters(events, context) do
with actor when actor != nil <- Map.get(context, :actor) do
...
end
end
zachdaniel:
can you add a change to the root resource and see if the actor is being passed at all?
zachdaniel:
I donât see a reason why the actor wouldnât be available in that context you showed
Jan Ulbrich:
Yes, Iâll add the same debug statement. Gimme a minute.
Jan Ulbrich:
Itâs weird: The inner query is kind of executed first
[info] POST /graphql
[debug] Processing with Absinthe.Plug
Parameters: %{"query" => "{\n alarm(filter: { id: {eq: 4711}}) {\n originatedAt\n extid\n longitude\n latitude\n day\n month\n year\n payload\n kind\n subkind\n events(sort: {field: ORIGINATED_AT}) {\n originatedAt\n payload\n }\n }\n}", "variables" => nil}
Pipelines: [:graphql]
[debug] ABSINTHE schema=TickerWeb.Schema variables=%{}
---
{
alarm(filter: { id: {eq: 4711}}) {
originatedAt
extid
longitude
latitude
day
month
year
payload
kind
subkind
events(sort: {field: ORIGINATED_AT}) {
originatedAt
payload
}
}
}
---
[debug] QUERY OK source="alarms" db=9.9ms queue=0.1ms idle=1777.5ms
SELECT a0."id", a0."created_at", a0."updated_at", a0."year", a0."month", a0."day", a0."originated_at", a0."message", a0."extid", a0."operations_center", a0."kind", a0."subkind", a0."longitude", a0."latitude", a0."payload" FROM "alarms" AS a0 WHERE (a0."id" = $1) [4711]
Inner context: %{tracer: nil, actor: nil, authorize?: nil}
Outer context: %{
tracer: nil,
actor: %{
id: "bwb-102290",
[...]
},
authorize?: true
}
[debug] QUERY OK source="alarms" db=3.7ms idle=1788.8ms
SELECT a0."created_at", a0."updated_at", a0."message", a0."operations_center", a0."id" FROM "alarms" AS a0 WHERE (a0."id"::bigint = $1::bigint) [4711]
[debug] QUERY OK source="events" db=201.7ms idle=1793.6ms
SELECT e0."id", e0."originated_at", e0."extid", e0."payload" FROM "events" AS e0 WHERE (e0."id"::bigint = $1::bigint) ORDER BY e0."originated_at" [4711]
Jan Ulbrich:
I thought, that I may have added some query as a precondition, but thatâs not the case: If I remove the relation in the query, thereâs no query to the events table at all.
[debug] Processing with Absinthe.Plug
Parameters: %{"query" => "{\n alarm(filter: { id: {eq: 4711}}) {\n originatedAt\n extid\n longitude\n latitude\n day\n month\n year\n payload\n kind\n subkind\n }\n}", "variables" => nil}
Pipelines: [:graphql]
[debug] ABSINTHE schema=TickerWeb.Schema variables=%{}
---
{
alarm(filter: { id: {eq: 4711}}) {
originatedAt
extid
longitude
latitude
day
month
year
payload
kind
subkind
}
}
---
[debug] QUERY OK source="alarms" db=9.0ms idle=117.1ms
SELECT a0."id", a0."created_at", a0."updated_at", a0."year", a0."month", a0."day", a0."originated_at", a0."message", a0."extid", a0."operations_center", a0."kind", a0."subkind", a0."longitude", a0."latitude", a0."payload" FROM "alarms" AS a0 WHERE (a0."id" = $1) [4811]
zachdaniel:
it has to do with the after action hooks
zachdaniel:
i.e the inner queryâs âafter actionâ happens before the outer queryâs âafter actionâ
zachdaniel:
and youâre on the latest ash_graphql?
zachdaniel:
I figured it out
Jan Ulbrich:
Yes, itâs 0.25.5 and installed as that version and not directly from master.
zachdaniel:
releasing a fix now. I was a bit worried as this sounded like something that could affect authorization
zachdaniel:
like the builtin policy authorization
zachdaniel:
but its not really, only if you have query preparations that reference the actor on read
zachdaniel:
I guess in some designs it could have been a security issue
zachdaniel:
but not for people using the policy authorizer at least
zachdaniel:
basically the case is when ash_graphql loaded related things, query preparations would get
actor: nil
zachdaniel:
but its highly unlikely that that would cause things to be less secure
zachdaniel:
more like more secure
zachdaniel:
(well, accidentally secure, preventing users who should be able to do things from doing them)
Jan Ulbrich:
Which is at least conservative and wouldnât compromise date.
zachdaniel:
Yeah
zachdaniel:
anyway
0.25.6
is out w/ the fix đ
Jan Ulbrich:
Wow, youâre wild! đ
Jan Ulbrich:
Yes, that works: I can confirm that I now get the same context and my filters show the right data. Pew⌠đ As always: Thanks again for your fast help! đ
zachdaniel:
My pleasure đ