eaco 0.6.0 → 0.6.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.
- 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
|