annotation_security 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +14 -0
- data/HOW-TO.md +275 -0
- data/{MIT-LICENSE → LICENSE} +1 -1
- data/README.md +39 -0
- data/Rakefile +62 -55
- data/assets/app/helpers/annotation_security_helper.rb +8 -8
- data/assets/config/initializers/annotation_security.rb +11 -11
- data/assets/config/security/relations.rb +20 -20
- data/assets/vendor/plugins/annotation_security/init.rb +13 -13
- data/bin/annotation_security +7 -7
- data/lib/annotation_security/exceptions.rb +124 -124
- data/lib/annotation_security/exec.rb +188 -188
- data/lib/annotation_security/filters.rb +37 -37
- data/lib/annotation_security/includes/action_controller.rb +144 -143
- data/lib/annotation_security/includes/active_record.rb +27 -27
- data/lib/annotation_security/includes/helper.rb +215 -215
- data/lib/annotation_security/includes/resource.rb +84 -84
- data/lib/annotation_security/includes/role.rb +30 -30
- data/lib/annotation_security/includes/user.rb +26 -26
- data/lib/annotation_security/manager/policy_factory.rb +29 -29
- data/lib/annotation_security/manager/policy_manager.rb +79 -79
- data/lib/annotation_security/manager/relation_loader.rb +272 -272
- data/lib/annotation_security/manager/resource_manager.rb +36 -36
- data/lib/annotation_security/manager/right_loader.rb +87 -87
- data/lib/annotation_security/model_observer.rb +61 -61
- data/lib/annotation_security/policy/abstract_policy.rb +344 -344
- data/lib/annotation_security/policy/abstract_static_policy.rb +75 -75
- data/lib/annotation_security/policy/all_resources_policy.rb +20 -20
- data/lib/annotation_security/policy/rule.rb +340 -340
- data/lib/annotation_security/policy/rule_set.rb +138 -138
- data/lib/annotation_security/rails.rb +38 -38
- data/lib/annotation_security/user_wrapper.rb +73 -73
- data/lib/annotation_security/utils.rb +141 -141
- data/lib/annotation_security/version.rb +10 -0
- data/lib/annotation_security.rb +102 -97
- data/lib/extensions/action_controller.rb +32 -32
- data/lib/extensions/active_record.rb +34 -34
- data/lib/extensions/filter.rb +133 -133
- data/lib/extensions/object.rb +10 -10
- data/lib/security_context.rb +589 -551
- data/spec/annotation_security/exceptions_spec.rb +16 -16
- data/spec/annotation_security/includes/helper_spec.rb +82 -82
- data/spec/annotation_security/manager/policy_manager_spec.rb +15 -15
- data/spec/annotation_security/manager/resource_manager_spec.rb +17 -17
- data/spec/annotation_security/manager/right_loader_spec.rb +17 -17
- data/spec/annotation_security/policy/abstract_policy_spec.rb +16 -16
- data/spec/annotation_security/policy/all_resources_policy_spec.rb +24 -24
- data/spec/annotation_security/policy/rule_set_spec.rb +112 -112
- data/spec/annotation_security/policy/rule_spec.rb +77 -77
- data/spec/annotation_security/policy/test_policy_spec.rb +80 -80
- data/spec/annotation_security/security_context_spec.rb +78 -78
- data/spec/annotation_security/utils_spec.rb +73 -73
- data/spec/helper/test_controller.rb +65 -65
- data/spec/helper/test_helper.rb +5 -5
- data/spec/helper/test_relations.rb +6 -6
- data/spec/helper/test_resource.rb +38 -38
- data/spec/helper/test_role.rb +21 -21
- data/spec/helper/test_user.rb +31 -31
- data/spec/rails_stub.rb +37 -37
- metadata +94 -72
- data/CHANGELOG +0 -2
- data/HOW-TO +0 -261
- data/README +0 -39
@@ -1,139 +1,139 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/policy/rule_set.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::RuleSet
|
6
|
-
# Contains all rule objects for a policy
|
7
|
-
#
|
8
|
-
class AnnotationSecurity::RuleSet # :nodoc:
|
9
|
-
|
10
|
-
# Initializes the rule set
|
11
|
-
# * +pclass+ Policy class this rule set belongs to
|
12
|
-
#
|
13
|
-
def initialize(pclass)
|
14
|
-
super()
|
15
|
-
@pclass = pclass
|
16
|
-
@rights = {}
|
17
|
-
@static = {}
|
18
|
-
@dynamic = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_s
|
22
|
-
"<RuleSet of #@pclass>"
|
23
|
-
end
|
24
|
-
|
25
|
-
# Returns a rule object or nil if the rule does not exist.
|
26
|
-
# * +symbol+ name of the rule
|
27
|
-
# * +static+ boolean specifing whether the rule is static or dynamic
|
28
|
-
def get_rule(symbol,static)
|
29
|
-
static ? get_static_rule(symbol) : get_dynamic_rule(symbol)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns a dynamic rule or nil if the rule does not exist.
|
33
|
-
# * +symbol+ name of the rule
|
34
|
-
def get_dynamic_rule(symbol)
|
35
|
-
# If no rule is available, maybe there is a right that can be used
|
36
|
-
@dynamic[symbol] ||= get_dynamic_right(symbol)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Returns a static rule or nil if the rule does not exist.
|
40
|
-
# * +symbol+ name of the rule
|
41
|
-
def get_static_rule(symbol)
|
42
|
-
# If no rule is available, maybe there is a right that can be used
|
43
|
-
@static[symbol] ||= get_static_right(symbol)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Copies a rule from another rule set.
|
47
|
-
# Returns the newly created rule or nil if the operation had no effect.
|
48
|
-
# * +symbol+ name of the rule
|
49
|
-
# * +source+ rule set to copy from
|
50
|
-
# * +static+ boolean specifing whether the rule is static or dynamic
|
51
|
-
def copy_rule_from(symbol,source,static)
|
52
|
-
add_copy(source.get_rule(symbol,static))
|
53
|
-
end
|
54
|
-
|
55
|
-
# Creates a dynamic rule that redirects to a static rule with the same name.
|
56
|
-
# Returns the newly created rule or nil if the operation had no effect.
|
57
|
-
# * +symbol+ name of the rule
|
58
|
-
def create_dynamic_copy(symbol)
|
59
|
-
rule = get_static_rule(symbol)
|
60
|
-
if rule
|
61
|
-
add_rule(symbol,
|
62
|
-
"static_policy.#{symbol}(*args)",
|
63
|
-
:resource,
|
64
|
-
:require_credential => rule.requires_credential?)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
# Adds a new rule to this rule set. The rule will be classified either
|
69
|
-
# as dynamic, static, both or right.
|
70
|
-
# Returns the newly create rule.
|
71
|
-
# For an explainition of the parameters see AnnotationSecurity::Rule#initialize.
|
72
|
-
def add_rule(symbol,*args,&block)
|
73
|
-
__add__ AnnotationSecurity::Rule.new(symbol,@pclass,*args,&block)
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
# Copies a rule object to this rule set.
|
79
|
-
# Returns the newly created rule or nil.
|
80
|
-
# * +rule+ rule object to copy or nil.
|
81
|
-
def add_copy(rule)
|
82
|
-
__add__(rule.copy(@pclass)) if rule
|
83
|
-
end
|
84
|
-
|
85
|
-
# Adds a new rule to this rule set. The rule will be classified either
|
86
|
-
# as dynamic, static, both or right.
|
87
|
-
# * +rule+ rule object
|
88
|
-
def __add__(rule)
|
89
|
-
if rule.right?
|
90
|
-
# if the rule is a right, its not clear yet whether
|
91
|
-
# it is static or dynamic. These rules will be analyzed later.
|
92
|
-
raise_if_forbidden_name 'right', rule
|
93
|
-
raise_if_exists 'right', @rights[rule.name]
|
94
|
-
@rights[rule.name] = rule
|
95
|
-
else
|
96
|
-
raise_if_forbidden_name 'relation', rule
|
97
|
-
if rule.dynamic?
|
98
|
-
raise_if_exists 'dynamic relation', @dynamic[rule.name]
|
99
|
-
@dynamic[rule.name] = rule
|
100
|
-
end
|
101
|
-
if rule.static?
|
102
|
-
raise_if_exists 'static relation', @static[rule.name]
|
103
|
-
@static[rule.name] = rule
|
104
|
-
end
|
105
|
-
end
|
106
|
-
rule
|
107
|
-
end
|
108
|
-
|
109
|
-
# Raises an error if +rule+ is not nil.
|
110
|
-
# * +type+ type of rule, like 'right' or 'dynamic relation'
|
111
|
-
# * +rule+ existing rule object or nil
|
112
|
-
def raise_if_exists(type,rule)
|
113
|
-
raise AnnotationSecurity::RuleError.defined_twice(type,rule) if rule
|
114
|
-
end
|
115
|
-
|
116
|
-
# Raises an error if +rule+ has a forbidden name.
|
117
|
-
# * +type+ type of rule, like 'right' or 'relation'
|
118
|
-
# * +rule+ rule object
|
119
|
-
def raise_if_forbidden_name(type,rule)
|
120
|
-
if AnnotationSecurity::AbstractPolicy.forbidden_rule_names.include? rule.name.to_s
|
121
|
-
raise AnnotationSecurity::RuleError.forbidden_name(type,rule)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Returns a dynamic rule that was defined as right
|
126
|
-
# * +symbol+ name of the rule
|
127
|
-
def get_dynamic_right(symbol)
|
128
|
-
r = @rights[symbol]
|
129
|
-
r and r.dynamic? ? r : nil
|
130
|
-
end
|
131
|
-
|
132
|
-
# Returns a static rule that was defined as right
|
133
|
-
# * +symbol+ name of the rule
|
134
|
-
def get_static_right(symbol)
|
135
|
-
r = @rights[symbol]
|
136
|
-
r and r.static? ? r : nil
|
137
|
-
end
|
138
|
-
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/policy/rule_set.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::RuleSet
|
6
|
+
# Contains all rule objects for a policy
|
7
|
+
#
|
8
|
+
class AnnotationSecurity::RuleSet # :nodoc:
|
9
|
+
|
10
|
+
# Initializes the rule set
|
11
|
+
# * +pclass+ Policy class this rule set belongs to
|
12
|
+
#
|
13
|
+
def initialize(pclass)
|
14
|
+
super()
|
15
|
+
@pclass = pclass
|
16
|
+
@rights = {}
|
17
|
+
@static = {}
|
18
|
+
@dynamic = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"<RuleSet of #@pclass>"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a rule object or nil if the rule does not exist.
|
26
|
+
# * +symbol+ name of the rule
|
27
|
+
# * +static+ boolean specifing whether the rule is static or dynamic
|
28
|
+
def get_rule(symbol,static)
|
29
|
+
static ? get_static_rule(symbol) : get_dynamic_rule(symbol)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns a dynamic rule or nil if the rule does not exist.
|
33
|
+
# * +symbol+ name of the rule
|
34
|
+
def get_dynamic_rule(symbol)
|
35
|
+
# If no rule is available, maybe there is a right that can be used
|
36
|
+
@dynamic[symbol] ||= get_dynamic_right(symbol)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a static rule or nil if the rule does not exist.
|
40
|
+
# * +symbol+ name of the rule
|
41
|
+
def get_static_rule(symbol)
|
42
|
+
# If no rule is available, maybe there is a right that can be used
|
43
|
+
@static[symbol] ||= get_static_right(symbol)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Copies a rule from another rule set.
|
47
|
+
# Returns the newly created rule or nil if the operation had no effect.
|
48
|
+
# * +symbol+ name of the rule
|
49
|
+
# * +source+ rule set to copy from
|
50
|
+
# * +static+ boolean specifing whether the rule is static or dynamic
|
51
|
+
def copy_rule_from(symbol,source,static)
|
52
|
+
add_copy(source.get_rule(symbol,static))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Creates a dynamic rule that redirects to a static rule with the same name.
|
56
|
+
# Returns the newly created rule or nil if the operation had no effect.
|
57
|
+
# * +symbol+ name of the rule
|
58
|
+
def create_dynamic_copy(symbol)
|
59
|
+
rule = get_static_rule(symbol)
|
60
|
+
if rule
|
61
|
+
add_rule(symbol,
|
62
|
+
"static_policy.#{symbol}(*args)",
|
63
|
+
:resource,
|
64
|
+
:require_credential => rule.requires_credential?)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Adds a new rule to this rule set. The rule will be classified either
|
69
|
+
# as dynamic, static, both or right.
|
70
|
+
# Returns the newly create rule.
|
71
|
+
# For an explainition of the parameters see AnnotationSecurity::Rule#initialize.
|
72
|
+
def add_rule(symbol,*args,&block)
|
73
|
+
__add__ AnnotationSecurity::Rule.new(symbol,@pclass,*args,&block)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Copies a rule object to this rule set.
|
79
|
+
# Returns the newly created rule or nil.
|
80
|
+
# * +rule+ rule object to copy or nil.
|
81
|
+
def add_copy(rule)
|
82
|
+
__add__(rule.copy(@pclass)) if rule
|
83
|
+
end
|
84
|
+
|
85
|
+
# Adds a new rule to this rule set. The rule will be classified either
|
86
|
+
# as dynamic, static, both or right.
|
87
|
+
# * +rule+ rule object
|
88
|
+
def __add__(rule)
|
89
|
+
if rule.right?
|
90
|
+
# if the rule is a right, its not clear yet whether
|
91
|
+
# it is static or dynamic. These rules will be analyzed later.
|
92
|
+
raise_if_forbidden_name 'right', rule
|
93
|
+
raise_if_exists 'right', @rights[rule.name]
|
94
|
+
@rights[rule.name] = rule
|
95
|
+
else
|
96
|
+
raise_if_forbidden_name 'relation', rule
|
97
|
+
if rule.dynamic?
|
98
|
+
raise_if_exists 'dynamic relation', @dynamic[rule.name]
|
99
|
+
@dynamic[rule.name] = rule
|
100
|
+
end
|
101
|
+
if rule.static?
|
102
|
+
raise_if_exists 'static relation', @static[rule.name]
|
103
|
+
@static[rule.name] = rule
|
104
|
+
end
|
105
|
+
end
|
106
|
+
rule
|
107
|
+
end
|
108
|
+
|
109
|
+
# Raises an error if +rule+ is not nil.
|
110
|
+
# * +type+ type of rule, like 'right' or 'dynamic relation'
|
111
|
+
# * +rule+ existing rule object or nil
|
112
|
+
def raise_if_exists(type,rule)
|
113
|
+
raise AnnotationSecurity::RuleError.defined_twice(type,rule) if rule
|
114
|
+
end
|
115
|
+
|
116
|
+
# Raises an error if +rule+ has a forbidden name.
|
117
|
+
# * +type+ type of rule, like 'right' or 'relation'
|
118
|
+
# * +rule+ rule object
|
119
|
+
def raise_if_forbidden_name(type,rule)
|
120
|
+
if AnnotationSecurity::AbstractPolicy.forbidden_rule_names.include? rule.name.to_s
|
121
|
+
raise AnnotationSecurity::RuleError.forbidden_name(type,rule)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Returns a dynamic rule that was defined as right
|
126
|
+
# * +symbol+ name of the rule
|
127
|
+
def get_dynamic_right(symbol)
|
128
|
+
r = @rights[symbol]
|
129
|
+
r and r.dynamic? ? r : nil
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns a static rule that was defined as right
|
133
|
+
# * +symbol+ name of the rule
|
134
|
+
def get_static_right(symbol)
|
135
|
+
r = @rights[symbol]
|
136
|
+
r and r.static? ? r : nil
|
137
|
+
end
|
138
|
+
|
139
139
|
end
|
@@ -1,39 +1,39 @@
|
|
1
|
-
#
|
2
|
-
# = annotation_security/rails/init.rb
|
3
|
-
#
|
4
|
-
# Loads the annotation security layer for a rails app
|
5
|
-
|
6
|
-
require "action_controller/dispatcher"
|
7
|
-
require "action_controller/base"
|
8
|
-
|
9
|
-
module AnnotationSecurity
|
10
|
-
|
11
|
-
# Contains rails specific initializer
|
12
|
-
class Rails
|
13
|
-
def self.init!(config)
|
14
|
-
|
15
|
-
# Policy files are situated under RAILS_ROOT/config/security
|
16
|
-
# Default policy file is internal, load it
|
17
|
-
::AnnotationSecurity.load_relations(File.dirname(__FILE__) + '/policy/all_resources_policy')
|
18
|
-
|
19
|
-
# Add AnnotationSecurity::ModelObserver to observe changes in models.
|
20
|
-
# See http://riotprojects.com/2009/1/18/active-record-observers-in-gems-plugins
|
21
|
-
#
|
22
|
-
config.after_initialize do
|
23
|
-
# Set up a dummy security context that does not interfer with script
|
24
|
-
::SecurityContext.initialize nil
|
25
|
-
|
26
|
-
::ActiveRecord::Base.observers << ::AnnotationSecurity::ModelObserver
|
27
|
-
|
28
|
-
# In development mode, the models we observe get reloaded with each request. Using
|
29
|
-
# this hook allows us to reload the observer relationships each time as well.
|
30
|
-
::ActionController::Dispatcher.to_prepare(:cache_advance_reload) do
|
31
|
-
::AnnotationSecurity.reset
|
32
|
-
::AnnotationSecurity::ModelObserver.instance.reload_model_observer
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
puts "Security layer initialized"
|
37
|
-
end
|
38
|
-
end
|
1
|
+
#
|
2
|
+
# = annotation_security/rails/init.rb
|
3
|
+
#
|
4
|
+
# Loads the annotation security layer for a rails app
|
5
|
+
|
6
|
+
require "action_controller/dispatcher"
|
7
|
+
require "action_controller/base"
|
8
|
+
|
9
|
+
module AnnotationSecurity
|
10
|
+
|
11
|
+
# Contains rails specific initializer
|
12
|
+
class Rails
|
13
|
+
def self.init!(config)
|
14
|
+
|
15
|
+
# Policy files are situated under RAILS_ROOT/config/security
|
16
|
+
# Default policy file is internal, load it
|
17
|
+
::AnnotationSecurity.load_relations(File.dirname(__FILE__) + '/policy/all_resources_policy')
|
18
|
+
|
19
|
+
# Add AnnotationSecurity::ModelObserver to observe changes in models.
|
20
|
+
# See http://riotprojects.com/2009/1/18/active-record-observers-in-gems-plugins
|
21
|
+
#
|
22
|
+
config.after_initialize do
|
23
|
+
# Set up a dummy security context that does not interfer with script
|
24
|
+
::SecurityContext.initialize nil
|
25
|
+
|
26
|
+
::ActiveRecord::Base.observers << ::AnnotationSecurity::ModelObserver
|
27
|
+
|
28
|
+
# In development mode, the models we observe get reloaded with each request. Using
|
29
|
+
# this hook allows us to reload the observer relationships each time as well.
|
30
|
+
::ActionController::Dispatcher.to_prepare(:cache_advance_reload) do
|
31
|
+
::AnnotationSecurity.reset
|
32
|
+
::AnnotationSecurity::ModelObserver.instance.reload_model_observer
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "Security layer initialized"
|
37
|
+
end
|
38
|
+
end
|
39
39
|
end
|
@@ -1,74 +1,74 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/user_wrapper.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::UserWrapper
|
6
|
-
#
|
7
|
-
# This class is not in use!
|
8
|
-
#
|
9
|
-
# Needed for evaluating relations, especially if the :as-option is used.
|
10
|
-
#
|
11
|
-
# Merges a user and a role. If a role is given,
|
12
|
-
#
|
13
|
-
class AnnotationSecurity::UserWrapper # :nodoc:
|
14
|
-
|
15
|
-
# Return user wrappers for the requested role. The role(s) will be
|
16
|
-
# determined with sending user.as_'role'.
|
17
|
-
# (Normally a user has a role only once, however it will work when he
|
18
|
-
# has many roles of the same kind as well)
|
19
|
-
def self.all_for_role(user,role_name)
|
20
|
-
return [] if user.nil?
|
21
|
-
user = user.__user__ if user.is_a? AnnotationSecurity::UserWrapper
|
22
|
-
return [new(user)] if role_name.nil?
|
23
|
-
roles = user.__send__("as_#{role_name}")
|
24
|
-
return [] if roles.blank?
|
25
|
-
roles = [roles] unless roles.is_a?(Array)
|
26
|
-
roles.compact.collect { |role| new(user,role) }
|
27
|
-
end
|
28
|
-
|
29
|
-
def initialize(user,role=nil)
|
30
|
-
@user = user
|
31
|
-
@role = role
|
32
|
-
end
|
33
|
-
|
34
|
-
def id
|
35
|
-
@role? @role.id : @user.id
|
36
|
-
end
|
37
|
-
|
38
|
-
def __user__
|
39
|
-
@user
|
40
|
-
end
|
41
|
-
|
42
|
-
def __role__
|
43
|
-
@role
|
44
|
-
end
|
45
|
-
|
46
|
-
def ==(obj)
|
47
|
-
@user == obj or (!@role.nil? and @role == obj)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Try to send to role, user and policy of args[0]
|
51
|
-
#
|
52
|
-
def method_missing(symbol,*args,&block)
|
53
|
-
if @role && (@role.respond_to? symbol)
|
54
|
-
@role.__send__(symbol,*args,&block)
|
55
|
-
elsif @user.respond_to? symbol
|
56
|
-
@user.__send__(symbol,*args,&block)
|
57
|
-
elsif args.first.respond_to? :policy_for
|
58
|
-
args.first.policy_for(@user).__send__(symbol,*args[1..-1])
|
59
|
-
else
|
60
|
-
# This will raise a NoMethodError
|
61
|
-
@user.__send__(symbol,*args,&block)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def is_a?(klass)
|
66
|
-
return true if super(klass)
|
67
|
-
if @role
|
68
|
-
@role.is_a?(klass)
|
69
|
-
else
|
70
|
-
@user.is_a?(klass)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/user_wrapper.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::UserWrapper
|
6
|
+
#
|
7
|
+
# This class is not in use!
|
8
|
+
#
|
9
|
+
# Needed for evaluating relations, especially if the :as-option is used.
|
10
|
+
#
|
11
|
+
# Merges a user and a role. If a role is given,
|
12
|
+
#
|
13
|
+
class AnnotationSecurity::UserWrapper # :nodoc:
|
14
|
+
|
15
|
+
# Return user wrappers for the requested role. The role(s) will be
|
16
|
+
# determined with sending user.as_'role'.
|
17
|
+
# (Normally a user has a role only once, however it will work when he
|
18
|
+
# has many roles of the same kind as well)
|
19
|
+
def self.all_for_role(user,role_name)
|
20
|
+
return [] if user.nil?
|
21
|
+
user = user.__user__ if user.is_a? AnnotationSecurity::UserWrapper
|
22
|
+
return [new(user)] if role_name.nil?
|
23
|
+
roles = user.__send__("as_#{role_name}")
|
24
|
+
return [] if roles.blank?
|
25
|
+
roles = [roles] unless roles.is_a?(Array)
|
26
|
+
roles.compact.collect { |role| new(user,role) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(user,role=nil)
|
30
|
+
@user = user
|
31
|
+
@role = role
|
32
|
+
end
|
33
|
+
|
34
|
+
def id
|
35
|
+
@role? @role.id : @user.id
|
36
|
+
end
|
37
|
+
|
38
|
+
def __user__
|
39
|
+
@user
|
40
|
+
end
|
41
|
+
|
42
|
+
def __role__
|
43
|
+
@role
|
44
|
+
end
|
45
|
+
|
46
|
+
def ==(obj)
|
47
|
+
@user == obj or (!@role.nil? and @role == obj)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Try to send to role, user and policy of args[0]
|
51
|
+
#
|
52
|
+
def method_missing(symbol,*args,&block)
|
53
|
+
if @role && (@role.respond_to? symbol)
|
54
|
+
@role.__send__(symbol,*args,&block)
|
55
|
+
elsif @user.respond_to? symbol
|
56
|
+
@user.__send__(symbol,*args,&block)
|
57
|
+
elsif args.first.respond_to? :policy_for
|
58
|
+
args.first.policy_for(@user).__send__(symbol,*args[1..-1])
|
59
|
+
else
|
60
|
+
# This will raise a NoMethodError
|
61
|
+
@user.__send__(symbol,*args,&block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_a?(klass)
|
66
|
+
return true if super(klass)
|
67
|
+
if @role
|
68
|
+
@role.is_a?(klass)
|
69
|
+
else
|
70
|
+
@user.is_a?(klass)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
74
|
end
|