View Source Membership (ex_membership v1.0.3)
Main Membership module for including macros
Membership has 4 main components:
Membership.Role
- Representation of a single role e.g. :admin, :luser, :userMembership.Plan
- Representation of a single plan e.g. :gold, :silver, :copperMembership.Member
- Main actor which is holding given plansMembership.Feature
- Feature of a plan eg. :edit_feature
Relations between models
Membership.Member
-> Membership.Feature
[1-n] - Any given member have multiple features with this we can have more granular features for each member is adding a specific feature to a member not in his plan
Membership.Member
-> Membership.Plan
[1-n] - Any given member can have multiple plans
Membership.Member
-> Membership.Role
[1-n] - Any given member can have multiple roles
Membership.Plan
-> Membership.Feature
[m-n] - Any given plan can have multiple features
Membership.Role
-> Membership.Feature
[m-n] - Any given role can have multiple features
Calculating permissions
Calculation of permissions is done by 2 ets tables one holding the logged in members permissions the other holds modules function/permissions, then true = Enum.member?(module_permissions, member_permissions)
Available as_authorized
Membership.has_plan?/3
- Requires single plan to be present on memberMembership.has_role?/3
- Requires single role to be present on memberMembership.has_feature?/3
- Requires single feature to be present on member
Summary
Functions
Macro for wrapping protected code
Returns authorization result on collected member and required features/plans
Defines calculated permission to be evaluated in runtime
List membership and related modules.
Requires a feature within permissions block
Perform feature check on passed member and feature
Requires an plan within permissions block
Perform authorization on passed member and plans
Requires an role within permissions block
Perform authorization on passed member and roles
Perform authorization on passed member and roles
The Function list to ignore when building the permissions registry's
Load the plans into ets for the module/functions
Macro for defining required permissions
List version.
Functions
Macro for wrapping protected code
Example
defmodule HelloTest do
use Membership
member = HelloTest.Repo.get(Membership.Member, 1)
{:ok, member } = load_and_authorize_member(member)
def test_authorization do
as_authorized(member, :test_authorization) do
IO.inspect("This code is executed only for authorized member")
end
end
end
Returns authorization result on collected member and required features/plans
Example
defmodule HelloTest do
use Membership
def test_authorization do
case authorized? do
:ok -> "Member is authorized"
{:error, message: _message} -> "Member is not authorized"
end
end
end
Defines calculated permission to be evaluated in runtime
Examples
defmodule HelloTest do
use Membership
member = HelloTest.Repo.get(Membership.Member, 1)
{:ok, member } = load_and_authorize_member(member)
def test_authorization do
permissions do
calculated(fn member ->
member.email_confirmed?
end)
end
as_authorized(member) do
IO.inspect("This code is executed only for authorized member")
end
end
end
You can also use DSL form which takes function name as argument
defmodule HelloTest do
use Membership
def test_authorization do
use Membership
member = HelloTest.Repo.get(Membership.Member, 1)
{:ok, member } = load_and_authorize_member(member)
permissions do
calculated(member,:email_confirmed, :calculated)
end
as_authorized(member) do
IO.inspect("This code is executed only for authorized member")
end
end
def email_confirmed(member) do
member.email_confirmed?
end
end
For more complex calculations you need to pass bindings to the function
defmodule HelloTest do
use Membership
member = HelloTest.Repo.get(Membership.Member, 1)
{:ok, member} = load_and_authorize_member(member)
def test_authorization do
post = %Post{owner_id: 1}
permissions do
calculated(member,:is_owner, [post])
calculated(fn member, [post] ->
post.owner_id == member.id
end)
end
as_authorized(member) do
IO.inspect("This code is executed only for authorized member")
end
end
def is_owner(member, [post]) do
post.owner_id == member.id
end
end
List membership and related modules.
Examples
iex> Membership.get_loaded_modules()
Requires a feature within permissions block
Example
defmodule HelloTest do
use Membership
def test_authorization do
permissions do
has_feature(:admin)
end
end
end
Perform feature check on passed member and feature
Requires an plan within permissions block
Example
defmodule HelloTest do
use Membership
def test_authorization do
permissions do
has_plan(:gold, :test_authorization)
end
end
end
@spec has_plan?(Membership.Member.t(), atom(), String.t()) :: boolean()
Perform authorization on passed member and plans
Requires an role within permissions block
Example
defmodule HelloTest do
use Membership
def test_authorization do
permissions do
has_role(:gold, :test_authorization)
end
end
end
Perform authorization on passed member and roles
@spec has_role?(Membership.Member.t(), atom(), String.t()) :: boolean()
@spec has_role?(Membership.Member.t(), atom(), String.t()) :: boolean()
Perform authorization on passed member and roles
The Function list to ignore when building the permissions registry's
Load the plans into ets for the module/functions
Macro for defining required permissions
Example
defmodule HelloTest do
use Membership
def test_authorization do
permissions do
has_feature(:admin_feature, :test_authorization)
has_plan(:gold, :test_authorization)
end
end
end
List version.
Examples
iex> Membership.version()