annotation_security 1.0.2 → 1.3.1
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 +22 -0
- data/HOW-TO +261 -0
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README +39 -0
- data/Rakefile +53 -62
- 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 +14 -14
- data/bin/annotation_security +7 -7
- data/lib/annotation_security.rb +94 -103
- data/lib/annotation_security/exceptions.rb +124 -124
- data/lib/annotation_security/exec.rb +188 -188
- 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 +87 -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/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 +22 -39
- data/lib/{extensions → annotation_security/rails/2/extensions}/filter.rb +131 -133
- data/lib/annotation_security/rails/2/includes/action_controller.rb +144 -0
- data/lib/annotation_security/rails/2/includes/active_record.rb +28 -0
- data/lib/annotation_security/rails/2/initializer.rb +35 -0
- data/lib/annotation_security/{model_observer.rb → rails/2/model_observer.rb} +61 -61
- data/lib/annotation_security/rails/3/extensions/filter.rb +28 -0
- data/lib/annotation_security/{includes → rails/3/includes}/action_controller.rb +143 -144
- data/lib/annotation_security/{includes → rails/3/includes}/active_record.rb +27 -27
- data/lib/annotation_security/rails/3/initializer.rb +40 -0
- data/lib/annotation_security/rails/3/model_observer.rb +61 -0
- data/lib/annotation_security/rails/extensions.rb +21 -0
- data/lib/{extensions → annotation_security/rails/extensions}/action_controller.rb +31 -32
- data/lib/{extensions → annotation_security/rails/extensions}/active_record.rb +33 -34
- data/lib/{extensions → annotation_security/rails/extensions}/object.rb +10 -10
- data/lib/annotation_security/{filters.rb → rails/filters.rb} +37 -37
- data/lib/annotation_security/user_wrapper.rb +73 -73
- data/lib/annotation_security/utils.rb +141 -141
- data/lib/security_context.rb +588 -589
- 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 +129 -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 +44 -37
- metadata +110 -96
- data/CHANGELOG.md +0 -14
- data/HOW-TO.md +0 -275
- data/README.md +0 -39
- data/lib/annotation_security/version.rb +0 -10
data/spec/rails_stub.rb
CHANGED
@@ -1,38 +1,45 @@
|
|
1
|
-
# AnnoationSecurity requires rails.
|
2
|
-
# Here are some stubs to simulate a rails environment for testing.
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
module
|
22
|
-
class
|
23
|
-
def
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
1
|
+
# AnnoationSecurity requires rails.
|
2
|
+
# Here are some stubs to simulate a rails environment for testing.
|
3
|
+
#
|
4
|
+
|
5
|
+
class Rails
|
6
|
+
def root
|
7
|
+
Pathname.new('')
|
8
|
+
end
|
9
|
+
|
10
|
+
def env
|
11
|
+
return {}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ConfigStub
|
16
|
+
def config
|
17
|
+
self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module ActiveRecord
|
22
|
+
class Observer
|
23
|
+
def self.observe(*args)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ActionController
|
29
|
+
class Base
|
30
|
+
def render(*args)
|
31
|
+
end
|
32
|
+
def redirect_to(*args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
module Routing
|
36
|
+
class Routes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
module Filters
|
40
|
+
class Filter
|
41
|
+
end
|
42
|
+
class AroundFilter < Filter
|
43
|
+
end
|
44
|
+
end
|
38
45
|
end
|
metadata
CHANGED
@@ -1,105 +1,102 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: annotation_security
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 3
|
8
|
+
- 1
|
9
|
+
version: 1.3.1
|
6
10
|
platform: ruby
|
7
|
-
authors:
|
11
|
+
authors:
|
8
12
|
- Nico Rehwaldt, Arian Treffer
|
9
13
|
autorequire:
|
10
14
|
bindir: bin
|
11
15
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
|
17
|
+
date: 2010-11-19 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: action_annotation
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 1.0.1
|
22
|
-
type: :runtime
|
23
22
|
prerelease: false
|
24
|
-
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 0
|
31
|
+
- 1
|
29
32
|
version: 1.0.1
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: activesupport
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: 2.3.18
|
38
33
|
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: activesupport
|
39
37
|
prerelease: false
|
40
|
-
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
-
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
- 3
|
46
|
+
- 5
|
47
|
+
version: 2.3.5
|
48
|
+
type: :runtime
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
47
51
|
name: rspec
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: 1.3.2
|
54
|
-
type: :development
|
55
52
|
prerelease: false
|
56
|
-
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 1.3.2
|
62
|
-
- !ruby/object:Gem::Dependency
|
63
|
-
name: mocha
|
64
|
-
requirement: !ruby/object:Gem::Requirement
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
65
54
|
none: false
|
66
|
-
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 2
|
61
|
+
- 0
|
62
|
+
version: 1.2.0
|
70
63
|
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: mocha
|
71
67
|
prerelease: false
|
72
|
-
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
69
|
none: false
|
74
|
-
requirements:
|
75
|
-
- -
|
76
|
-
- !ruby/object:Gem::Version
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
- 9
|
76
|
+
- 8
|
77
77
|
version: 0.9.8
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
logic. See the gem's homepage for an example.
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
description: AnnotationSecurity provides a role based security model with automated rule evaluation for Ruby on Rails. It allows you to define user-resource-relations and rights in separate files, keeping your controllers and views free from any security logic. See the gem's homepage for an example.
|
82
81
|
email: ruby@nixis.de
|
83
|
-
executables:
|
82
|
+
executables:
|
84
83
|
- annotation_security
|
85
84
|
extensions: []
|
86
|
-
|
87
|
-
|
88
|
-
-
|
89
|
-
-
|
90
|
-
-
|
91
|
-
|
92
|
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
85
|
+
|
86
|
+
extra_rdoc_files:
|
87
|
+
- README
|
88
|
+
- MIT-LICENSE
|
89
|
+
- CHANGELOG
|
90
|
+
- HOW-TO
|
91
|
+
files:
|
92
|
+
- CHANGELOG
|
93
|
+
- MIT-LICENSE
|
94
|
+
- README
|
95
|
+
- HOW-TO
|
96
96
|
- Rakefile
|
97
97
|
- bin/annotation_security
|
98
98
|
- lib/annotation_security/exceptions.rb
|
99
99
|
- lib/annotation_security/exec.rb
|
100
|
-
- lib/annotation_security/filters.rb
|
101
|
-
- lib/annotation_security/includes/action_controller.rb
|
102
|
-
- lib/annotation_security/includes/active_record.rb
|
103
100
|
- lib/annotation_security/includes/helper.rb
|
104
101
|
- lib/annotation_security/includes/resource.rb
|
105
102
|
- lib/annotation_security/includes/role.rb
|
@@ -109,21 +106,30 @@ files:
|
|
109
106
|
- lib/annotation_security/manager/relation_loader.rb
|
110
107
|
- lib/annotation_security/manager/resource_manager.rb
|
111
108
|
- lib/annotation_security/manager/right_loader.rb
|
112
|
-
- lib/annotation_security/model_observer.rb
|
113
109
|
- lib/annotation_security/policy/abstract_policy.rb
|
114
110
|
- lib/annotation_security/policy/abstract_static_policy.rb
|
115
111
|
- lib/annotation_security/policy/all_resources_policy.rb
|
116
112
|
- lib/annotation_security/policy/rule.rb
|
117
113
|
- lib/annotation_security/policy/rule_set.rb
|
114
|
+
- lib/annotation_security/rails/2/extensions/filter.rb
|
115
|
+
- lib/annotation_security/rails/2/includes/action_controller.rb
|
116
|
+
- lib/annotation_security/rails/2/includes/active_record.rb
|
117
|
+
- lib/annotation_security/rails/2/initializer.rb
|
118
|
+
- lib/annotation_security/rails/2/model_observer.rb
|
119
|
+
- lib/annotation_security/rails/3/extensions/filter.rb
|
120
|
+
- lib/annotation_security/rails/3/includes/action_controller.rb
|
121
|
+
- lib/annotation_security/rails/3/includes/active_record.rb
|
122
|
+
- lib/annotation_security/rails/3/initializer.rb
|
123
|
+
- lib/annotation_security/rails/3/model_observer.rb
|
124
|
+
- lib/annotation_security/rails/extensions/action_controller.rb
|
125
|
+
- lib/annotation_security/rails/extensions/active_record.rb
|
126
|
+
- lib/annotation_security/rails/extensions/object.rb
|
127
|
+
- lib/annotation_security/rails/extensions.rb
|
128
|
+
- lib/annotation_security/rails/filters.rb
|
118
129
|
- lib/annotation_security/rails.rb
|
119
130
|
- lib/annotation_security/user_wrapper.rb
|
120
131
|
- lib/annotation_security/utils.rb
|
121
|
-
- lib/annotation_security/version.rb
|
122
132
|
- lib/annotation_security.rb
|
123
|
-
- lib/extensions/action_controller.rb
|
124
|
-
- lib/extensions/active_record.rb
|
125
|
-
- lib/extensions/filter.rb
|
126
|
-
- lib/extensions/object.rb
|
127
133
|
- lib/security_context.rb
|
128
134
|
- spec/annotation_security/exceptions_spec.rb
|
129
135
|
- spec/annotation_security/includes/helper_spec.rb
|
@@ -151,29 +157,37 @@ files:
|
|
151
157
|
- assets/config/security/relations.rb
|
152
158
|
- assets/config/security/rights.yml
|
153
159
|
- assets/vendor/plugins/annotation_security/init.rb
|
154
|
-
|
160
|
+
has_rdoc: true
|
161
|
+
homepage: http://tech.lefedt.de/2010/3/annotation-based-security-for-rails
|
155
162
|
licenses: []
|
163
|
+
|
156
164
|
post_install_message:
|
157
165
|
rdoc_options: []
|
158
|
-
|
166
|
+
|
167
|
+
require_paths:
|
159
168
|
- lib
|
160
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
170
|
none: false
|
162
|
-
requirements:
|
163
|
-
- -
|
164
|
-
- !ruby/object:Gem::Version
|
165
|
-
|
166
|
-
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
segments:
|
175
|
+
- 0
|
176
|
+
version: "0"
|
177
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
178
|
none: false
|
168
|
-
requirements:
|
169
|
-
- -
|
170
|
-
- !ruby/object:Gem::Version
|
171
|
-
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
segments:
|
183
|
+
- 0
|
184
|
+
version: "0"
|
172
185
|
requirements: []
|
186
|
+
|
173
187
|
rubyforge_project:
|
174
|
-
rubygems_version: 1.
|
188
|
+
rubygems_version: 1.3.7
|
175
189
|
signing_key:
|
176
190
|
specification_version: 3
|
177
|
-
summary: A role based security model for rails applications with descriptive definitions
|
178
|
-
and automated evaluation.
|
191
|
+
summary: A role based security model for rails applications with descriptive definitions and automated evaluation.
|
179
192
|
test_files: []
|
193
|
+
|
data/CHANGELOG.md
DELETED
data/HOW-TO.md
DELETED
@@ -1,275 +0,0 @@
|
|
1
|
-
# How to secure your Rails application with Annotation Security
|
2
|
-
|
3
|
-
## Step 0: Install Annotation Security
|
4
|
-
|
5
|
-
Annotation Security comes as a gem hosted on rubygems.org. You can install it
|
6
|
-
via `gem install annotation_security`.
|
7
|
-
The gem contains a binary called `annotation_security`. It can be used to
|
8
|
-
install the security layer into a rails app via
|
9
|
-
`annotation_security --rails RAILS_HOME`. This will make your app ready to be
|
10
|
-
secured.
|
11
|
-
|
12
|
-
### Version Notes
|
13
|
-
|
14
|
-
Use the gem version < 2 for Rails 2.3.x applications.
|
15
|
-
Use the gem version 3.x for Rails 3.x applications.
|
16
|
-
|
17
|
-
## Step 1: Defining user and roles
|
18
|
-
|
19
|
-
Annotation Security assumes that there is a user class, representing the user,
|
20
|
-
and some role classes containing additional information if the user has a
|
21
|
-
certain role in the application.
|
22
|
-
|
23
|
-
If you don't have user or role classes in your application,
|
24
|
-
continue with step 2.
|
25
|
-
|
26
|
-
### User
|
27
|
-
|
28
|
-
In most cases the user class will be a subclass of `ActiveRecord::Base`,
|
29
|
-
but this is not necessary.
|
30
|
-
|
31
|
-
Include the `module AnnotationSecurity::User` into this class.
|
32
|
-
|
33
|
-
class User < ActiveRecord::Base
|
34
|
-
include AnnotationSecurity::User
|
35
|
-
...
|
36
|
-
|
37
|
-
### Roles
|
38
|
-
|
39
|
-
Include the module `AnnotationSecurity::Role` into these classes. If you are
|
40
|
-
having a hierachy of role classes, only include the module in the topmost class.
|
41
|
-
|
42
|
-
class Role < ActiveRecord::Base
|
43
|
-
belongs_to :user
|
44
|
-
include AnnotationSecurity::Role
|
45
|
-
...
|
46
|
-
|
47
|
-
class Student < Role
|
48
|
-
# no include here
|
49
|
-
...
|
50
|
-
|
51
|
-
A role object should respond to `user` with returning the user object
|
52
|
-
it belongs to.
|
53
|
-
|
54
|
-
__Do not include both modules in one class!__
|
55
|
-
|
56
|
-
### Connecting user and roles
|
57
|
-
|
58
|
-
As next, you should provide some default methods for accessing the roles
|
59
|
-
of a user. You can skip this step, but it will be helpfull later on.
|
60
|
-
|
61
|
-
There are two types of access methods: `is_ROLE?` and `as_ROLE`.
|
62
|
-
|
63
|
-
IS-methods return true or false whether a user has a role or not.
|
64
|
-
|
65
|
-
class User < ActiveRecord::Base
|
66
|
-
def is_administrator?
|
67
|
-
self.admin_flag == 1
|
68
|
-
end
|
69
|
-
|
70
|
-
def is_student?
|
71
|
-
self.roles.any? { |role| role.is_a? Student }
|
72
|
-
end
|
73
|
-
...
|
74
|
-
|
75
|
-
AS-methods return a single object or an array of objects representing the role.
|
76
|
-
If the user does not have the role, the result should be an empty array or nil.
|
77
|
-
|
78
|
-
class User < ActiveRecord::Base
|
79
|
-
def as_administrator
|
80
|
-
# there is no administrator class, just return the user
|
81
|
-
is_administrator? ? self : nil
|
82
|
-
end
|
83
|
-
|
84
|
-
def as_student
|
85
|
-
# assuming a user can only be student once
|
86
|
-
self.roles.detect { |role| role.is_a? Student }
|
87
|
-
end
|
88
|
-
|
89
|
-
def as_corrector
|
90
|
-
# assuming a user can be a corrector several times
|
91
|
-
self.roles.select { |role| role.is_a? Corrector }
|
92
|
-
end
|
93
|
-
|
94
|
-
## Step 2: Providing the current credential
|
95
|
-
|
96
|
-
To evaluate the security policies, for each request the current credential has
|
97
|
-
to be provided. Therefore, a new filter type was introduced: security filters
|
98
|
-
are around filters that are always the first in the filter chain. You can also
|
99
|
-
use these filters to react to security violations.
|
100
|
-
|
101
|
-
In this example, the user is simply fetched from the session. However, you
|
102
|
-
could also pass a symbol or a string (e.g. if you are using API-keys).
|
103
|
-
|
104
|
-
Passing `nil` will be interpreted as not being authenticated in any way.
|
105
|
-
|
106
|
-
class ApplicationController < ActionController::Base
|
107
|
-
|
108
|
-
security_filter :security_filter
|
109
|
-
|
110
|
-
private
|
111
|
-
|
112
|
-
def security_filter
|
113
|
-
SecurityContext.current_credential = session[:user]
|
114
|
-
yield
|
115
|
-
rescue SecurityViolationError
|
116
|
-
if SecurityContext.is? :logged_in
|
117
|
-
render :template => "welcome/not_allowed"
|
118
|
-
else
|
119
|
-
render :template => "welcome/please_login"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
Please notice that once set, the credential cannot be changed.
|
124
|
-
|
125
|
-
## Step 3: Defining your resources
|
126
|
-
|
127
|
-
Another wild assumption we made is that your application contains some resources
|
128
|
-
you want to protect. In most cases, this will be your ActiveRecord classes.
|
129
|
-
To turn them into resources, just call `resource(symbol)` in the class
|
130
|
-
definition.
|
131
|
-
|
132
|
-
class Course < ActiveRecord::Base
|
133
|
-
resource :course
|
134
|
-
...
|
135
|
-
|
136
|
-
The symbol is used to further identify this class and should be unique.
|
137
|
-
|
138
|
-
It is possible (and likely) that the users and roles are resources as well.
|
139
|
-
|
140
|
-
If you want to restrict access to other resource classes, see
|
141
|
-
`AnnotationSecurity::Resource` for more information.
|
142
|
-
|
143
|
-
## Step 4: Defining relations and rights
|
144
|
-
|
145
|
-
in `config/security` you will find the files `relations.rb` and
|
146
|
-
`rights.yml`.
|
147
|
-
|
148
|
-
### Relations
|
149
|
-
|
150
|
-
The relations between the user (or the roles) and the resources are defined
|
151
|
-
as code blocks, that evaluate to true or false.
|
152
|
-
|
153
|
-
The `:as`-flag causes that instead of the user object, a role object
|
154
|
-
will be passed into the block (using the `as_ROLE`-method from above).
|
155
|
-
Similar, the `:is`-flag can be used as precondition.
|
156
|
-
|
157
|
-
AnnotationSecurity.define_relations do
|
158
|
-
resource :course do
|
159
|
-
enrolled :as => :student { |student,course| course.students.include? student }
|
160
|
-
corrector :as => :corrector { |corrector,course| corrector.corrects? course }
|
161
|
-
lecturer :as => :lecturer { |lecturer,course| lecturer.lectures? course }
|
162
|
-
end
|
163
|
-
...
|
164
|
-
|
165
|
-
You can also define relations that are valid for all resources.
|
166
|
-
|
167
|
-
all_resources do
|
168
|
-
# corrector and lecturer are defined by the resource
|
169
|
-
responsible { corrector or lecturer }
|
170
|
-
# no block required here
|
171
|
-
administrator :is => :administrator
|
172
|
-
end
|
173
|
-
|
174
|
-
For more details and features on defining relations,
|
175
|
-
see `AnnotationSecurity::RelationLoader`.
|
176
|
-
|
177
|
-
### Rights
|
178
|
-
|
179
|
-
The rights of application are specified in a YAML-file, they correspond to the
|
180
|
-
actions(not necessarily the controller actions) that can be performed on a
|
181
|
-
resource. For instance, to edit a course object, you will need the edit-right
|
182
|
-
for the course resource. If you are not sure which rights your application
|
183
|
-
needs, just skip this now and return after step 5.
|
184
|
-
|
185
|
-
Rights should be valid ruby conditional statements.
|
186
|
-
|
187
|
-
course:
|
188
|
-
create: if lecturer
|
189
|
-
show: if enrolled or responsible
|
190
|
-
edit: if responsible
|
191
|
-
|
192
|
-
AnnotationSecurity provides two default relations: `logged_in`, that is true
|
193
|
-
if there is a user at all, and +self+, that can be used to determine if a user
|
194
|
-
or role resource belongs to the current user.
|
195
|
-
|
196
|
-
user:
|
197
|
-
register: unless logged_in
|
198
|
-
show: if logged_in
|
199
|
-
edit: if self or administrator
|
200
|
-
student:
|
201
|
-
show_results: if self
|
202
|
-
|
203
|
-
To improve readability, you can append 'may', 'is', 'can' or 'has' as prefix and
|
204
|
-
'for', 'in', 'of' or 'to' as suffix to the relation name.
|
205
|
-
This is especially recommended if you are defining rights that depend on
|
206
|
-
other rights of the resource.
|
207
|
-
|
208
|
-
assignment:
|
209
|
-
edit: if responsible
|
210
|
-
delete: if may_edit
|
211
|
-
|
212
|
-
Another example can be found at `AnnotationSecurity::RightLoader`.
|
213
|
-
|
214
|
-
## Step 5: Securing your actions
|
215
|
-
|
216
|
-
The main goal of AnnotationSecurity was to remove security logic from
|
217
|
-
controller actions. Now you only have to define the abstract effects of an
|
218
|
-
action.
|
219
|
-
|
220
|
-
An action performs one or more tasks on different resources. You have to provide
|
221
|
-
this information as a descriptions, using the
|
222
|
-
[Action Annotation Gem](http://github.com/Nikku/action_annotation).
|
223
|
-
A description always has the form 'ACTION on RESOURCE'.
|
224
|
-
|
225
|
-
desc 'shows a course'
|
226
|
-
def show
|
227
|
-
@course = Course.find(params[:id])
|
228
|
-
end
|
229
|
-
|
230
|
-
To perform a task, the user must have the right for it. Thus, when a course is
|
231
|
-
fetched from the database during the show-action, the right course/show will be
|
232
|
-
evaluated for the current user and the course instance.
|
233
|
-
|
234
|
-
In our example, the user has to be responsible or enrolled. If both relations
|
235
|
-
evaluate to false, the right is not given and access will be denied by raising
|
236
|
-
a SecurityViolationError, which will then be catched in the security filter.
|
237
|
-
|
238
|
-
Congratulations, you Rails application is secured now.
|
239
|
-
|
240
|
-
## Step 6: Securing your views
|
241
|
-
|
242
|
-
However, actions aren't the only place with security code. Links to the actions
|
243
|
-
are shown in the view and very often, the view itself depends on the
|
244
|
-
user's rights.
|
245
|
-
|
246
|
-
When setting up Annotation Security in your Rails project, a helper will be
|
247
|
-
included automatically. The most important functions this helper provides are
|
248
|
-
`allowed?` and `link_to_if_allowed`.
|
249
|
-
|
250
|
-
The method `allowed?` expects a right and a resource and returns true iif
|
251
|
-
the current user has that right.
|
252
|
-
|
253
|
-
<% unless allowed? :edit, @course %>
|
254
|
-
<p>You may not edit this course!</p>
|
255
|
-
<% end %>
|
256
|
-
|
257
|
-
`link_to_if_allowed` expects the same arguments as +link_to+, except it also
|
258
|
-
expects a block like +link_to_if+ (which will be called internally).
|
259
|
-
|
260
|
-
<%= link_to_if_allowed("New", new_course_path) { "You may not create a new course." } %>
|
261
|
-
<%= link_to_if_allowed("Edit", edit_course_path(@course)) { } %>
|
262
|
-
<%= link_to_if_allowed("Delete", @course, {:method => :delete}) { } %>
|
263
|
-
|
264
|
-
`link_to_if_allowed` tries to automatically detect the accessed resources.
|
265
|
-
In case this should not work for you, see `AnnotationSecurity::Helper` for more
|
266
|
-
features.
|
267
|
-
|
268
|
-
## Step 7: Live long and prosper
|
269
|
-
|
270
|
-
Well, that's it. Here are some additional notes:
|
271
|
-
|
272
|
-
* in development mode, the rights and relations are reloaded with every request.
|
273
|
-
* See `AnnotationSecurity::RelationLoader` and `AnnotationSecurity::RightLoader`
|
274
|
-
for more examples and features for defining relations and rights.
|
275
|
-
* See `AnnotationSecurity::Helper` for more methods for securing your views.
|