sezaru

sezaru

Proposal: Allow creation of policy check groups

Consider a resource that has a bunch of actions in it and I’m creating policies for them.

Some actions have some policies checks that are common between them and some are not.

Right now, I would write the policies something like this:

policies do
  policy action([:a, :b, :c, ...]) do
    # all actions common checks
  end

  policy action :a do
    # specific a checks
  end

  policy action :b do
    # specific b checks
  end

  policy action [:a, :b] do
    # common checks between :a and :b
  end

  ...
end

The issue that I see with this is that as I keep adding more and more policies, it gets harder and harder to read them since I need to find all places some action can match a policy to get the full picture of what policies an action has (and from my experience, that incentivizes the developers to ignore the policies or write wrong/incomplete ones).

A way that I though to mitigate this it to have a explicit policy block per action, that way I just need to check that action policy block and I get the full picture of what its policies checks are.

The obvious problem with this approach is that now I have a bunch of code duplication:

policies do
  policy action(:a) do
    # common checks
    # common checks between :a and :b
    # specific :a checks
  end

  policy action(:b) do
    # common checks
    # common checks between :a and :b
    # specific :b checks
  end

  policy action(:c) do
    ...
  end 

  ...
end

So, the proposal is a way to help this scenario by allowing the creation of check groups, basically a check group contains a list of checks the same way a policy code block has and a name, then, that check block can be referenced inside any policy block and their checks would be applied to that policy block.

It would work kinda similar to phoenix route pipelines.

So, the above solution with check groups would be something like this:

policies do
  check_group :common do
    # check 1
    # check 2
    ...
  end

  check_group :common_a_and_b do
    # check 1
    # check 2
    ...
  end

  policy action(:a) do
    check_group :common
    check_group :common_a_and_b
    # specific :a checks
  end

  policy action(:b) do
    check_group :common
    check_group :common_a_and_b
    # specific :a checks
  end

  policy action(:c) do
    ...
  end 

  ...

Of course, if I just have 2~3 actions, then this is more verbose and probably will use more lines, but the idea is that this would help with bigger resources that have a bunch of actions (5~20).

Do you think something like this would be feasible @zachdaniel ?

First Post!

zachdaniel

zachdaniel

Creator of Ash

:a: thinking: its an interesting proposal. One thing that can be complex is the way that these compose. For example:

policy action(:a) do
  check_group :common
  authorize_if :a
  authorize_if :b
end

and

policy action(:a) do
  authorize_if :a
  check_group :common
  authorize_if :b
end

compose differently, its not a simple as a && common && b, and modeling the workflow this way could be pretty confusing.

With that said, you can actually experiment with this pretty easily using macros.

defmacrop common_a_and_b() do
  quote do
     ...your checks
  end
end

...


policy action(:a) do
  common_a_and_b()
end

Where Next?

Popular in Discussions Top

matthias_toepp
I’d love to hear what people think about Wisp, the new Gleam web framework started by Gleam’s primary creator Louis Pilfold. Gleam, alon...
New
cvkmohan
The upcoming Phoenix 1.6 release looks very interesting. Became a habit to watch the commits - and - what they are bringing in. phx.gen...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
shishini
I think this twitter post and youtube video didn’t get as much attention as I hoped I am still new to Elixir, so can’t really judge ...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
chulkilee
Here are the list of HTTP client libraries/wrappers, and some thoughts on HTTP client in general. I’d like to hear from others how they w...
New
griffinbyatt
Sobelow Sobelow is a security-focused static analysis tool for the Phoenix framework. For security researchers, it is a useful tool for g...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
paulanthonywilson
I like Umbrella projects and pretty much always use them for personal Elixir stuff, especially Nerves things. But I don’t think this is ...
New
slashdotdash
Phoenix Live View is now publicly available on GitHub. Here’s Chris McCord’s tweet announcing making it public.
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
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
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
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
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
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement