Guy14
Hello!!
I have a UserEmotion Resource (it’s a join between User resource and Emotion resource).
In my User resource, I allow only users with role == :admin to access the :read action:
policy action(:read) do
authorize_if actor_attribute_equals(:role, :admin)
end
The UserEmotion exposes a create function named add_user_emotion which is quite basic:
create :add_user_emotion do
description "Adds a new entry to user_emotions."
argument :user, :uuid do
allow_nil? false
end
argument :emotion, :uuid do
allow_nil? false
end
change manage_relationship(:user, type: :append)
change manage_relationship(:emotion, type: :append)
end
I want this function to be available for all Users, including those who are not :admin (maybe I’ll populate the :user myself from the actor to ensure a User only adds Emotions for itself).
To fix the permission issue, I could:
- create a
:listfunction inUserresource, and I expose this function instead of:readin the API, so I put restricting policies on:listand I open all permissions on:read→ it doesn’t feel the right way to me, since there’s a breach if I later expose the:readfunction by mistake
OR - create an intermediary function before the
:add_user_emotionthat will set an actor likeactor: %{internal: true}, and then authorize this internal new actor in the policy like so:
policy action(:read) do
authorize_if actor_attribute_equals(:role, :admin)
authorize_if actor_attribute_equals(:internal, :true) // NEW ACTOR
end
None of my solutions seems good to me. Do you have any advice on this case? I guess it’s a common challenge, but I haven’t found a solution while checking at the docs (but I found many responses to other questions I had
).
P.S. I’ve also tried the accessing_from builtin policy, but It doesn’t work since my UserEmotion Resource is not yet created but on the path to be created…
policy action(:read) do
authorize_if actor_attribute_equals(:role, :admin)
authorize_if accessing_from(UserEmotion, :emotions)
end
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Guy14
I found a better way to do what I want: it looks like this
This way I don’t need to retrieve the
Userfrom a givenuuid, and it logically allows only the current actor to manage its ownEmotions.I’m still curious if there is a way to allow the current action (once it’s authorized) to call other internal actions that would not directly be authorized for the initial
actor.Maybe it would be a bad design since it would be a way to retrieve data that is not supposed to be callable by the inital
actor?But so is there a trick to keep a way of retrieving
Userfor instance from theiruuidto link them to a Resource under creation? (my first “solution” works, after all… but I’m not sure of it’s legitimacy)zachdaniel
You can pass an
authorize?: falseoption tomanage_relationshipif you want the parent action’s authorization rules to be the arbiter in this context. That might have helped with your original design.Guy14
Oh yeah, that’s great, I’ll keep this one close
Thanks a lot!
sevenseacat
In this case you might also want an authorization rule for users, to let them read their own records. ie.
authorize_if expr(id == ^actor(:id))I think you still need to be able to read the user record, to use
relate_actor!Guy14
Thanks a lot for the precision @sevenseacat !!
To give you my feedback: the
relate_actorworks, even if the actor has no rights on the primaryUser’s:readfunction.I guess it’s because the actor is already a
UserResource in the context, rather than being only anuuid, and that Ash needs to retrieve the Resource to link thoUserResource to theUserEmotion.FlyingNoodle
My feeling says use
relate_actorand then if you need an admin to set any user you do something like:sevenseacat
Gotcha. I just did some experimenting, and it seems it will work on
createactions, and atomicupdateactions (it’ll fetch the attribute from the User resource) - but for non-atomicupdateactions, it won’tGuy14
Yeah, seems like a safe and practical way to do what I want
@sevenseacat Thanks for this new feedback! So it feels safer to add the policy you gave me:
authorize_if expr(id == ^actor(:id))on theUser’s:readaction.