permission_ex v0.6.0 PermissionEx View Source
Main module and interface to testing permissions.
If you wish to test a single permission for equality, then you would use
PermissionEx.test_permission/2
.
If you wish to test an entire permission struct for matching allowed
permissions then you would use PermissionEx.test_permissions/2
.
If you wish to test an entire permission struct for matching allowed
permissions on a struct tagged map then you would use
PermissionEx.test_tagged_permissions/2
.
The examples in this module use these definitions of structs for testing permissions:
defmodule PermissionEx.Test.Structs.User do
@moduledoc false
@derive [Poison.Encoder]
defstruct name: nil
end
defmodule PermissionEx.Test.Structs.Page do
@moduledoc false
@derive [Poison.Encoder]
defstruct action: nil
end
defmodule PermissionEx.Test.Structs.PageReq do
@moduledoc false
@derive [Poison.Encoder]
defstruct action: nil
end
defmodule PermissionEx.Test.Structs.PagePerm do
@moduledoc false
@derive [Poison.Encoder]
defstruct action: nil
end
Link to this section Summary
Types
A Permission matcher is either anything, of which it must then match the
required permission precisely, or it is a list starting with :any
such as
[:any | permissions]
where each item in the list will be tested against
the requirement as a base permission, if any are true then this matches.
This is a set of permissions such as %{}, [%{}], etc...
This is a map that has a mapping of a %{Struct => %Struct{}}.
Functions
This tests a specific required permission against a specific permission.
This tests a specific requirement against a set of permission.
This takes a map
of permissions with the keys being a tag to be looked up
on. The required permission struct type is the tag to match on.
Link to this section Types
permission()
View Source
permission() :: [:any | permission()] | any()
permission() :: [:any | permission()] | any()
A Permission matcher is either anything, of which it must then match the
required permission precisely, or it is a list starting with :any
such as
[:any | permissions]
where each item in the list will be tested against
the requirement as a base permission, if any are true then this matches.
permissions()
View Source
permissions() ::
:_
| boolean()
| nil
| [permissions()]
| %{required(any()) => permission()}
| struct()
permissions() :: :_ | boolean() | nil | [permissions()] | %{required(any()) => permission()} | struct()
This is a set of permissions such as %{}, [%{}], etc...
A :_
or true
matches any entire requirement set.
A false
or nil
will always not match.
A list of permissions
will each be checked individually against the
requirement, if any are a true match then it returns true.
A struct or map will be tested against the requirements directly, a struct is
treated like a map except the :__struct__
field will not be tested, useful
if you want a requirement and permission to use different structs. Do note
that the tagged_permissions
keys should match the :__struct__
of the
requirement struct, not of the permission struct. I.E. given a
PermissionEx.Test.Structs.PageReq
and a
PermissionEx.Test.Structs.PagePerm
, such as if you want the default values
for the requirement stuct to be by default tight or lenient, and the opposite
for the permission struct, then calling PermissionEx.test_permissions/2
will
be like:
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{PermissionEx.Test.Structs.PageReq => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{PermissionEx.Test.Structs.PagePerm => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
false
tagged_permissions()
View Source
tagged_permissions() ::
struct()
| %{:admin => tagged_permissions(), required(atom()) => permissions()}
| %{required(atom()) => permissions()}
tagged_permissions() :: struct() | %{:admin => tagged_permissions(), required(atom()) => permissions()} | %{required(atom()) => permissions()}
This is a map that has a mapping of a %{Struct => %Struct{}}.
The value being an actual struct is optional, it can also be a map on its own,
as long as it has matching keys => values of the struct, any missing will have
the requirement be false unless the requirement is :_
.
If there is an :admin
key in the permissions, then this is checked first and
can act as an easy override for the main permission set.
Link to this section Functions
test_permission(required, permission)
View Source
test_permission(any(), permission()) :: boolean()
test_permission(any(), permission()) :: boolean()
This tests a specific required permission against a specific permission.
- If either are
:_
then it is true. - If both are identical, then it is true.
- If the permission is the list starting with
:any
such as[:any | <permissions>]
then each permission in the list is tested against the requirement - The permission "" is equivilent to `:`
Examples
iex> PermissionEx.test_permission(:_, :_)
true
iex> PermissionEx.test_permission(:_, "_")
true
iex> PermissionEx.test_permission("_", :_)
true
iex> PermissionEx.test_permission("_", "_")
true
iex> PermissionEx.test_permission(:_, nil)
true
iex> PermissionEx.test_permission(nil, :_)
true
iex> PermissionEx.test_permission("_", nil)
true
iex> PermissionEx.test_permission(nil, "_")
true
iex> PermissionEx.test_permission(nil, nil)
true
iex> PermissionEx.test_permission(nil, :notnil)
false
iex> PermissionEx.test_permission(:notnil, nil)
false
iex> PermissionEx.test_permission(1, 1)
true
iex> PermissionEx.test_permission(1, 1.0)
false
iex> PermissionEx.test_permission('test', 'test')
true
iex> PermissionEx.test_permission("test", "test")
true
iex> PermissionEx.test_permission('test', "test")
false
iex> PermissionEx.test_permission(:show, :show)
true
iex> PermissionEx.test_permission(:show, :edit)
false
iex> PermissionEx.test_permission(:show, [:any])
false
iex> PermissionEx.test_permission(:show, [:any, :show])
true
iex> PermissionEx.test_permission(:show, [:any, :show, :edit])
true
iex> PermissionEx.test_permission(:show, [:any, :edit, :show])
true
iex> PermissionEx.test_permission(:show, [:any, :edit, :otherwise])
false
iex> PermissionEx.test_permission(:show, ["any"])
false
iex> PermissionEx.test_permission(:show, ["any", :show])
true
iex> PermissionEx.test_permission(:show, ["any", :show, :edit])
true
iex> PermissionEx.test_permission(:show, ["any", :edit, :show])
true
iex> PermissionEx.test_permission(:show, ["any", :edit, :otherwise])
false
iex> PermissionEx.test_permission(:show, ["any", "edit", "show"])
true
iex> PermissionEx.test_permission(:show, ["any", "edit", "otherwise"])
false
iex> PermissionEx.test_permission(:show, [:many])
false
iex> PermissionEx.test_permission(:show, [:many, :show, :edit])
true
iex> PermissionEx.test_permission([:show, :edit], [:many, :show, :edit])
true
iex> PermissionEx.test_permission([:edit, :show], [:many, :show, :edit])
true
iex> PermissionEx.test_permission(:show, "show")
true
iex> PermissionEx.test_permission(:show, "_")
true
iex> PermissionEx.test_permission(nil, "_")
true
iex> PermissionEx.test_permission([:show, 123], ["show", 123])
true
iex> PermissionEx.test_permission(%{}, %{})
true
iex> PermissionEx.test_permission(%{action: :show}, %{action: "show"})
true
iex> PermissionEx.test_permission(%{action: "show"}, %{action: "show"})
true
iex> PermissionEx.test_permission(%{action: :show}, %{"action" => :show})
true
iex> PermissionEx.test_permission(%{"action" => :show}, %{action: :show})
true
iex> PermissionEx.test_permission(%{action: :show}, %{action: [:any, :show, :index]})
true
iex> PermissionEx.test_permission(%{action: :none}, %{action: [:any, :show, :index]})
false
test_permissions(required, permissions)
View Source
test_permissions(struct(), permissions()) :: boolean()
test_permissions(struct(), permissions()) :: boolean()
This tests a specific requirement against a set of permission.
See PermissionEx.test_permission/2
for possible permission formats.
Examples
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, :_)
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, true)
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, false)
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, nil)
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{action: :edit})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{action: :show})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{action: :_})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{action: true})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{action: [:any, :edit, :show]})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{action: :edit})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{action: :show})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{action: :_})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{action: true})
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %PermissionEx.Test.Structs.Page{action: [:any, :edit, :show]})
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [:_])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [true])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [false])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [nil])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [[]])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{action: :edit}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{action: :show}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{action: :_}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{action: true}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{action: [:any, :edit, :show]}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{action: :edit}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{action: :show}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{action: :_}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{action: true}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%PermissionEx.Test.Structs.Page{action: [:any, :edit, :show]}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{"action" => :edit}])
false
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{"action" => :show}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{"action" => :_}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: :show}, [%{"action" => "_"}])
true
iex> PermissionEx.test_permissions(%PermissionEx.Test.Structs.Page{action: [:something, 123]}, [%{"action" => ["something", 123]}])
true
test_tagged_permissions(required, tagged_perm_map)
View Source
test_tagged_permissions(struct(), tagged_permissions()) :: boolean()
test_tagged_permissions(struct(), tagged_permissions()) :: boolean()
This takes a map
of permissions with the keys being a tag to be looked up
on. The required permission struct type is the tag to match on.
In the key of :admin
, if true
, will always return true no matter what the
required matcher wants, it is an override that allows all permissions.
If the key of :admin
contains a map, then the tag will be looked up in it
and tested against, such as if true
then they will get permission for that
tag regardless.
If a given tag has the boolean of 'true' then it will always return true, basically giving admin just for that specific tag.
See PermissionEx.test_permissions/2
for how a permission struct/map is matched.
See PermissionEx.test_permission/2
for possible permission formats.
Examples
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{}, %{admin: true})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{}, %{admin: %{PermissionEx.Test.Structs.Page => true}})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.User{}, %{admin: %{PermissionEx.Test.Structs.Page => true}})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{admin: %{PermissionEx.Test.Structs.Page => %{action: :show}}})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :edit}, %{admin: %{PermissionEx.Test.Structs.Page => %{action: :show}}})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => true})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => %{}})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => %{}})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => %PermissionEx.Test.Structs.Page{action: :show}})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => %PermissionEx.Test.Structs.Page{action: :_}})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => %PermissionEx.Test.Structs.Page{action: nil}})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => [%PermissionEx.Test.Structs.Page{action: :show}]})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => [%PermissionEx.Test.Structs.Page{action: :_}]})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.Page{action: :show}, %{PermissionEx.Test.Structs.Page => [%PermissionEx.Test.Structs.Page{action: nil}]})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{PermissionEx.Test.Structs.PageReq => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{PermissionEx.Test.Structs.PagePerm => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
false
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{"Elixir.PermissionEx.Test.Structs.PageReq" => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
true
iex> PermissionEx.test_tagged_permissions(%PermissionEx.Test.Structs.PageReq{action: :show}, %{"Elixir.PermissionEx.Test.Structs.PagePerm" => [%PermissionEx.Test.Structs.PagePerm{action: :_}]})
false