Ooo, I like the style, kind of a more refined version of what I’m doing now. I currently use my PermissionEx library to do the actual permission testing, and the canada library to test specific things, mine works like this:
First I define a behaviour I want, lets start with:
defmodule MyServer.PermsBehaviour do
@callback get_as_new() :: %{}
end
Where get_as_new/0
just returns what is a good default structure for assigning this permission to someone.
I then define some permissions, say this for a simple example:
defmodule MyServer.Perms.Auth.Profile do
@behaviour MyServer.PermsBehaviour
defstruct action: nil, uid: :_
def get_as_new(), do: %MyServer.Perms.Auth.Profile{action: "", uid: :_}
end
I can get all of my permission types in the entire program (say for populating a drop-down list in the admin section to assign someone permission and values and such) like this by using my PluginsEx library (I should probably release it someday, it is so useful, but such a huge hack…):
all_perms = PluginsEx.get_plugins(MyServer.PermsBehaviour)
Where all_perms
is now a list of atoms, given the above permission it would just be [MyServer.Perms.Auth.Profile]
.
To use the permission via canada, an example:
alias MyServer.Perms
@perm true = conn |> can?(index(%Perms.Auth.Profile{uid: uid}))
And I can refine it over time, so for example I can do this:
@perm true = conn |> can?(index(%Perms.Auth.Profile{uid: :_}))
uid = get_uid_from_params(params)
@perm true = conn |> can?(index(%Perms.Auth.Profile{uid: uid}))
Or something like that, say if getting the uid is a costly db lookup and you don’t want to do it if they do not have access to any uid at all first. My PermissionEx library looks like it would work well with authorize, basically it would replace canary (which only returns true/false) with a better return structure and information (like a message). Looks useful.