Class: StoneWall::AccessController
- Inherits:
-
Object
- Object
- StoneWall::AccessController
- Defined in:
- lib/stonewall/access_controller.rb
Overview
a word of caution, use this framework to guard 'normal user space' methods only - don't try to guard meta stuff like 'send'. If you have ever seen 'Being John Malkovich', you can understand why.
Instance Attribute Summary collapse
-
#actions ⇒ Object
Returns the value of attribute actions.
-
#guarded_attributes ⇒ Object
readonly
Returns the value of attribute guarded_attributes.
-
#guarded_class ⇒ Object
readonly
Returns the value of attribute guarded_class.
-
#guarded_methods ⇒ Object
readonly
Returns the value of attribute guarded_methods.
-
#matrix ⇒ Object
the matrix is the money-shot of the access controller.
-
#method_groups ⇒ Object
Returns the value of attribute method_groups.
-
#variant_field ⇒ Object
readonly
Returns the value of attribute variant_field.
Instance Method Summary collapse
- #add_grant(r, v, m) ⇒ Object
-
#allowed?(guarded_object, user, method) ⇒ Boolean
-------------- This is 1/3rd of the magic in this gem.
- #granted?(r, v, m) ⇒ Boolean
- #grants ⇒ Object
- #guard_attribute(attribute) ⇒ Object
-
#guard_method(method) ⇒ Object
This is similar to, but not the same as, the guard method on the parser.
-
#initialize(guarded_class) ⇒ AccessController
constructor
A new instance of AccessController.
- #set_variant_field(field) ⇒ Object
Constructor Details
#initialize(guarded_class) ⇒ AccessController
Returns a new instance of AccessController.
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/stonewall/access_controller.rb', line 20 def initialize(guarded_class) @guarded_class = guarded_class @guarded_methods = Array.new @guarded_attributes = Array.new @actions = Hash.new @matrix = Hash.new @method_groups = Hash.new @method_groups[:readers] = Array.new @method_groups[:writers] = Array.new end |
Instance Attribute Details
#actions ⇒ Object
Returns the value of attribute actions.
9 10 11 |
# File 'lib/stonewall/access_controller.rb', line 9 def actions @actions end |
#guarded_attributes ⇒ Object (readonly)
Returns the value of attribute guarded_attributes.
11 12 13 |
# File 'lib/stonewall/access_controller.rb', line 11 def guarded_attributes @guarded_attributes end |
#guarded_class ⇒ Object (readonly)
Returns the value of attribute guarded_class.
7 8 9 |
# File 'lib/stonewall/access_controller.rb', line 7 def guarded_class @guarded_class end |
#guarded_methods ⇒ Object (readonly)
Returns the value of attribute guarded_methods.
10 11 12 |
# File 'lib/stonewall/access_controller.rb', line 10 def guarded_methods @guarded_methods end |
#matrix ⇒ Object
the matrix is the money-shot of the access controller. You can set it through add_grant, and query it through 'granted', but you can also access the data structure directly if you want to avoid the dsl. It is in the format [role][varient][member]
18 19 20 |
# File 'lib/stonewall/access_controller.rb', line 18 def matrix @matrix end |
#method_groups ⇒ Object
Returns the value of attribute method_groups.
12 13 14 |
# File 'lib/stonewall/access_controller.rb', line 12 def method_groups @method_groups end |
#variant_field ⇒ Object (readonly)
Returns the value of attribute variant_field.
8 9 10 |
# File 'lib/stonewall/access_controller.rb', line 8 def variant_field @variant_field end |
Instance Method Details
#add_grant(r, v, m) ⇒ Object
40 41 42 43 44 |
# File 'lib/stonewall/access_controller.rb', line 40 def add_grant(r, v, m) @matrix[r] ||= Hash.new @matrix[r][v] ||= Array.new @matrix[r][v] << m end |
#allowed?(guarded_object, user, method) ⇒ Boolean
This is 1/3rd of the magic in this gem. Every method you guard is checked by this method. It looks at the matrix of permissions you built in the dsl and allows or denies based on the guarded object, the user, and the method being accessed. #should we fail secure?
this method is too complex - needs some refactoring to make it more easily testable
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/stonewall/access_controller.rb', line 76 def allowed?(guarded_object, user, method) return true if (guarded_object.nil? || user.nil? || method.nil?) return true unless @guarded_methods.include?(method) # if they can always view it, no need to check variant. always = user.stonewall_role_info.detect do |r| granted?(r, :all, :all) || granted?(r, :all, method) end return always if always v = guarded_object.send(variant_field) && guarded_object.send(variant_field).to_sym # if the variant field isn't set, is this a reasonable thing to do? return true if v.nil? user.stonewall_role_info.detect do |r| granted?(r, v, :all) || granted?(r, v, method) end || false end |
#granted?(r, v, m) ⇒ Boolean
46 47 48 |
# File 'lib/stonewall/access_controller.rb', line 46 def granted?(r, v, m) matrix[r] && matrix[r][v] && matrix[r][v].include?(m) end |
#grants ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/stonewall/access_controller.rb', line 97 def grants grants = Array.new @matrix.each do |r, vm| vm.each do |v, methods| methods.each do |m| grants << [r, v, m] end end end return grants end |
#guard_attribute(attribute) ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/stonewall/access_controller.rb', line 58 def guard_attribute(attribute) guarded_attributes << attribute guard_method(attribute) @method_groups[:readers] << attribute setter = (attribute.to_s + "=").to_sym guard_method(setter) @method_groups[:writers] << setter end |
#guard_method(method) ⇒ Object
This is similar to, but not the same as, the guard method on the parser. The parser has to wait until the methods are reified. Since this is got adding guards at runtime, we don't have that restruction here.
53 54 55 56 |
# File 'lib/stonewall/access_controller.rb', line 53 def guard_method(method) StoneWall::Helpers.guard(@guarded_class, method) StoneWall::Helpers.fix_alias_for(@guarded_class, method) end |
#set_variant_field(field) ⇒ Object
32 33 34 35 36 37 38 |
# File 'lib/stonewall/access_controller.rb', line 32 def set_variant_field(field) if @variant_field.nil? @variant_field = field else raise "no redefinition of variant field" end end |