Class: Eaco::DSL::Resource::Permissions

Inherits:
Base
  • Object
show all
Defined in:
lib/eaco/dsl/resource/permissions.rb

Overview

Permission collector, based on method_missing.

Example:

1 authorize Foobar do
2   permissions do
3     reader :read_foo, :read_bar
4     editor reader, :edit_foo, :edit_bar
5     owner  editor, :destroy
6   end
7 end

Within the block, each undefined method call defines a new method that returns the given arguments.

After evaluating line 3 above:

>> reader
=> #<Set{ :read_foo, :read_bar }>

The method is used then on line 4, giving the editor role the same set of permissions granted to the reader, plus its own set of permissions:

>> editor
=> #<Set{ :read_foo, :read_bar, :edit_foo, :edit_bar }>

Instance Attribute Summary

Attributes inherited from Base

#options, #target

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#target_eval

Constructor Details

#initializePermissions

Sets up an hash with a default value of a new Set.


61
62
63
64
65
# File 'lib/eaco/dsl/resource/permissions.rb', line 61

def initialize(*)
  super

  @permissions = Hash.new {|hsh, key| hsh[key] = Set.new}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(role, *permissions) ⇒ Set (private)

Here the method name is the role code. If we already have defined permissions for the given role, those are returned.

Else, #save_permission is called to memoize the given permissions for the role.

Parameters:

  • role (Symbol)
  • permissions (Array)

    permissions to grant to the given role.

Returns:

  • (Set)

91
92
93
94
95
96
97
# File 'lib/eaco/dsl/resource/permissions.rb', line 91

def method_missing(role, *permissions)
  if @permissions.key?(role)
    @permissions[role]
  else
    save_permission(role, permissions)
  end
end

Class Method Details

.eval(&block) ⇒ Permissions

Evaluates the given block in the context of a new collector

Returns an Hash of permissions, keyed by role.

>> Permissions.eval do
 |   permissions do
 |     reader :read
 |     editor reader, :edit
 |   end
 | end

=> {
 |   reader: #<Set{ :read },
 |   editor: #<Set{ :read, :edit }
 | }

Returns:


54
55
56
# File 'lib/eaco/dsl/resource/permissions.rb', line 54

def self.eval(*, &block)
  super
end

Instance Method Details

#resultHash

Returns the collected permissions in a plain Hash, lacking the default block used by the collector's internals - to give to the outside an Hash with a predictable behaviour :-).

Returns:

  • (Hash)

74
75
76
# File 'lib/eaco/dsl/resource/permissions.rb', line 74

def result
  Hash.new.merge(@permissions)
end

#save_permission(role, permissions) ⇒ Set (private)

Memoizes the given set of permissions for the given role.

Parameters:

  • role (Symbol)
  • permissions (Array)

Returns:

  • (Set)

Raises:

  • (Malformed)

    if the syntax is not valid.


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/eaco/dsl/resource/permissions.rb', line 109

def save_permission(role, permissions)
  permissions = permissions.inject(Set.new) do |set, perm|
    if perm.is_a?(Symbol)
      set.add perm

    elsif perm.is_a?(Set)
      set.merge perm

    else
      raise Malformed, <<-EOF
        Invalid #{role} permission definition: #{perm.inspect}.
        Permissions can be defined only by plain symbols.
      EOF
    end
  end

  @permissions[role].merge(permissions)
end