View Source Membership (ex_membership v1.0.3)

Main Membership module for including macros

Membership has 4 main components:

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

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

Link to this function

add_function_param_to_block(block)

View Source
Link to this macro

as_authorized(member, func_name, list)

View Source (macro)

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
Link to this function

authorized?(member, func_name)

View Source

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
Link to this macro

calculated(current_member, func_name)

View Source (macro)

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
Link to this macro

calculated(current_member, callback, func_name)

View Source (macro)
Link to this macro

calculated(current_member, callback, bindings, func_name)

View Source (macro)

List membership and related modules.

Examples

iex> Membership.get_loaded_modules()
Link to this function

has_feature(feature, func_name)

View Source
@spec has_feature(atom(), atom()) :: {:ok, atom()}

Requires a feature within permissions block

Example

defmodule HelloTest do
  use Membership

  def test_authorization do
    permissions do
      has_feature(:admin)
    end
  end
end
Link to this function

has_feature?(member, feature_name)

View Source

Perform feature check on passed member and feature

Link to this function

has_feature?(member, func_name, feature_name)

View Source
Link to this function

has_plan(plan, func_name)

View Source
@spec has_plan(atom(), atom()) :: {:ok, atom()}

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
Link to this function

has_plan?(member, func_name, plan_name)

View Source
@spec has_plan?(Membership.Member.t(), atom(), String.t()) :: boolean()

Perform authorization on passed member and plans

Link to this function

has_role(role, func_name)

View Source
@spec has_role(atom(), atom()) :: {:ok, atom()}

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
Link to this function

has_role?(member, role_name)

View Source

Perform authorization on passed member and roles

Link to this function

has_role?(member, func_name, role_name)

View Source
@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

Link to this function

load_ets_data(current_module \\ __MODULE__)

View Source

Load the plans into ets for the module/functions

Link to this macro

permissions(list)

View Source (macro)

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
Link to this macro

permissions(member, list)

View Source (macro)

List version.

Examples

iex> Membership.version()