access_schema 0.4.0 → 0.5.0
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/.gitignore +1 -0
- data/Gemfile +1 -0
- data/README.md +150 -100
- data/lib/access_schema/builders/asserts_builder.rb +1 -1
- data/lib/access_schema/builders/privilege_builder.rb +1 -1
- data/lib/access_schema/builders/resource_builder.rb +1 -1
- data/lib/access_schema/builders/roles_builder.rb +1 -1
- data/lib/access_schema/builders/schema_builder.rb +1 -1
- data/lib/access_schema/exceptions.rb +1 -1
- data/lib/access_schema/expectation.rb +1 -1
- data/lib/access_schema/privilege.rb +5 -1
- data/lib/access_schema/proxy.rb +2 -7
- data/lib/access_schema/schema.rb +34 -17
- data/lib/access_schema/version.rb +1 -1
- data/spec/access_schema/proxy_spec.rb +3 -3
- data/spec/access_schema/schema_builder_spec.rb +5 -8
- data/spec/access_schema/schema_spec.rb +67 -7
- data/spec/schema_example.rb +10 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/support/review.rb +3 -0
- metadata +6 -4
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
# AccessSchema gem - ACL
|
1
|
+
# AccessSchema gem - ACL and domain policies for your app
|
2
2
|
|
3
|
-
AccessSchema
|
4
|
-
to define ACL schemas with realy simple DSL.
|
3
|
+
AccessSchema is tool to add ACL and domain policy rules to an application. It is framework/ORM agnostic and provides declarative DSL.
|
5
4
|
|
6
5
|
Inspired by [ya_acl](https://github.com/kaize/ya_acl)
|
7
6
|
|
@@ -9,104 +8,23 @@ Inspired by [ya_acl](https://github.com/kaize/ya_acl)
|
|
9
8
|
gem install access_schema
|
10
9
|
```
|
11
10
|
|
12
|
-
## An example of use
|
13
|
-
|
14
|
-
|
15
|
-
### Accessing from application code
|
16
|
-
|
17
|
-
In Rails controllers we usualy have a current_user and we can
|
18
|
-
add some default options in helpers:
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
#access_schema_helper.rb
|
22
|
-
|
23
|
-
class AccessSchemaHelper
|
24
|
-
|
25
|
-
def role
|
26
|
-
AccessSchema.schema(:plans).with_options({
|
27
|
-
:role => Rails.development? && params[:debug_role] || current_user.try(:role) || :none
|
28
|
-
})
|
29
|
-
end
|
30
|
-
|
31
|
-
def acl
|
32
|
-
AccessSchema.schema(:acl).with_options({
|
33
|
-
:role => current_user.try(:role) || :none,
|
34
|
-
:user_id => current_user.try(:id)
|
35
|
-
})
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
```
|
41
|
-
|
42
|
-
So at may be used in controllers:
|
43
|
-
|
44
|
-
```ruby
|
45
|
-
acl.require! review, :edit
|
46
|
-
role.require! review, :mark_privileged
|
47
|
-
|
48
|
-
```
|
49
|
-
|
50
|
-
Or views:
|
51
|
-
|
52
|
-
```ruby
|
53
|
-
- if role.allow? review, :add_photo
|
54
|
-
= render :partial => "add_photo"
|
55
|
-
```
|
56
|
-
|
57
|
-
|
58
|
-
On the ather side there are no any current_user accessible. In a Service Layer for
|
59
|
-
example. So we have to pass extra options:
|
60
|
-
|
61
|
-
|
62
|
-
```ruby
|
63
|
-
#./app/services/review_service.rb
|
64
|
-
|
65
|
-
class ReviewService < BaseSevice
|
66
|
-
|
67
|
-
def mark_privileged(review_id, options)
|
68
|
-
|
69
|
-
review = Review.find(review_id)
|
70
|
-
|
71
|
-
acl = AccessSchema.schema(:acl).with_options(:roles => options[:actor].roles)
|
72
|
-
acl.require! review, :mark_privileged
|
73
|
-
|
74
|
-
plans = AccessSchema.schema(:plans).with_options(:plans => options[:actor].plans)
|
75
|
-
plans.require! review, :mark_privileged
|
76
|
-
|
77
|
-
review.privileged = true
|
78
|
-
review.save!
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
def update(review_id, attrs)
|
83
|
-
|
84
|
-
review = Review.find(review_id)
|
85
|
-
|
86
|
-
acl = AccessSchema.schema(:acl).with_options(:roles => options[:actor].roles)
|
87
|
-
acl.require! review, :edit
|
88
|
-
|
89
|
-
plans = AccessSchema.schema(:plan).with_options(:plan => options[:actor].plan)
|
90
|
-
plans.require! review, :edit, :new_attrs => attrs
|
91
|
-
|
92
|
-
review.update_attributes(attrs)
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
```
|
11
|
+
## An example of use with Rails
|
99
12
|
|
100
13
|
### Definition
|
101
14
|
|
102
15
|
```ruby
|
103
|
-
# config/
|
16
|
+
# config/policy.rb
|
104
17
|
|
105
18
|
roles do
|
19
|
+
|
20
|
+
# Tariff plans
|
106
21
|
role :none
|
107
22
|
role :bulb
|
108
23
|
role :flower
|
109
24
|
role :bouquet
|
25
|
+
|
26
|
+
# To allow admin violate tariff plan rules
|
27
|
+
role :admin
|
110
28
|
end
|
111
29
|
|
112
30
|
asserts do
|
@@ -123,9 +41,10 @@ example. So we have to pass extra options:
|
|
123
41
|
|
124
42
|
resource "Review" do
|
125
43
|
|
126
|
-
privilege :
|
44
|
+
privilege :mark_featured, [:flower, :bouquet]
|
127
45
|
|
128
|
-
|
46
|
+
# Admin is able to add over limit
|
47
|
+
privilege :add_photo, [:bouquet, :admin] do
|
129
48
|
assert :photo_limit, [:none], :limit => 1
|
130
49
|
assert :photo_limit, [:bulb], :limit => 5
|
131
50
|
assert :photo_limit, [:flower], :limit => 10
|
@@ -154,27 +73,30 @@ example. So we have to pass extra options:
|
|
154
73
|
|
155
74
|
end
|
156
75
|
|
157
|
-
resource "
|
76
|
+
resource "ReviewsController" do
|
77
|
+
|
78
|
+
privilege :index
|
79
|
+
privilege :show
|
158
80
|
|
159
81
|
privilege :edit, [:admin] do
|
160
82
|
assert :owner, [:none]
|
161
83
|
end
|
162
84
|
|
85
|
+
privilege :update, [:admin] do
|
86
|
+
assert :owner, [:none]
|
87
|
+
end
|
88
|
+
|
163
89
|
end
|
164
90
|
```
|
165
91
|
|
166
|
-
|
167
|
-
|
168
|
-
Configured schema can be accessed with AccessSchema.schema(name)
|
169
|
-
anywhere in app. Alternatively it can be assempled with ServiceLocator.
|
170
|
-
|
92
|
+
### Configuration
|
171
93
|
|
172
94
|
```ruby
|
173
95
|
#config/initializers/access_schema.rb
|
174
96
|
|
175
97
|
AccessSchema.configure do
|
176
98
|
|
177
|
-
schema :
|
99
|
+
schema :policy, AccessSchema.build_file('config/policy.rb')
|
178
100
|
schema :acl, AccessSchema.build_file('config/acl.rb')
|
179
101
|
|
180
102
|
logger Rails.logger
|
@@ -183,4 +105,132 @@ anywhere in app. Alternatively it can be assempled with ServiceLocator.
|
|
183
105
|
|
184
106
|
```
|
185
107
|
|
108
|
+
### Accessing from Rails application code
|
109
|
+
|
110
|
+
Define a helper:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
#access_schema_helper.rb
|
114
|
+
|
115
|
+
class AccessSchemaHelper
|
116
|
+
|
117
|
+
# Use ACL in controllers:
|
118
|
+
#
|
119
|
+
# before_filter { required! :reviews, :delete }
|
120
|
+
#
|
121
|
+
# and views
|
122
|
+
#
|
123
|
+
# - if can? :reviews, :delete, :subject => review
|
124
|
+
# = link_to "Delete", review_path(review)
|
125
|
+
#
|
126
|
+
|
127
|
+
def required!(route_method, action = nil, options = {})
|
128
|
+
|
129
|
+
url_options = send "hash_for_#{route_method}_path"
|
130
|
+
resource = "#{url_options[:controller].to_s.camelize}Controller"
|
131
|
+
|
132
|
+
privilege = action || url_options[:action]
|
133
|
+
acl.require! resource, privilege, options
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
def can?(*args)
|
138
|
+
required!(*args)
|
139
|
+
rescue AccessSchema::NotAllowed => e
|
140
|
+
false
|
141
|
+
else
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
def acl
|
146
|
+
|
147
|
+
AccessSchema.schema(:acl).with_options({
|
148
|
+
roles: current_roles,
|
149
|
+
user_id: current_user.try(:id)
|
150
|
+
})
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
# Use in controllers and views
|
155
|
+
# tarifF plans or other domain logic policies
|
156
|
+
#
|
157
|
+
# policy.allow? review, :add_photo
|
158
|
+
#
|
159
|
+
|
160
|
+
|
161
|
+
def policy
|
162
|
+
|
163
|
+
# Policy have to check actor roles and subject owner state (tariff plans for example)
|
164
|
+
# to evaluate permission. So we pass proc and deal with particular subject to
|
165
|
+
# calculate roles.
|
166
|
+
#
|
167
|
+
roles_calculator = proc do |options|
|
168
|
+
|
169
|
+
plan = options[:subject].try(:owner).try(:plan)
|
170
|
+
plan ||= [ current_user.try(:plan) || :none ]
|
171
|
+
current_roles | plan
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
AccessSchema.schema(:policy).with_options({
|
176
|
+
roles: roles_calculator,
|
177
|
+
user_id: current_user.try(:id)
|
178
|
+
})
|
179
|
+
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
```
|
185
|
+
|
186
|
+
But there are no current_user method in a Service Layer! So pass an extra option - actor:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
#./app/services/base_service.rb
|
190
|
+
class BaseService
|
191
|
+
|
192
|
+
def policy(actor)
|
193
|
+
|
194
|
+
roles_calculator = proc do |options|
|
195
|
+
|
196
|
+
plan = options[:subject].try(:owner).try(:plan)
|
197
|
+
plan ||= [ actor.try(:plan) || :none ]
|
198
|
+
current_roles | plan
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
AccessSchema.schema(:policy).with_options({
|
203
|
+
roles: roles_calculator,
|
204
|
+
user_id: actor.try(:id)
|
205
|
+
})
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
#./app/services/review_service.rb
|
211
|
+
|
212
|
+
class ReviewService < BaseSevice
|
213
|
+
|
214
|
+
def mark_featured(review_id, actor)
|
215
|
+
|
216
|
+
review = Review.find(review_id)
|
217
|
+
policy(actor).require! review, :mark_featured
|
218
|
+
|
219
|
+
review.featured = true
|
220
|
+
review.save!
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
def update(review_id, attrs, actor)
|
225
|
+
|
226
|
+
review = Review.find(review_id)
|
227
|
+
policy(actor).require! review, :edit, :attrs => attrs
|
228
|
+
|
229
|
+
review.update_attributes(attrs)
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
```
|
186
236
|
|
@@ -2,7 +2,7 @@ module AccessSchema
|
|
2
2
|
class PrivilegeBuilder < BasicBuilder
|
3
3
|
|
4
4
|
def assert(name, roles = [], options = {})
|
5
|
-
expectation = Expectation.new(name.
|
5
|
+
expectation = Expectation.new(name.to_s, roles.map(&:to_s), options)
|
6
6
|
schema.add_expectation(expectation)
|
7
7
|
end
|
8
8
|
|
@@ -2,7 +2,7 @@ module AccessSchema
|
|
2
2
|
class ResourceBuilder < BasicBuilder
|
3
3
|
|
4
4
|
def privilege(name, roles = [], &block)
|
5
|
-
privilege = Privilege.new(name.
|
5
|
+
privilege = Privilege.new(name.to_s, roles.map(&:to_s))
|
6
6
|
if block_given?
|
7
7
|
builder = PrivilegeBuilder.new(privilege)
|
8
8
|
builder.instance_eval(&block)
|
@@ -16,7 +16,11 @@ module AccessSchema
|
|
16
16
|
def allow?(roles)
|
17
17
|
(@roles & roles).size > 0 || begin
|
18
18
|
checklist = @expectations.select { |exp| exp.for?(roles) }
|
19
|
-
checklist.length > 0
|
19
|
+
if checklist.length > 0
|
20
|
+
checklist.all? { |exp| yield(exp) }
|
21
|
+
else
|
22
|
+
@roles.empty?
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/lib/access_schema/proxy.rb
CHANGED
@@ -10,10 +10,6 @@ module AccessSchema
|
|
10
10
|
@schema.roles
|
11
11
|
end
|
12
12
|
|
13
|
-
def plans
|
14
|
-
@schema.plans
|
15
|
-
end
|
16
|
-
|
17
13
|
def allow?(*args)
|
18
14
|
@schema.allow?(*normalize_args(args))
|
19
15
|
end
|
@@ -34,14 +30,13 @@ module AccessSchema
|
|
34
30
|
|
35
31
|
roles, options = case args[2]
|
36
32
|
when Hash, nil
|
37
|
-
[@options[:
|
33
|
+
[@options[:roles], args[2] || {}]
|
38
34
|
else
|
39
35
|
[args[2], args[3] || {}]
|
40
36
|
end
|
41
37
|
|
42
38
|
options_to_pass = @options.dup
|
43
|
-
options_to_pass.delete :
|
44
|
-
options_to_pass.delete :role
|
39
|
+
options_to_pass.delete :roles
|
45
40
|
|
46
41
|
[resource, privilege, roles, options_to_pass.merge(options)]
|
47
42
|
end
|
data/lib/access_schema/schema.rb
CHANGED
@@ -2,7 +2,6 @@ module AccessSchema
|
|
2
2
|
class Schema
|
3
3
|
|
4
4
|
attr_reader :roles
|
5
|
-
alias :plans :roles
|
6
5
|
|
7
6
|
def initialize
|
8
7
|
@roles = []
|
@@ -39,27 +38,47 @@ module AccessSchema
|
|
39
38
|
def normalize_args(args)
|
40
39
|
|
41
40
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
42
|
-
privilege = args[1].
|
43
|
-
|
41
|
+
privilege = args[1].to_s
|
44
42
|
roles = args[2]
|
45
|
-
roles = roles.respond_to?(:map) ? roles.map(&:to_sym) : [roles && roles.to_sym]
|
46
|
-
|
47
|
-
raise NoRoleError.new if (self.roles & roles).empty?
|
48
|
-
|
49
|
-
roles = normalize_roles_order(roles)
|
50
43
|
|
51
44
|
case args[0]
|
52
45
|
when String, Symbol
|
53
|
-
resource = args[0].
|
54
|
-
[resource, privilege, roles, options]
|
46
|
+
resource = args[0].to_s
|
55
47
|
else
|
56
|
-
resource = args[0].class.name.
|
57
|
-
|
48
|
+
resource = args[0].class.name.to_s
|
49
|
+
options.merge!(:subject => args[0])
|
50
|
+
end
|
51
|
+
|
52
|
+
roles = calculate_roles(roles, options)
|
53
|
+
|
54
|
+
if (self.roles & roles).empty?
|
55
|
+
raise InvalidRolesError.new(:roles => roles)
|
56
|
+
end
|
57
|
+
|
58
|
+
roles = sort_roles(roles)
|
59
|
+
|
60
|
+
[resource, privilege, roles, options]
|
61
|
+
end
|
62
|
+
|
63
|
+
def calculate_roles(roles, check_options)
|
64
|
+
|
65
|
+
roles = if roles.respond_to?(:call)
|
66
|
+
roles.call(check_options.dup)
|
67
|
+
elsif !roles.respond_to?(:map)
|
68
|
+
[ roles ]
|
69
|
+
else
|
70
|
+
roles
|
71
|
+
end
|
72
|
+
|
73
|
+
unless roles.respond_to?(:map)
|
74
|
+
raise InvalidRolesError.new(:result => roles)
|
58
75
|
end
|
59
76
|
|
77
|
+
roles.map(&:to_s)
|
78
|
+
|
60
79
|
end
|
61
80
|
|
62
|
-
def
|
81
|
+
def sort_roles(roles)
|
63
82
|
@roles.select do |role|
|
64
83
|
roles.include? role
|
65
84
|
end
|
@@ -67,8 +86,8 @@ module AccessSchema
|
|
67
86
|
|
68
87
|
def check!(resource_name, privilege_name, roles, options)
|
69
88
|
|
70
|
-
resouce_name = resource_name.
|
71
|
-
privilege_name = privilege_name.
|
89
|
+
resouce_name = resource_name.to_s
|
90
|
+
privilege_name = privilege_name.to_s
|
72
91
|
|
73
92
|
resource = @resources[resource_name]
|
74
93
|
|
@@ -110,8 +129,6 @@ module AccessSchema
|
|
110
129
|
|
111
130
|
end
|
112
131
|
|
113
|
-
private
|
114
|
-
|
115
132
|
def logger
|
116
133
|
AccessSchema.config.logger
|
117
134
|
end
|
@@ -13,14 +13,14 @@ describe AccessSchema::Proxy do
|
|
13
13
|
describe "#with_options" do
|
14
14
|
|
15
15
|
before do
|
16
|
-
@schema = @proxy.with_options(:
|
16
|
+
@schema = @proxy.with_options(:roles => [:flower], :user_id => 1)
|
17
17
|
end
|
18
18
|
|
19
|
-
it "allows to not specify
|
19
|
+
it "allows to not specify roles for schema calls" do
|
20
20
|
@schema.allow?("Review", :mark_featured).should be_true
|
21
21
|
end
|
22
22
|
|
23
|
-
it "but it accepts
|
23
|
+
it "but it accepts roles too" do
|
24
24
|
@schema.allow?("Review", :mark_featured, :flower).should be_true
|
25
25
|
@schema.allow?("Review", :mark_featured, :none).should be_false
|
26
26
|
end
|
@@ -25,9 +25,6 @@ describe AccessSchema::SchemaBuilder do
|
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
class Review; end
|
30
|
-
|
31
28
|
describe AccessSchema::SchemaBuilder, "produced schema example" do
|
32
29
|
|
33
30
|
before do
|
@@ -37,10 +34,10 @@ describe AccessSchema::SchemaBuilder, "produced schema example" do
|
|
37
34
|
end
|
38
35
|
|
39
36
|
it "creates roles" do
|
40
|
-
@schema.roles.should
|
37
|
+
@schema.roles.should ==%w(none bulb flower bouquet admin user)
|
41
38
|
end
|
42
39
|
|
43
|
-
context "when checking against
|
40
|
+
context "when checking against role 'none'" do
|
44
41
|
|
45
42
|
it "does not allows to mark featured" do
|
46
43
|
@schema.allow?(@review, :mark_featured, :none).should be_false
|
@@ -58,7 +55,7 @@ describe AccessSchema::SchemaBuilder, "produced schema example" do
|
|
58
55
|
|
59
56
|
end
|
60
57
|
|
61
|
-
context "when checking against
|
58
|
+
context "when checking against role 'bulb'" do
|
62
59
|
|
63
60
|
it "does not allow to mark featured" do
|
64
61
|
@schema.allow?(@review, :mark_featured, :bulb).should be_false
|
@@ -76,7 +73,7 @@ describe AccessSchema::SchemaBuilder, "produced schema example" do
|
|
76
73
|
|
77
74
|
end
|
78
75
|
|
79
|
-
context "when checking against
|
76
|
+
context "when checking against role 'flower'" do
|
80
77
|
|
81
78
|
it "allows to mark featured" do
|
82
79
|
@schema.allow?(@review, :mark_featured, :flower).should be_true
|
@@ -94,7 +91,7 @@ describe AccessSchema::SchemaBuilder, "produced schema example" do
|
|
94
91
|
|
95
92
|
end
|
96
93
|
|
97
|
-
context "when checking against
|
94
|
+
context "when checking against role 'bouquet'" do
|
98
95
|
|
99
96
|
it "allows to mark featured" do
|
100
97
|
@schema.allow?(@review, :mark_featured, :bouquet).should be_true
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe AccessSchema::Schema
|
3
|
+
describe AccessSchema::Schema do
|
4
4
|
|
5
5
|
before do
|
6
6
|
@schema = AccessSchema::SchemaBuilder.build_file('spec/schema_example.rb')
|
7
7
|
end
|
8
8
|
|
9
|
-
describe "#
|
9
|
+
describe "#add_role" do
|
10
10
|
|
11
11
|
it "raises error if duplicate"
|
12
12
|
|
@@ -21,7 +21,7 @@ describe AccessSchema::Schema, "errors rising" do
|
|
21
21
|
describe "#add_feature" do
|
22
22
|
|
23
23
|
it "raises error if duplicate"
|
24
|
-
it "raises error for invalid
|
24
|
+
it "raises error for invalid role"
|
25
25
|
it "raises error for invalid assert"
|
26
26
|
|
27
27
|
end
|
@@ -37,15 +37,24 @@ describe AccessSchema::Schema, "errors rising" do
|
|
37
37
|
it "raises exception on invalid role" do
|
38
38
|
lambda {
|
39
39
|
@schema.allow? "Review", :mark_featured, :invalid
|
40
|
-
}.should raise_error(AccessSchema::
|
40
|
+
}.should raise_error(AccessSchema::InvalidRolesError)
|
41
41
|
|
42
42
|
lambda {
|
43
43
|
@schema.allow? "Review", :mark_featured
|
44
|
-
}.should raise_error(AccessSchema::
|
44
|
+
}.should raise_error(AccessSchema::InvalidRolesError)
|
45
45
|
end
|
46
46
|
|
47
47
|
it "raises exception on invalid feature"
|
48
48
|
|
49
|
+
it "passes is no roles and asserts are specified in privilege definition" do
|
50
|
+
@schema.should be_allow("Review", :view, [:user])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "checks assert if no roles specified in assert definition" do
|
54
|
+
@schema.should be_allow("Review", :echo_privilege, [:user], :result => true)
|
55
|
+
@schema.should_not be_allow("Review", :echo_privilege, [:user], :result => false)
|
56
|
+
end
|
57
|
+
|
49
58
|
end
|
50
59
|
|
51
60
|
describe "privilege union for multiple roles" do
|
@@ -68,6 +77,57 @@ describe AccessSchema::Schema, "errors rising" do
|
|
68
77
|
|
69
78
|
end
|
70
79
|
|
80
|
+
describe "dynamic roles calculation" do
|
81
|
+
|
82
|
+
it "accepts proc as roles" do
|
83
|
+
|
84
|
+
lambda {
|
85
|
+
roles_calculator = proc { [:admin] }
|
86
|
+
@schema.allow? "Review", :update, roles_calculator
|
87
|
+
}.should_not raise_error
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
it "passes options hash with subject into proc" do
|
92
|
+
|
93
|
+
@passed_options = nil
|
94
|
+
roles_calculator = proc do |options|
|
95
|
+
@passed_options = options
|
96
|
+
[:admin]
|
97
|
+
end
|
98
|
+
subject = Review.new
|
99
|
+
@schema.allow? subject, :update, roles_calculator, :option1 => :value1
|
100
|
+
@passed_options.should be
|
101
|
+
@passed_options[:subject].should == subject
|
102
|
+
@passed_options[:option1].should == :value1
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
it "passes a copy of options hash" do
|
107
|
+
|
108
|
+
@passed_options = {:option1 => :value1}
|
109
|
+
roles_calculator = proc do |options|
|
110
|
+
options[:option1] = :changed_value
|
111
|
+
[:admin]
|
112
|
+
end
|
113
|
+
|
114
|
+
@schema.allow? "Review", :update, roles_calculator
|
115
|
+
|
116
|
+
@passed_options[:option1].should == :value1
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
it "raises error if none array returned from proc" do
|
121
|
+
|
122
|
+
lambda {
|
123
|
+
roles_calculator = proc { :admin }
|
124
|
+
@schema.allow? "Review", :update, roles_calculator
|
125
|
+
}.should raise_error(AccessSchema::InvalidRolesError)
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
71
131
|
describe "#require!" do
|
72
132
|
|
73
133
|
it "raises en error is feature is nt allowed"
|
@@ -84,13 +144,13 @@ describe AccessSchema::Schema, "errors rising" do
|
|
84
144
|
it "logs check arguments with debug level" do
|
85
145
|
@logger.log_only_level = "debug"
|
86
146
|
@schema.allow? "Review", :mark_featured, :flower
|
87
|
-
@logger.output.should == "AccessSchema: check PASSED: {:resource
|
147
|
+
@logger.output.should == "AccessSchema: check PASSED: {:resource=>\"Review\", :privilege=>\"mark_featured\", :roles=>[\"flower\"], :options=>{}}"
|
88
148
|
end
|
89
149
|
|
90
150
|
it "logs check fail with info level" do
|
91
151
|
@logger.log_only_level = "info"
|
92
152
|
@schema.allow? "Review", :mark_featured, :none
|
93
|
-
@logger.output.should == "AccessSchema: check FAILED: {:resource
|
153
|
+
@logger.output.should == "AccessSchema: check FAILED: {:resource=>\"Review\", :privilege=>\"mark_featured\", :roles=>[\"none\"], :options=>{}, :failed_asserts=>{}}"
|
94
154
|
end
|
95
155
|
end
|
96
156
|
|
data/spec/schema_example.rb
CHANGED
@@ -19,6 +19,10 @@ asserts do
|
|
19
19
|
false
|
20
20
|
end
|
21
21
|
|
22
|
+
assert :echo, [:result] do
|
23
|
+
result
|
24
|
+
end
|
25
|
+
|
22
26
|
end
|
23
27
|
|
24
28
|
resource "Review" do
|
@@ -35,4 +39,10 @@ resource "Review" do
|
|
35
39
|
assert :false, [:user]
|
36
40
|
end
|
37
41
|
|
42
|
+
privilege :view
|
43
|
+
|
44
|
+
privilege :echo_privilege do
|
45
|
+
assert :echo
|
46
|
+
end
|
47
|
+
|
38
48
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'rspec'
|
2
|
+
Dir[File.expand_path('../support/**/*', __FILE__)].each { |f| require f }
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
SimpleCov.start
|
7
|
+
|
2
8
|
require 'access_schema'
|
3
9
|
|
4
10
|
require 'access_schema/loggers/test_logger'
|
5
11
|
|
6
|
-
Dir[File.expand_path('../support/**/*', __FILE__)].each { |f| require f }
|
7
12
|
|
8
13
|
RSpec.configure do |config|
|
9
14
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: access_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-01 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: AccessSchema is a tool for ACL or tariff plans schema definition and
|
15
15
|
checks
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- spec/access_schema_spec.rb
|
56
56
|
- spec/schema_example.rb
|
57
57
|
- spec/spec_helper.rb
|
58
|
+
- spec/support/review.rb
|
58
59
|
homepage: ''
|
59
60
|
licenses: []
|
60
61
|
post_install_message:
|
@@ -69,7 +70,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
70
|
version: '0'
|
70
71
|
segments:
|
71
72
|
- 0
|
72
|
-
hash: -
|
73
|
+
hash: -4292309596279283833
|
73
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
75
|
none: false
|
75
76
|
requirements:
|
@@ -78,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
79
|
version: '0'
|
79
80
|
segments:
|
80
81
|
- 0
|
81
|
-
hash: -
|
82
|
+
hash: -4292309596279283833
|
82
83
|
requirements: []
|
83
84
|
rubyforge_project: access_schema
|
84
85
|
rubygems_version: 1.8.16
|
@@ -94,3 +95,4 @@ test_files:
|
|
94
95
|
- spec/access_schema_spec.rb
|
95
96
|
- spec/schema_example.rb
|
96
97
|
- spec/spec_helper.rb
|
98
|
+
- spec/support/review.rb
|