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,38 +1,38 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/filters.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
require "active_record"
|
6
|
-
|
7
|
-
module AnnotationSecurity # :nodoc:
|
8
|
-
|
9
|
-
# Contains filters of the security layer which filter current requests,
|
10
|
-
# set up security context and apply security rules.
|
11
|
-
module Filters
|
12
|
-
# This filter is a before filter and is executed as the first filter in the
|
13
|
-
# filter chain. It initializes the security layer.
|
14
|
-
class InitializeSecurity
|
15
|
-
|
16
|
-
# Initialize current security context depending on logged_in user
|
17
|
-
def self.filter(controller)
|
18
|
-
SecurityContext.initialize(controller)
|
19
|
-
yield
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# This filter is an around filter and is executed as the last filter before
|
24
|
-
# execution of action. It applies the security mechanisms.
|
25
|
-
class ApplySecurity
|
26
|
-
# Applies security policies based on current user.
|
27
|
-
def self.filter(controller)
|
28
|
-
::ActiveRecord::Base.transaction do
|
29
|
-
rules = controller.class.descriptions_of(controller.action_name)
|
30
|
-
SecurityContext.current.eval_with_security(rules){ yield }
|
31
|
-
end
|
32
|
-
rescue AnnotationSecurity::SecurityError
|
33
|
-
SecurityContext.security_exception = $!
|
34
|
-
raise $!
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/filters.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
require "active_record"
|
6
|
+
|
7
|
+
module AnnotationSecurity # :nodoc:
|
8
|
+
|
9
|
+
# Contains filters of the security layer which filter current requests,
|
10
|
+
# set up security context and apply security rules.
|
11
|
+
module Filters
|
12
|
+
# This filter is a before filter and is executed as the first filter in the
|
13
|
+
# filter chain. It initializes the security layer.
|
14
|
+
class InitializeSecurity
|
15
|
+
|
16
|
+
# Initialize current security context depending on logged_in user
|
17
|
+
def self.filter(controller)
|
18
|
+
SecurityContext.initialize(controller)
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# This filter is an around filter and is executed as the last filter before
|
24
|
+
# execution of action. It applies the security mechanisms.
|
25
|
+
class ApplySecurity
|
26
|
+
# Applies security policies based on current user.
|
27
|
+
def self.filter(controller)
|
28
|
+
::ActiveRecord::Base.transaction do
|
29
|
+
rules = controller.class.descriptions_of(controller.action_name)
|
30
|
+
SecurityContext.current.eval_with_security(rules){ yield }
|
31
|
+
end
|
32
|
+
rescue AnnotationSecurity::SecurityError
|
33
|
+
SecurityContext.security_exception = $!
|
34
|
+
raise $!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
38
|
end
|
@@ -1,144 +1,145 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/includes/action_controller.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# Provides security extensions for rails controllers.
|
6
|
-
# Is included in ActionController::Base.
|
7
|
-
#
|
8
|
-
# See AnnotationSecurity::ActionController::ClassMethods.
|
9
|
-
#
|
10
|
-
module AnnotationSecurity::ActionController
|
11
|
-
|
12
|
-
def self.included(base) # :nodoc:
|
13
|
-
base.extend(ClassMethods)
|
14
|
-
base.send :include, InstanceMethods
|
15
|
-
end
|
16
|
-
|
17
|
-
# Provides security extensions for rails controllers on the class side.
|
18
|
-
#
|
19
|
-
module ClassMethods
|
20
|
-
|
21
|
-
# Filters are not affected by the security settings of the action.
|
22
|
-
# If you want security checkings in your filters, activate them with
|
23
|
-
# +apply_security+.
|
24
|
-
#
|
25
|
-
# apply_security :get_user
|
26
|
-
#
|
27
|
-
# private
|
28
|
-
#
|
29
|
-
# desc "shows a user"
|
30
|
-
# def get_user
|
31
|
-
# @user = User.find params[:id]
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# You can use +apply_security+ to secure any methods, not only filters.
|
35
|
-
# Notice that these rules are *not* taken into account when evaluating
|
36
|
-
# AnnotationSecurity::Helper#link_to_if_allowed and similar methods.
|
37
|
-
#
|
38
|
-
def apply_security(*symbols)
|
39
|
-
symbols.each { |s| pending_security_wrappers << s.to_sym }
|
40
|
-
end
|
41
|
-
|
42
|
-
# Filters are not affected by the security settings of the action.
|
43
|
-
# If you want the security settings of the action applied to your filter,
|
44
|
-
# use this method. It can be combined with #apply_security
|
45
|
-
def apply_action_security(*symbols)
|
46
|
-
symbols.each { |s| pending_action_security_wrappers << s.to_sym }
|
47
|
-
end
|
48
|
-
|
49
|
-
# AnnotationSecurity is using the +method_added+ callback. If this method
|
50
|
-
# is overwritten without calling +super+, +apply_security+ will not work.
|
51
|
-
#
|
52
|
-
def method_added(method)
|
53
|
-
super(method)
|
54
|
-
if pending_security_wrappers.delete method
|
55
|
-
build_security_wrapper(method)
|
56
|
-
end
|
57
|
-
if pending_action_security_wrappers.delete method
|
58
|
-
build_action_security_wrapper(method)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# If no resource type is provided in a description, the default resource
|
63
|
-
# will be used. Once set the value cannot be changed.
|
64
|
-
#
|
65
|
-
# This is still experimental. You should not use it unless you have a
|
66
|
-
# reason. It might be
|
67
|
-
#
|
68
|
-
def default_resource(value=nil)
|
69
|
-
@default_resource ||= value || compute_default_resource
|
70
|
-
end
|
71
|
-
|
72
|
-
# Creates a new security filter.
|
73
|
-
#
|
74
|
-
# Security filters are around filters that are evaluated before the first
|
75
|
-
# before filter. Use security filters to set the credentials and to react
|
76
|
-
# to security violations.
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/includes/action_controller.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# Provides security extensions for rails controllers.
|
6
|
+
# Is included in ActionController::Base.
|
7
|
+
#
|
8
|
+
# See AnnotationSecurity::ActionController::ClassMethods.
|
9
|
+
#
|
10
|
+
module AnnotationSecurity::ActionController
|
11
|
+
|
12
|
+
def self.included(base) # :nodoc:
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
base.send :include, InstanceMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
# Provides security extensions for rails controllers on the class side.
|
18
|
+
#
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
# Filters are not affected by the security settings of the action.
|
22
|
+
# If you want security checkings in your filters, activate them with
|
23
|
+
# +apply_security+.
|
24
|
+
#
|
25
|
+
# apply_security :get_user
|
26
|
+
#
|
27
|
+
# private
|
28
|
+
#
|
29
|
+
# desc "shows a user"
|
30
|
+
# def get_user
|
31
|
+
# @user = User.find params[:id]
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# You can use +apply_security+ to secure any methods, not only filters.
|
35
|
+
# Notice that these rules are *not* taken into account when evaluating
|
36
|
+
# AnnotationSecurity::Helper#link_to_if_allowed and similar methods.
|
37
|
+
#
|
38
|
+
def apply_security(*symbols)
|
39
|
+
symbols.each { |s| pending_security_wrappers << s.to_sym }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Filters are not affected by the security settings of the action.
|
43
|
+
# If you want the security settings of the action applied to your filter,
|
44
|
+
# use this method. It can be combined with #apply_security
|
45
|
+
def apply_action_security(*symbols)
|
46
|
+
symbols.each { |s| pending_action_security_wrappers << s.to_sym }
|
47
|
+
end
|
48
|
+
|
49
|
+
# AnnotationSecurity is using the +method_added+ callback. If this method
|
50
|
+
# is overwritten without calling +super+, +apply_security+ will not work.
|
51
|
+
#
|
52
|
+
def method_added(method)
|
53
|
+
super(method)
|
54
|
+
if pending_security_wrappers.delete method
|
55
|
+
build_security_wrapper(method)
|
56
|
+
end
|
57
|
+
if pending_action_security_wrappers.delete method
|
58
|
+
build_action_security_wrapper(method)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# If no resource type is provided in a description, the default resource
|
63
|
+
# will be used. Once set the value cannot be changed.
|
64
|
+
#
|
65
|
+
# This is still experimental. You should not use it unless you have a
|
66
|
+
# reason. It might be useful for inheritance.
|
67
|
+
#
|
68
|
+
def default_resource(value=nil)
|
69
|
+
@default_resource ||= value || compute_default_resource
|
70
|
+
end
|
71
|
+
|
72
|
+
# Creates a new security filter.
|
73
|
+
#
|
74
|
+
# Security filters are around filters that are evaluated before the first
|
75
|
+
# before filter. Use security filters to set the credentials and to react
|
76
|
+
# to security violations.
|
77
|
+
#
|
78
|
+
# class ApplicationController < ActionController::Base
|
79
|
+
#
|
80
|
+
# security_filter :security_filter
|
81
|
+
#
|
82
|
+
# private
|
83
|
+
#
|
84
|
+
# def security_filter
|
85
|
+
# SecurityContext.current_credential = session[:user]
|
86
|
+
# yield
|
87
|
+
# rescue SecurityViolationError
|
88
|
+
# if SecurityContext.is? :logged_in
|
89
|
+
# render :template => "welcome/not_allowed"
|
90
|
+
# else
|
91
|
+
# render :template => "welcome/please_login"
|
92
|
+
# end
|
93
|
+
# end
|
94
|
+
#
|
95
|
+
# See SecurityContext#current_credential= and SecurityViolationError.
|
96
|
+
#
|
97
|
+
def security_filter(symbol, &block)
|
98
|
+
filter_chain.append_filter_to_chain([symbol], :security, &block)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def pending_security_wrappers
|
104
|
+
@pending_security_wrappers ||= []
|
105
|
+
end
|
106
|
+
|
107
|
+
def pending_action_security_wrappers
|
108
|
+
@pending_action_security_wrappers ||= []
|
109
|
+
end
|
110
|
+
|
111
|
+
def build_security_wrapper(method)
|
112
|
+
no_security = "#{method}_without_security".to_sym
|
113
|
+
class_eval %{
|
114
|
+
alias :#{no_security} :#{method}
|
115
|
+
def #{method}(*args, &proc)
|
116
|
+
rules = self.class.descriptions_of(:#{method})
|
117
|
+
SecurityContext.current.send_with_security(rules, self, :#{no_security}, *args, &proc)
|
118
|
+
end
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
def build_action_security_wrapper(method)
|
123
|
+
no_security = "#{method}_without_action_security".to_sym
|
124
|
+
class_eval %{
|
125
|
+
alias :#{no_security} :#{method}
|
126
|
+
def #{method}(*args, &proc)
|
127
|
+
rules = self.class.descriptions_of(action_name)
|
128
|
+
SecurityContext.current.send_with_security(rules, self, :#{no_security}, *args, &proc)
|
129
|
+
end
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def compute_default_resource
|
134
|
+
name.first(-"Controller".length).singularize.underscore.to_sym
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
module InstanceMethods # :nodoc:
|
140
|
+
|
141
|
+
def security_exception=(ex)
|
142
|
+
@security_exception = ex
|
143
|
+
end
|
144
|
+
end
|
144
145
|
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
#
|
2
|
-
# = lib/annotation_security/includes/active_record.rb
|
3
|
-
#
|
4
|
-
|
5
|
-
# = AnnotationSecurity::ActiveRecord
|
6
|
-
#
|
7
|
-
# Included by model classes if they are used as resources.
|
8
|
-
# Includes AnnotationSecurity::Resource and sets up the model observer.
|
9
|
-
#
|
10
|
-
module AnnotationSecurity::ActiveRecord # :nodoc:
|
11
|
-
|
12
|
-
def self.included(base)
|
13
|
-
base.class_eval do
|
14
|
-
include ::AnnotationSecurity::Resource
|
15
|
-
end
|
16
|
-
base.extend(ClassMethods)
|
17
|
-
AnnotationSecurity::ModelObserver.observe base.name.underscore.to_sym
|
18
|
-
AnnotationSecurity::ModelObserver.instance.reload_model_observer
|
19
|
-
end
|
20
|
-
|
21
|
-
module ClassMethods # :nodoc:
|
22
|
-
def get_resource(object)
|
23
|
-
return object if object.is_a? self
|
24
|
-
# Object.const_get(name) needed because of a bug in Rails
|
25
|
-
Object.const_get(name).find(object)
|
26
|
-
end
|
27
|
-
end
|
1
|
+
#
|
2
|
+
# = lib/annotation_security/includes/active_record.rb
|
3
|
+
#
|
4
|
+
|
5
|
+
# = AnnotationSecurity::ActiveRecord
|
6
|
+
#
|
7
|
+
# Included by model classes if they are used as resources.
|
8
|
+
# Includes AnnotationSecurity::Resource and sets up the model observer.
|
9
|
+
#
|
10
|
+
module AnnotationSecurity::ActiveRecord # :nodoc:
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.class_eval do
|
14
|
+
include ::AnnotationSecurity::Resource
|
15
|
+
end
|
16
|
+
base.extend(ClassMethods)
|
17
|
+
AnnotationSecurity::ModelObserver.observe base.name.underscore.to_sym
|
18
|
+
AnnotationSecurity::ModelObserver.instance.reload_model_observer
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods # :nodoc:
|
22
|
+
def get_resource(object)
|
23
|
+
return object if object.is_a? self
|
24
|
+
# Object.const_get(name) needed because of a bug in Rails
|
25
|
+
Object.const_get(name).find(object)
|
26
|
+
end
|
27
|
+
end
|
28
28
|
end
|