Miss understanding to use policy in read action, Handling Missing Actor
Hi sorry again, I've read the documentation multiple times but still struggle to properly handle a case in my
:me
:me
action.
Here’s my current setup:
read :me do description "Get the current authenticated user" get? true filter expr(id == ^actor(:id)) prepare fn query, _context -> query |> Ash.Query.load([:permissions, :permission_values, :site]) endendbypass action(:me) do authorize_if expr(id == ^actor(:id))end
read :me do description "Get the current authenticated user" get? true filter expr(id == ^actor(:id)) prepare fn query, _context -> query |> Ash.Query.load([:permissions, :permission_values, :site]) endendbypass action(:me) do authorize_if expr(id == ^actor(:id))end
This works when a valid token (and therefore actor) is present. However, when I make a JSON API request without a token, I receive a generic 400 error like:
I want it to return a 403 Forbidden instead. So I tried this policy:
policy action(:me) do access_type :strict forbid_unless actor_present() authorize_if always()end
policy action(:me) do access_type :strict forbid_unless actor_present() authorize_if always()end
Now, when there’s no token, it correctly returns 403 Forbidden.
But unfortunately, when there is a token, I get a 404 Not Found instead:
{ "errors": [ { "code": "not_found", "status": "404", "title": "Entity Not Found", "detail": "No user record found with ``" } ]}
{ "errors": [ { "code": "not_found", "status": "404", "title": "Entity Not Found", "detail": "No user record found with ``" } ]}
Even when I adjusted the code further, I still get 404. How can I ensure:
* 403 Forbidden is returned when no token is provided * 200 OK(with user info) is returned when a valid token exists instead of getting a 404?
By the way, my user is using
multitenancy global? true
multitenancy global? true
I think i miss a part Thank you in advance
Solution
Oh i changed my order of policies it shows :thinkies:
this was the last line of policies and i move
bypass always() do authorize_if {MishkaCms.Accounts.Checks.AccessPermissions, permissions: ["admin:dashboard:*", "admin:api:*", "*"]} end
bypass always() do authorize_if {MishkaCms.Accounts.Checks.AccessPermissions, permissions: ["admin:dashboard:*", "admin:api:*", "*"]} end
and i move top of
policy action(:me) do access_type :strict forbid_unless actor_present() authorize_if always() end
policy action(:me) do access_type :strict forbid_unless actor_present() authorize_if always() end
And for preventing warning of no actor
read :me do description "Get the current authenticated user" get? true # filter expr(id == ^actor(:id)) prepare fn query, context -> if context.actor do query |> Ash.Query.filter(id == ^context.actor.id) |> Ash.Query.load([:permissions, :permission_values, :site]) else query |> Ash.Query.filter(expr(false)) end end end
read :me do description "Get the current authenticated user" get? true # filter expr(id == ^actor(:id)) prepare fn query, context -> if context.actor do query |> Ash.Query.filter(id == ^context.actor.id) |> Ash.Query.load([:permissions, :permission_values, :site]) else query |> Ash.Query.filter(expr(false)) end end end
The Elixir backend framework for unparalleled productivity. Declarative tools that let you stop wasting time. Use with Phoenix LiveView or build APIs in minutes for your front-end of choice.