annotation_security 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,88 +1,88 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/manager/right_loader.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::RightLoader
|
6
|
-
# Contains the right loader class, which is responsible for loading
|
7
|
-
# right definitions for resources. Load rights from a yaml file or a hash.
|
8
|
-
#
|
9
|
-
# == Example YAML
|
10
|
-
#
|
11
|
-
# The file <tt>config/security/rights.yml</tt> inside a rails app
|
12
|
-
# might look like this:
|
13
|
-
# picture:
|
14
|
-
# # a user may show a picture if he fulfils the 'related'-relation
|
15
|
-
# show: if related
|
16
|
-
# comment:
|
17
|
-
# # you have to be logged in to view comments
|
18
|
-
# show: if logged_in
|
19
|
-
# user:
|
20
|
-
# # like in ruby, 'unless' is equivalent to 'if not'
|
21
|
-
# register: unless logged_in
|
22
|
-
# delete: if administrator # comments are also possible behind a line
|
23
|
-
# user_content:
|
24
|
-
# # all rights of 'user_content' are defined for 'picture' and 'comment' too
|
25
|
-
# applies_to: picture, comment
|
26
|
-
# create: if logged_in
|
27
|
-
# edit: if owner
|
28
|
-
# delete: if owner or administrator
|
29
|
-
# The file can be loaded via <code>AnnotationSecurity#load_rights('rights')</code>.
|
30
|
-
#
|
31
|
-
# A right's condition can use the keywords +if+, +unless+, +and+, +or+ and
|
32
|
-
# +not+, brackets, other rights and all of the resource's relations
|
33
|
-
# (see AnnotationSecurity::RelationLoader). For better readability you may
|
34
|
-
# add the prefixes +may+, +is+, +can+ or +has+,
|
35
|
-
# or append one of the suffixes +for+, +in+, +of+ or +to+.
|
36
|
-
#
|
37
|
-
# user_content:
|
38
|
-
# edit: if is_owner_of
|
39
|
-
# delete: if may_edit or is_administrator
|
40
|
-
#
|
41
|
-
# However, it is recommended to use this feature sparingly.
|
42
|
-
#
|
43
|
-
class AnnotationSecurity::RightLoader
|
44
|
-
|
45
|
-
# Goes through all resources of +hash+ and load the defined rights.
|
46
|
-
#
|
47
|
-
def self.define_rights(hash) # :nodoc:
|
48
|
-
if hash
|
49
|
-
hash.each_pair do |resource_class, rights|
|
50
|
-
new(resource_class).define_rights(rights)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
# An instance of RightLoader is responsible for loading the rights of a
|
56
|
-
# resource class.
|
57
|
-
#
|
58
|
-
def initialize(resource) # :nodoc:
|
59
|
-
@factory = AnnotationSecurity::PolicyManager.policy_factory(resource)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Goes through all rights in +hash+ and creates rules for all policies these
|
63
|
-
# rights apply to.
|
64
|
-
#
|
65
|
-
def define_rights(hash) # :nodoc:
|
66
|
-
factories = extract_applies_to(hash) << @factory
|
67
|
-
hash.each_pair do |right,condition|
|
68
|
-
# Important: set the :right-flag to activate automatic detection of
|
69
|
-
# the other flags (static,dynamic,require_user)
|
70
|
-
factories.each { |f| f.add_rule(right,:right,condition) }
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
# Looks for the key 'applies_to', which is no right but a command to apply
|
77
|
-
# all rights of the current resource class to the resource classes listed
|
78
|
-
# in the value.
|
79
|
-
#
|
80
|
-
def extract_applies_to(hash)
|
81
|
-
applies_to = hash.delete('applies_to') || hash.delete(:applies_to)
|
82
|
-
return [] if applies_to.blank?
|
83
|
-
applies_to = [applies_to] if applies_to.is_a? String
|
84
|
-
applies_to.collect{ |r| r.split(',') }.flatten.
|
85
|
-
collect{ |r| AnnotationSecurity::PolicyManager.policy_factory(r.strip) }
|
86
|
-
end
|
87
|
-
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/manager/right_loader.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::RightLoader
|
6
|
+
# Contains the right loader class, which is responsible for loading
|
7
|
+
# right definitions for resources. Load rights from a yaml file or a hash.
|
8
|
+
#
|
9
|
+
# == Example YAML
|
10
|
+
#
|
11
|
+
# The file <tt>config/security/rights.yml</tt> inside a rails app
|
12
|
+
# might look like this:
|
13
|
+
# picture:
|
14
|
+
# # a user may show a picture if he fulfils the 'related'-relation
|
15
|
+
# show: if related
|
16
|
+
# comment:
|
17
|
+
# # you have to be logged in to view comments
|
18
|
+
# show: if logged_in
|
19
|
+
# user:
|
20
|
+
# # like in ruby, 'unless' is equivalent to 'if not'
|
21
|
+
# register: unless logged_in
|
22
|
+
# delete: if administrator # comments are also possible behind a line
|
23
|
+
# user_content:
|
24
|
+
# # all rights of 'user_content' are defined for 'picture' and 'comment' too
|
25
|
+
# applies_to: picture, comment
|
26
|
+
# create: if logged_in
|
27
|
+
# edit: if owner
|
28
|
+
# delete: if owner or administrator
|
29
|
+
# The file can be loaded via <code>AnnotationSecurity#load_rights('rights')</code>.
|
30
|
+
#
|
31
|
+
# A right's condition can use the keywords +if+, +unless+, +and+, +or+ and
|
32
|
+
# +not+, brackets, other rights and all of the resource's relations
|
33
|
+
# (see AnnotationSecurity::RelationLoader). For better readability you may
|
34
|
+
# add the prefixes +may+, +is+, +can+ or +has+,
|
35
|
+
# or append one of the suffixes +for+, +in+, +of+ or +to+.
|
36
|
+
#
|
37
|
+
# user_content:
|
38
|
+
# edit: if is_owner_of
|
39
|
+
# delete: if may_edit or is_administrator
|
40
|
+
#
|
41
|
+
# However, it is recommended to use this feature sparingly.
|
42
|
+
#
|
43
|
+
class AnnotationSecurity::RightLoader
|
44
|
+
|
45
|
+
# Goes through all resources of +hash+ and load the defined rights.
|
46
|
+
#
|
47
|
+
def self.define_rights(hash) # :nodoc:
|
48
|
+
if hash
|
49
|
+
hash.each_pair do |resource_class, rights|
|
50
|
+
new(resource_class).define_rights(rights)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# An instance of RightLoader is responsible for loading the rights of a
|
56
|
+
# resource class.
|
57
|
+
#
|
58
|
+
def initialize(resource) # :nodoc:
|
59
|
+
@factory = AnnotationSecurity::PolicyManager.policy_factory(resource)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Goes through all rights in +hash+ and creates rules for all policies these
|
63
|
+
# rights apply to.
|
64
|
+
#
|
65
|
+
def define_rights(hash) # :nodoc:
|
66
|
+
factories = extract_applies_to(hash) << @factory
|
67
|
+
hash.each_pair do |right,condition|
|
68
|
+
# Important: set the :right-flag to activate automatic detection of
|
69
|
+
# the other flags (static,dynamic,require_user)
|
70
|
+
factories.each { |f| f.add_rule(right,:right,condition) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Looks for the key 'applies_to', which is no right but a command to apply
|
77
|
+
# all rights of the current resource class to the resource classes listed
|
78
|
+
# in the value.
|
79
|
+
#
|
80
|
+
def extract_applies_to(hash)
|
81
|
+
applies_to = hash.delete('applies_to') || hash.delete(:applies_to)
|
82
|
+
return [] if applies_to.blank?
|
83
|
+
applies_to = [applies_to] if applies_to.is_a? String
|
84
|
+
applies_to.collect{ |r| r.split(',') }.flatten.
|
85
|
+
collect{ |r| AnnotationSecurity::PolicyManager.policy_factory(r.strip) }
|
86
|
+
end
|
87
|
+
|
88
88
|
end
|
@@ -1,61 +1,61 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/model_observer.rb
|
3
|
-
#
|
4
|
-
# Contains SecurityObserver which implements constraint checking for model
|
5
|
-
# classes.
|
6
|
-
#
|
7
|
-
|
8
|
-
module AnnotationSecurity
|
9
|
-
|
10
|
-
# Observes changes in models and applies security policy to them
|
11
|
-
#
|
12
|
-
class ModelObserver < ::ActiveRecord::Observer # :nodoc:
|
13
|
-
|
14
|
-
# Sets the observed model classes
|
15
|
-
#
|
16
|
-
observe # will be set automatically. However, observe must not be removed
|
17
|
-
|
18
|
-
def before_validation_on_create(record)
|
19
|
-
SecurityContext.observe record
|
20
|
-
end
|
21
|
-
|
22
|
-
def before_validation_on_update(record)
|
23
|
-
SecurityContext.observe record
|
24
|
-
end
|
25
|
-
|
26
|
-
# after_find is removed in favour of after_initialize
|
27
|
-
|
28
|
-
def after_initialize(record)
|
29
|
-
if record.new_record?
|
30
|
-
# The record is new
|
31
|
-
else
|
32
|
-
# The record came out of database
|
33
|
-
SecurityContext.observe record
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def before_destroy(record)
|
38
|
-
SecurityContext.observe record
|
39
|
-
end
|
40
|
-
|
41
|
-
# Re-register on classes you are observing
|
42
|
-
# See http://riotprojects.com/2009/1/18/active-record-observers-in-gems-plugins
|
43
|
-
#
|
44
|
-
def reload_model_observer
|
45
|
-
observed_classes.each do |klass|
|
46
|
-
add_observer!(klass.name.constantize)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
protected
|
51
|
-
|
52
|
-
def add_observer!(klass)
|
53
|
-
klass.delete_observer(self)
|
54
|
-
super
|
55
|
-
|
56
|
-
if respond_to?(:after_initialize) && !klass.method_defined?(:after_initialize)
|
57
|
-
klass.class_eval 'def after_initialize() end'
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/model_observer.rb
|
3
|
+
#
|
4
|
+
# Contains SecurityObserver which implements constraint checking for model
|
5
|
+
# classes.
|
6
|
+
#
|
7
|
+
|
8
|
+
module AnnotationSecurity
|
9
|
+
|
10
|
+
# Observes changes in models and applies security policy to them
|
11
|
+
#
|
12
|
+
class ModelObserver < ::ActiveRecord::Observer # :nodoc:
|
13
|
+
|
14
|
+
# Sets the observed model classes
|
15
|
+
#
|
16
|
+
observe # will be set automatically. However, observe must not be removed
|
17
|
+
|
18
|
+
def before_validation_on_create(record)
|
19
|
+
SecurityContext.observe record
|
20
|
+
end
|
21
|
+
|
22
|
+
def before_validation_on_update(record)
|
23
|
+
SecurityContext.observe record
|
24
|
+
end
|
25
|
+
|
26
|
+
# after_find is removed in favour of after_initialize
|
27
|
+
|
28
|
+
def after_initialize(record)
|
29
|
+
if record.new_record?
|
30
|
+
# The record is new
|
31
|
+
else
|
32
|
+
# The record came out of database
|
33
|
+
SecurityContext.observe record
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def before_destroy(record)
|
38
|
+
SecurityContext.observe record
|
39
|
+
end
|
40
|
+
|
41
|
+
# Re-register on classes you are observing
|
42
|
+
# See http://riotprojects.com/2009/1/18/active-record-observers-in-gems-plugins
|
43
|
+
#
|
44
|
+
def reload_model_observer
|
45
|
+
observed_classes.each do |klass|
|
46
|
+
add_observer!(klass.name.constantize)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def add_observer!(klass)
|
53
|
+
klass.delete_observer(self)
|
54
|
+
super
|
55
|
+
|
56
|
+
if respond_to?(:after_initialize) && !klass.method_defined?(:after_initialize)
|
57
|
+
klass.class_eval 'def after_initialize() end'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|