Guy14

Guy14

What is the best way to set an authorization for the primary `:read` action when creating a linked Resource?

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 :list function in User resource, and I expose this function instead of :read in the API, so I put restricting policies on :list and 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 :read function by mistake
    OR
  • create an intermediary function before the :add_user_emotion that will set an actor like actor: %{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 :slightly_smiling_face: ).

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

Marked As Solved

zachdaniel

zachdaniel

Creator of Ash

You can pass an authorize?: false option to manage_relationship if you want the parent action’s authorization rules to be the arbiter in this context. That might have helped with your original design.

Also Liked

sevenseacat

sevenseacat

Author of Ash Framework

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!

FlyingNoodle

FlyingNoodle

My feeling says use relate_actor and then if you need an admin to set any user you do something like:

create :add_user_emotion_admin do
  argument :emotion, :uuid, allow_nil?: false
  argument :user, :uuid, allow_nil?: false
  change manage_relationship(:emotion, type: :append)
  change manage_relationship(:user, type: :append)
end

policies
  action(:add_user_emotion_admin) do
    authorize_if actor_attribute_equals(:admin, true)
  end
end

Where Next?

Popular in Questions Top

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New

Other popular topics Top

johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement