eaco 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Guardfile +10 -6
- data/README.md +1 -1
- data/eaco.gemspec +2 -1
- data/features/role_based_authorization.feature +14 -5
- data/features/step_definitions/actor_steps.rb +37 -0
- data/features/step_definitions/resource_steps.rb +40 -0
- data/lib/eaco/acl.rb +1 -0
- data/lib/eaco/actor.rb +1 -1
- data/lib/eaco/adapters/active_record/compatibility/v40.rb +1 -1
- data/lib/eaco/adapters/active_record/postgres_jsonb.rb +2 -2
- data/lib/eaco/controller.rb +6 -1
- data/lib/eaco/cucumber/active_record.rb +16 -12
- data/lib/eaco/designator.rb +1 -1
- data/lib/eaco/dsl/resource.rb +1 -1
- data/lib/eaco/rake/default_task.rb +7 -1
- data/lib/eaco/resource.rb +2 -2
- data/lib/eaco/version.rb +1 -1
- metadata +19 -5
- data/features/step_definitions/actor_definition.rb +0 -30
- data/features/step_definitions/resource_authorization.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d92e2ed7aceab41d46ba1f57fa2b75f9bb1b298
|
4
|
+
data.tar.gz: 32b88c52a4bf95262a6bd54524e60afa7ea802bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2212422e25d4927512160f445e0a25060bbc88bb95040ad99f6b747317a4c09f57f2e29822ab14bb5d9759ace82901b95f6d8abae52a88a7d6a8afab77c7533a
|
7
|
+
data.tar.gz: 99f977abda6d1d732b9b804264d4691f01372e86bb0845a232b9c5a3f1fb344742e6c8bbe6ffd3985cb55e94558fa526752fa4a34ff6b40dec0dd0d8b06f972d
|
data/Guardfile
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# Eaco's Guardfile
|
2
|
+
#
|
3
|
+
unless ENV['BUNDLE_GEMFILE'] =~ %r{gemfiles/rails}
|
4
|
+
abort 'specs and features require appraisal. Try `appraisal rails-4.2 guard`'
|
5
|
+
end
|
2
6
|
|
3
7
|
# Watch lib/ and spec/
|
4
|
-
directories %w(lib spec)
|
8
|
+
directories %w(lib spec features)
|
5
9
|
|
6
10
|
# Clear the screen before every task
|
7
11
|
clearing :on
|
8
12
|
|
9
|
-
guard :rspec, version: 3, cmd: 'rspec' do
|
13
|
+
guard :rspec, version: 3, cmd: 'bundle exec rspec' do
|
10
14
|
# When single specs change, run them.
|
11
15
|
watch(%r{^spec/.+_spec\.rb$})
|
12
16
|
|
@@ -28,7 +32,7 @@ guard :cucumber do
|
|
28
32
|
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
29
33
|
end
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
+
guard :shell do
|
36
|
+
# Rerun scenarios when source code changes
|
37
|
+
watch(%r{^lib/.+\.rb$}) { system 'cucumber' }
|
38
|
+
end
|
data/README.md
CHANGED
@@ -226,6 +226,6 @@ focus on a single release, use `appraisal rails-X.Y rake`, where `X.Y` can be
|
|
226
226
|
|
227
227
|
## Denominazione d'Origine Controllata
|
228
228
|
|
229
|
-
This software is Made in :
|
229
|
+
This software is Made in Italy :it: :smile:.
|
230
230
|
|
231
231
|
[eaco-e-telamone]: http://upload.wikimedia.org/wikipedia/commons/7/70/Aeacus_telemon.jpg "Aeacus telemon by user Ravenous at en.wikipedia.org - Public domain through Wikimedia Commons - http://commons.wikimedia.org/wiki/File:Aeacus_telemon.jpg#mediaviewer/File:Aeacus_telemon.jpg"
|
data/eaco.gemspec
CHANGED
@@ -21,7 +21,8 @@ Gem::Specification.new do |spec|
|
|
21
21
|
["bundler", "~> 1.6"],
|
22
22
|
"rake", "byebug", "guard", "yard", "appraisal",
|
23
23
|
"rspec", "guard-rspec", "yard-rspec",
|
24
|
-
"cucumber", "guard-cucumber", "coveralls"
|
24
|
+
"cucumber", "guard-cucumber", "coveralls",
|
25
|
+
"guard-shell"
|
25
26
|
|
26
27
|
].each {|gem| spec.add_development_dependency *gem }
|
27
28
|
end
|
@@ -26,8 +26,17 @@ Feature: Role-Based authorization
|
|
26
26
|
Given I have an actor named Bob
|
27
27
|
And I have an actor named Tom
|
28
28
|
|
29
|
-
Scenario:
|
30
|
-
|
31
|
-
And I grant Bob access as a reader in quality of user
|
32
|
-
Then Bob should be able to read
|
33
|
-
And Tom should not be able to read
|
29
|
+
Scenario: Discretionary access to a Resource
|
30
|
+
When I have a confidential Document named "Supa Dupa Fly"
|
31
|
+
And I grant Bob access to "Supa Dupa Fly" as a reader in quality of user
|
32
|
+
Then Bob should be able to read "Supa Dupa Fly"
|
33
|
+
And Tom should not be able to read "Supa Dupa Fly"
|
34
|
+
|
35
|
+
Scenario: Extraction of accessible Resources
|
36
|
+
When I have a confidential Document named "Strategic Plan"
|
37
|
+
And I grant Bob access to "Strategic Plan" as a reader in quality of user
|
38
|
+
And I have a confidential Document named "For Tom"
|
39
|
+
And I grant Tom access to "For Tom" as a reader in quality of user
|
40
|
+
And I have a confidential Document named "For no one"
|
41
|
+
Then Bob can see only "Strategic Plan" in the Document authorized list
|
42
|
+
And Tom can see only "For Tom" in the Document authorized list
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Given(/I have an (\w+) actor defined as/) do |model_name, author_definition|
|
2
|
+
@actor_model = find_model(model_name)
|
3
|
+
|
4
|
+
eval_dsl author_definition, @actor_model
|
5
|
+
end
|
6
|
+
|
7
|
+
Given(/I have an actor named (\w+)/) do |actor_name|
|
8
|
+
actor = @actor_model.new
|
9
|
+
actor.name = actor_name
|
10
|
+
actor.save!
|
11
|
+
|
12
|
+
@actors ||= {}
|
13
|
+
@actors[actor_name] = actor
|
14
|
+
end
|
15
|
+
|
16
|
+
When(/I grant (\w+) access to "(.+?)" as a (\w+) in quality of (\w+)/) do |actor_name, resource_name, role_name, designator|
|
17
|
+
actor = @actors.fetch(actor_name)
|
18
|
+
@resources[resource_name].grant role_name, designator, actor
|
19
|
+
@resources[resource_name].save!
|
20
|
+
end
|
21
|
+
|
22
|
+
Then(/^(\w+) should be able to (\w+) "(.+?)"$/) do |actor_name, permission_name, resource_name|
|
23
|
+
actor = @actors.fetch(actor_name)
|
24
|
+
resource = @resources.fetch(resource_name)
|
25
|
+
|
26
|
+
unless actor.can? permission_name, resource
|
27
|
+
raise "Expected #{actor_name} to be able to #{permission_name} #{resource_name}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Then(/^(\w+) should not be able to (\w+) "(.+?)"$/) do |actor_name, permission_name, resource_name|
|
32
|
+
actor = @actors.fetch(actor_name)
|
33
|
+
unless actor.cannot? permission_name, @resources.fetch(resource_name)
|
34
|
+
raise "Expected #{actor_name} to not be able to #{permission_name} #{resource_name}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
When(/I have a (\w+) resource defined as/) do |model_name, resource_definition|
|
2
|
+
@resource_model = find_model(model_name)
|
3
|
+
|
4
|
+
eval_dsl resource_definition, @resource_model
|
5
|
+
end
|
6
|
+
|
7
|
+
When(/I have a confidential \w+ named "([\w\s]+)"/) do |name|
|
8
|
+
@resources ||= {}
|
9
|
+
@resources[name] = @resource_model.new(name: name)
|
10
|
+
end
|
11
|
+
|
12
|
+
Then(/I should be able to set an ACL on it/) do
|
13
|
+
instance = @resource_model.new
|
14
|
+
|
15
|
+
instance.acl = {"foo" => :bar}
|
16
|
+
instance.save!
|
17
|
+
instance = @resource_model.find(instance.id)
|
18
|
+
|
19
|
+
unless instance.acl == {"foo" => :bar}
|
20
|
+
raise %[Expecting {"foo"=> :bar} as an ACL but found #{instance.acl.inspect}]
|
21
|
+
end
|
22
|
+
|
23
|
+
unless instance.acl.kind_of?(@resource_model.acl)
|
24
|
+
raise "Expecting #{instance.acl.class} to be a #{@resource_model.acl}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Then(/(\w+) can see only "(.*?)" in the (\w+) authorized list/) do |actor_name, resource_names, model_name|
|
29
|
+
actor = @actors[actor_name]
|
30
|
+
|
31
|
+
resource_names = resource_names.split(',')
|
32
|
+
resources = resource_names.map {|name| @resources.fetch(name)}
|
33
|
+
|
34
|
+
model = find_model(model_name)
|
35
|
+
accessible = model.accessible_by(actor).to_a
|
36
|
+
|
37
|
+
unless (accessible & resources) == resources
|
38
|
+
raise "Expected to have access to #{resources} but found only #{accessible}"
|
39
|
+
end
|
40
|
+
end
|
data/lib/eaco/acl.rb
CHANGED
data/lib/eaco/actor.rb
CHANGED
@@ -19,7 +19,7 @@ module Eaco
|
|
19
19
|
adapter.class::OID.register_type 'jsonb', adapter.class::OID::Json.new
|
20
20
|
adapter.send :reload_type_map
|
21
21
|
|
22
|
-
adapter.native_database_types.update(jsonb: {name: '
|
22
|
+
adapter.native_database_types.update(jsonb: {name: 'jsonb'})
|
23
23
|
|
24
24
|
adapter.class.parent::PostgreSQLColumn.instance_eval do
|
25
25
|
include Column
|
@@ -25,9 +25,9 @@ module Eaco
|
|
25
25
|
def accessible_by(actor)
|
26
26
|
return scoped if actor.is_admin?
|
27
27
|
|
28
|
-
designators = actor.designators.map {|d| quote_value(d) }
|
28
|
+
designators = actor.designators.map {|d| quote_value(d, nil) }
|
29
29
|
|
30
|
-
where("acl ?| array[#{designators.join(',')}]")
|
30
|
+
where("acl ?| array[#{designators.join(',')}]::varchar[]")
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
data/lib/eaco/controller.rb
CHANGED
@@ -137,25 +137,29 @@ module Eaco
|
|
137
137
|
# @return [nil]
|
138
138
|
#
|
139
139
|
def define_schema!
|
140
|
-
load 'eaco/cucumber/active_record/schema.rb'
|
140
|
+
log_stdout { load 'eaco/cucumber/active_record/schema.rb' }
|
141
141
|
end
|
142
142
|
|
143
|
+
protected
|
144
|
+
|
143
145
|
##
|
144
|
-
#
|
145
|
-
#
|
146
|
-
# TODO untangle from postgres
|
146
|
+
# Captures stdout and logs it
|
147
147
|
#
|
148
|
-
# @return [
|
148
|
+
# @return [nil]
|
149
149
|
#
|
150
|
-
def
|
151
|
-
|
152
|
-
|
150
|
+
def log_stdout
|
151
|
+
stdout, string = $stdout, StringIO.new
|
152
|
+
$stdout = string
|
153
153
|
|
154
|
-
|
155
|
-
|
156
|
-
|
154
|
+
yield
|
155
|
+
|
156
|
+
string.tap(&:rewind).read.split("\n").each do |line|
|
157
|
+
logger.info line
|
158
|
+
end
|
157
159
|
|
158
|
-
|
160
|
+
nil
|
161
|
+
ensure
|
162
|
+
$stdout = stdout
|
159
163
|
end
|
160
164
|
end
|
161
165
|
|
data/lib/eaco/designator.rb
CHANGED
data/lib/eaco/dsl/resource.rb
CHANGED
@@ -156,7 +156,13 @@ module Eaco
|
|
156
156
|
# @return [String]
|
157
157
|
#
|
158
158
|
def fancy(msg)
|
159
|
-
|
159
|
+
<<-EOF
|
160
|
+
\033[0m
|
161
|
+
\033[1;32m>>>
|
162
|
+
\033[1;32m>>> EACO: \033[1;37m#{msg}
|
163
|
+
\033[1;32m>>>
|
164
|
+
\033[0m
|
165
|
+
EOF
|
160
166
|
end
|
161
167
|
|
162
168
|
##
|
data/lib/eaco/resource.rb
CHANGED
@@ -61,7 +61,7 @@ module Eaco
|
|
61
61
|
perms = permissions[role]
|
62
62
|
return false unless perms
|
63
63
|
|
64
|
-
perms.include?(action)
|
64
|
+
perms.include?(action.to_sym)
|
65
65
|
end
|
66
66
|
|
67
67
|
##
|
@@ -112,7 +112,7 @@ module Eaco
|
|
112
112
|
|
113
113
|
# The defined roles.
|
114
114
|
#
|
115
|
-
# @return [
|
115
|
+
# @return [Array]
|
116
116
|
#
|
117
117
|
# @see DSL::Resource
|
118
118
|
#
|
data/lib/eaco/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eaco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcello Barnaba
|
@@ -178,6 +178,20 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: guard-shell
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
181
195
|
description:
|
182
196
|
email:
|
183
197
|
- vjt@openssl.it
|
@@ -200,8 +214,8 @@ files:
|
|
200
214
|
- features/active_record.travis.yml
|
201
215
|
- features/rails_integration.feature
|
202
216
|
- features/role_based_authorization.feature
|
203
|
-
- features/step_definitions/
|
204
|
-
- features/step_definitions/
|
217
|
+
- features/step_definitions/actor_steps.rb
|
218
|
+
- features/step_definitions/resource_steps.rb
|
205
219
|
- features/support/env.rb
|
206
220
|
- gemfiles/rails_3.2.gemfile
|
207
221
|
- gemfiles/rails_4.0.gemfile
|
@@ -291,8 +305,8 @@ test_files:
|
|
291
305
|
- features/active_record.travis.yml
|
292
306
|
- features/rails_integration.feature
|
293
307
|
- features/role_based_authorization.feature
|
294
|
-
- features/step_definitions/
|
295
|
-
- features/step_definitions/
|
308
|
+
- features/step_definitions/actor_steps.rb
|
309
|
+
- features/step_definitions/resource_steps.rb
|
296
310
|
- features/support/env.rb
|
297
311
|
- spec/eaco/acl_spec.rb
|
298
312
|
- spec/eaco/actor_spec.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
Given(/I have an (\w+) actor defined as/) do |model_name, author_definition|
|
2
|
-
@actor_model = find_model(model_name)
|
3
|
-
|
4
|
-
eval_dsl author_definition, @actor_model
|
5
|
-
end
|
6
|
-
|
7
|
-
Given(/I have an actor named (\w+)/) do |actor_name|
|
8
|
-
actor = @actor_model.new
|
9
|
-
actor.name = actor_name
|
10
|
-
|
11
|
-
@actors ||= {}
|
12
|
-
@actors[actor_name] = actor
|
13
|
-
end
|
14
|
-
|
15
|
-
When(/I grant (\w+) access as a (\w+) in quality of (\w+)/) do |actor_name, role_name, designator|
|
16
|
-
actor = @actors.fetch(actor_name)
|
17
|
-
@resource.grant role_name, designator, actor
|
18
|
-
@resource.save!
|
19
|
-
end
|
20
|
-
|
21
|
-
Then(/(\w+) should be able to (\w+) it/) do |actor_name, permission_name|
|
22
|
-
actor = @actors.fetch(actor_name)
|
23
|
-
actor.can? permission_name, @resource
|
24
|
-
end
|
25
|
-
|
26
|
-
Then(/(\w+) should not be able to (\w+) it/) do |actor_name, permission_name|
|
27
|
-
actor = @actors.fetch(actor_name)
|
28
|
-
actor.cannot? permission_name, @resource
|
29
|
-
end
|
30
|
-
|
@@ -1,19 +0,0 @@
|
|
1
|
-
When(/I have a (\w+) resource defined as/) do |model_name, resource_definition|
|
2
|
-
@resource_model = find_model(model_name)
|
3
|
-
|
4
|
-
eval_dsl resource_definition, @resource_model
|
5
|
-
end
|
6
|
-
|
7
|
-
When(/I have a confidential one named "([\w\s]+)"/) do |name|
|
8
|
-
@resource = @resource_model.new(name: name)
|
9
|
-
end
|
10
|
-
|
11
|
-
Then(/I should be able to set an ACL on it/) do
|
12
|
-
instance = @resource_model.new
|
13
|
-
|
14
|
-
instance.acl = {foo: :bar}
|
15
|
-
instance.save!
|
16
|
-
instance = @resource_model.find(instance.id)
|
17
|
-
|
18
|
-
instance.acl == {foo: :bar} && instance.acl.class.kind_of?(@resource_model.acl)
|
19
|
-
end
|