access_schema 0.3.5 → 0.4.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/README.md +23 -30
- data/lib/access_schema.rb +4 -4
- data/lib/access_schema/builders/{element_builder.rb → privilege_builder.rb} +1 -1
- data/lib/access_schema/builders/resource_builder.rb +14 -0
- data/lib/access_schema/builders/roles_builder.rb +0 -2
- data/lib/access_schema/builders/schema_builder.rb +4 -8
- data/lib/access_schema/{element.rb → privilege.rb} +1 -1
- data/lib/access_schema/proxy.rb +3 -3
- data/lib/access_schema/resource.rb +23 -0
- data/lib/access_schema/schema.rb +39 -45
- data/lib/access_schema/version.rb +1 -1
- data/spec/access_schema/config_builder_spec.rb +1 -1
- data/spec/access_schema/schema_builder_spec.rb +4 -4
- data/spec/access_schema/schema_spec.rb +22 -2
- data/spec/schema_example.rb +19 -8
- metadata +8 -8
- data/lib/access_schema/builders/namespace_builder.rb +0 -16
- data/lib/access_schema/namespace.rb +0 -16
data/README.md
CHANGED
@@ -5,8 +5,6 @@ to define ACL schemas with realy simple DSL.
|
|
5
5
|
|
6
6
|
Inspired by [ya_acl](https://github.com/kaize/ya_acl)
|
7
7
|
|
8
|
-
With a couple of aliases in DSL it enables you to deal with tariff plans. Plan and role, feature and privilege are synonyms.
|
9
|
-
|
10
8
|
```
|
11
9
|
gem install access_schema
|
12
10
|
```
|
@@ -24,9 +22,9 @@ add some default options in helpers:
|
|
24
22
|
|
25
23
|
class AccessSchemaHelper
|
26
24
|
|
27
|
-
def
|
25
|
+
def role
|
28
26
|
AccessSchema.schema(:plans).with_options({
|
29
|
-
:
|
27
|
+
:role => Rails.development? && params[:debug_role] || current_user.try(:role) || :none
|
30
28
|
})
|
31
29
|
end
|
32
30
|
|
@@ -45,14 +43,14 @@ So at may be used in controllers:
|
|
45
43
|
|
46
44
|
```ruby
|
47
45
|
acl.require! review, :edit
|
48
|
-
|
46
|
+
role.require! review, :mark_privileged
|
49
47
|
|
50
48
|
```
|
51
49
|
|
52
50
|
Or views:
|
53
51
|
|
54
52
|
```ruby
|
55
|
-
- if
|
53
|
+
- if role.allow? review, :add_photo
|
56
54
|
= render :partial => "add_photo"
|
57
55
|
```
|
58
56
|
|
@@ -66,17 +64,17 @@ example. So we have to pass extra options:
|
|
66
64
|
|
67
65
|
class ReviewService < BaseSevice
|
68
66
|
|
69
|
-
def
|
67
|
+
def mark_privileged(review_id, options)
|
70
68
|
|
71
69
|
review = Review.find(review_id)
|
72
70
|
|
73
|
-
acl = AccessSchema.schema(:acl).with_options(:
|
74
|
-
acl.require! review, :
|
71
|
+
acl = AccessSchema.schema(:acl).with_options(:roles => options[:actor].roles)
|
72
|
+
acl.require! review, :mark_privileged
|
75
73
|
|
76
|
-
plans = AccessSchema.schema(:plans).with_options(:
|
77
|
-
plans.require! review, :
|
74
|
+
plans = AccessSchema.schema(:plans).with_options(:plans => options[:actor].plans)
|
75
|
+
plans.require! review, :mark_privileged
|
78
76
|
|
79
|
-
review.
|
77
|
+
review.privileged = true
|
80
78
|
review.save!
|
81
79
|
|
82
80
|
end
|
@@ -85,10 +83,10 @@ example. So we have to pass extra options:
|
|
85
83
|
|
86
84
|
review = Review.find(review_id)
|
87
85
|
|
88
|
-
acl = AccessSchema.schema(:acl).with_options(:
|
86
|
+
acl = AccessSchema.schema(:acl).with_options(:roles => options[:actor].roles)
|
89
87
|
acl.require! review, :edit
|
90
88
|
|
91
|
-
plans = AccessSchema.schema(:
|
89
|
+
plans = AccessSchema.schema(:plan).with_options(:plan => options[:actor].plan)
|
92
90
|
plans.require! review, :edit, :new_attrs => attrs
|
93
91
|
|
94
92
|
review.update_attributes(attrs)
|
@@ -102,13 +100,13 @@ example. So we have to pass extra options:
|
|
102
100
|
### Definition
|
103
101
|
|
104
102
|
```ruby
|
105
|
-
# config/
|
103
|
+
# config/roles.rb
|
106
104
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
roles do
|
106
|
+
role :none
|
107
|
+
role :bulb
|
108
|
+
role :flower
|
109
|
+
role :bouquet
|
112
110
|
end
|
113
111
|
|
114
112
|
asserts do
|
@@ -123,22 +121,17 @@ example. So we have to pass extra options:
|
|
123
121
|
|
124
122
|
end
|
125
123
|
|
126
|
-
|
124
|
+
resource "Review" do
|
127
125
|
|
128
|
-
|
126
|
+
privilege :mark_privileged, [:flower, :bouquet]
|
129
127
|
|
130
|
-
|
128
|
+
privilege :add_photo, [:bouquet] do
|
131
129
|
assert :photo_limit, [:none], :limit => 1
|
132
130
|
assert :photo_limit, [:bulb], :limit => 5
|
133
131
|
assert :photo_limit, [:flower], :limit => 10
|
134
132
|
end
|
135
133
|
|
136
|
-
|
137
|
-
# greeting
|
138
|
-
# logo
|
139
|
-
# site_url
|
140
|
-
#
|
141
|
-
feature :edit, [:bouquet] do
|
134
|
+
privilege :edit, [:bouquet] do
|
142
135
|
assert :attrs, [:bulb], :disallow => [:greeting, :logo, :site_url]
|
143
136
|
assert :attrs, [:flower], :disallow => [:site_url]
|
144
137
|
end
|
@@ -161,7 +154,7 @@ example. So we have to pass extra options:
|
|
161
154
|
|
162
155
|
end
|
163
156
|
|
164
|
-
|
157
|
+
resource "Review" do
|
165
158
|
|
166
159
|
privilege :edit, [:admin] do
|
167
160
|
assert :owner, [:none]
|
data/lib/access_schema.rb
CHANGED
@@ -4,8 +4,8 @@ require 'access_schema/exceptions'
|
|
4
4
|
require 'access_schema/config'
|
5
5
|
require 'access_schema/schema'
|
6
6
|
require 'access_schema/assert'
|
7
|
-
require 'access_schema/
|
8
|
-
require 'access_schema/
|
7
|
+
require 'access_schema/resource'
|
8
|
+
require 'access_schema/privilege'
|
9
9
|
require 'access_schema/expectation'
|
10
10
|
|
11
11
|
require 'access_schema/loggers/proxy_logger'
|
@@ -16,8 +16,8 @@ require 'access_schema/builders/config_builder'
|
|
16
16
|
require 'access_schema/builders/basic_builder'
|
17
17
|
require 'access_schema/builders/roles_builder'
|
18
18
|
require 'access_schema/builders/asserts_builder'
|
19
|
-
require 'access_schema/builders/
|
20
|
-
require 'access_schema/builders/
|
19
|
+
require 'access_schema/builders/resource_builder'
|
20
|
+
require 'access_schema/builders/privilege_builder'
|
21
21
|
require 'access_schema/builders/schema_builder'
|
22
22
|
|
23
23
|
require 'access_schema/proxy'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module AccessSchema
|
2
|
+
class ResourceBuilder < BasicBuilder
|
3
|
+
|
4
|
+
def privilege(name, roles = [], &block)
|
5
|
+
privilege = Privilege.new(name.to_sym, roles.map(&:to_sym))
|
6
|
+
if block_given?
|
7
|
+
builder = PrivilegeBuilder.new(privilege)
|
8
|
+
builder.instance_eval(&block)
|
9
|
+
end
|
10
|
+
schema.add_privilege(privilege)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -18,21 +18,17 @@ module AccessSchema
|
|
18
18
|
builder.instance_eval(&block)
|
19
19
|
end
|
20
20
|
|
21
|
-
alias :plans :roles
|
22
|
-
|
23
21
|
def asserts(&block)
|
24
22
|
builder = AssertsBuilder.new(schema)
|
25
23
|
builder.instance_eval(&block)
|
26
24
|
end
|
27
25
|
|
28
|
-
def
|
29
|
-
|
30
|
-
builder =
|
26
|
+
def resource(name, &block)
|
27
|
+
resource = Resource.new(name.to_sym)
|
28
|
+
builder = ResourceBuilder.new(resource)
|
31
29
|
builder.instance_eval(&block)
|
32
|
-
schema.
|
30
|
+
schema.add_resource(resource)
|
33
31
|
end
|
34
32
|
|
35
|
-
alias :resource :namespace
|
36
|
-
|
37
33
|
end
|
38
34
|
end
|
data/lib/access_schema/proxy.rb
CHANGED
@@ -29,8 +29,8 @@ module AccessSchema
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def normalize_args(args)
|
32
|
-
|
33
|
-
|
32
|
+
resource = args[0]
|
33
|
+
privilege = args[1]
|
34
34
|
|
35
35
|
roles, options = case args[2]
|
36
36
|
when Hash, nil
|
@@ -43,7 +43,7 @@ module AccessSchema
|
|
43
43
|
options_to_pass.delete :plan
|
44
44
|
options_to_pass.delete :role
|
45
45
|
|
46
|
-
[
|
46
|
+
[resource, privilege, roles, options_to_pass.merge(options)]
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AccessSchema
|
2
|
+
class Resource
|
3
|
+
attr_reader :name
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
@privileges = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def privileges
|
11
|
+
@privileges.values
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_privilege(privilege)
|
15
|
+
@privileges[privilege.name] = privilege
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_privilege(name)
|
19
|
+
@privileges[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/access_schema/schema.rb
CHANGED
@@ -7,7 +7,7 @@ module AccessSchema
|
|
7
7
|
def initialize
|
8
8
|
@roles = []
|
9
9
|
@asserts = {}
|
10
|
-
@
|
10
|
+
@resources = {}
|
11
11
|
end
|
12
12
|
|
13
13
|
def add_role(role)
|
@@ -18,8 +18,8 @@ module AccessSchema
|
|
18
18
|
@asserts[assert.name] = assert
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
@
|
21
|
+
def add_resource(resource)
|
22
|
+
@resources[resource.name] = resource
|
23
23
|
end
|
24
24
|
|
25
25
|
def allow?(*args)
|
@@ -46,43 +46,61 @@ module AccessSchema
|
|
46
46
|
|
47
47
|
raise NoRoleError.new if (self.roles & roles).empty?
|
48
48
|
|
49
|
+
roles = normalize_roles_order(roles)
|
49
50
|
|
50
51
|
case args[0]
|
51
52
|
when String, Symbol
|
52
|
-
|
53
|
-
[
|
53
|
+
resource = args[0].to_sym
|
54
|
+
[resource, privilege, roles, options]
|
54
55
|
else
|
55
|
-
|
56
|
-
[
|
56
|
+
resource = args[0].class.name.to_sym
|
57
|
+
[resource, privilege, roles, options.merge(:subject => args[0])]
|
57
58
|
end
|
58
59
|
|
59
60
|
end
|
60
61
|
|
61
|
-
def
|
62
|
+
def normalize_roles_order(roles)
|
63
|
+
@roles.select do |role|
|
64
|
+
roles.include? role
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def check!(resource_name, privilege_name, roles, options)
|
69
|
+
|
70
|
+
resouce_name = resource_name.to_sym
|
71
|
+
privilege_name = privilege_name.to_sym
|
72
|
+
|
73
|
+
resource = @resources[resource_name]
|
74
|
+
|
75
|
+
if resource.nil?
|
76
|
+
raise NoResourceError.new(:resource => resource_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
privilege = resource.get_privilege(privilege_name)
|
80
|
+
|
81
|
+
if privilege.nil?
|
82
|
+
raise NoPrivilegeError.new(:resource => resource_name, :privilege => privilege_name)
|
83
|
+
end
|
62
84
|
|
63
|
-
|
64
|
-
failed_asserts = []
|
85
|
+
failed_asserts = Hash.new{|h, k| h[k] = []}
|
65
86
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
failed_asserts << expectation unless result
|
87
|
+
roles_checks = roles.map do |role|
|
88
|
+
privilege.allow?([role]) do |expectation|
|
89
|
+
@asserts[expectation.name].check?(expectation.options.merge(options)).tap do |result|
|
90
|
+
failed_asserts[role] << expectation.name unless result
|
71
91
|
end
|
72
92
|
end
|
73
93
|
end
|
74
94
|
|
75
|
-
raise NoPrivilegeError.new(:privilege => element_name.to_sym) unless existent_element
|
76
|
-
|
77
95
|
log_payload = {
|
78
|
-
:resource =>
|
79
|
-
:privilege =>
|
96
|
+
:resource => resource_name,
|
97
|
+
:privilege => privilege_name,
|
80
98
|
:roles => roles,
|
81
99
|
:options => options
|
82
100
|
}
|
83
101
|
|
84
|
-
unless
|
85
|
-
log_payload[:failed_asserts] = failed_asserts
|
102
|
+
unless roles_checks.any?
|
103
|
+
log_payload[:failed_asserts] = failed_asserts
|
86
104
|
logger.info{ "check FAILED: #{log_payload.inspect}" }
|
87
105
|
raise NotAllowedError.new(log_payload)
|
88
106
|
else
|
@@ -92,30 +110,6 @@ module AccessSchema
|
|
92
110
|
|
93
111
|
end
|
94
112
|
|
95
|
-
def check_assert(expectation, options)
|
96
|
-
@asserts[expectation.name].check?(expectation.options.merge(options))
|
97
|
-
end
|
98
|
-
|
99
|
-
def for_element(namespace, element)
|
100
|
-
ns = namespace.to_sym
|
101
|
-
en = element.to_sym
|
102
|
-
|
103
|
-
elements_for(ns).any? do |element|
|
104
|
-
if element.name == en
|
105
|
-
yield(element)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
def elements_for(namespace)
|
112
|
-
if @namespaces.has_key?(namespace)
|
113
|
-
@namespaces[namespace].elements
|
114
|
-
else
|
115
|
-
raise NoResourceError.new(:resource => namespace)
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
113
|
private
|
120
114
|
|
121
115
|
def logger
|
@@ -7,8 +7,8 @@ describe AccessSchema::SchemaBuilder do
|
|
7
7
|
|
8
8
|
it "builds schema from block" do
|
9
9
|
@schema = AccessSchema::SchemaBuilder.build do
|
10
|
-
|
11
|
-
|
10
|
+
roles do
|
11
|
+
role :none
|
12
12
|
end
|
13
13
|
end
|
14
14
|
@schema.should be
|
@@ -36,8 +36,8 @@ describe AccessSchema::SchemaBuilder, "produced schema example" do
|
|
36
36
|
@schema = AccessSchema::SchemaBuilder.build_file('spec/schema_example.rb')
|
37
37
|
end
|
38
38
|
|
39
|
-
it "creates
|
40
|
-
@schema.
|
39
|
+
it "creates roles" do
|
40
|
+
@schema.roles.should == [:none, :bulb, :flower, :bouquet, :admin, :user]
|
41
41
|
end
|
42
42
|
|
43
43
|
context "when checking against plan 'none'" do
|
@@ -28,7 +28,7 @@ describe AccessSchema::Schema, "errors rising" do
|
|
28
28
|
|
29
29
|
describe "#allow?" do
|
30
30
|
|
31
|
-
it "raises exception on invalid
|
31
|
+
it "raises exception on invalid resource" do
|
32
32
|
lambda {
|
33
33
|
@schema.allow? "Invalid", :mark_featured, :none
|
34
34
|
}.should raise_error(AccessSchema::NoResourceError)
|
@@ -48,6 +48,26 @@ describe AccessSchema::Schema, "errors rising" do
|
|
48
48
|
|
49
49
|
end
|
50
50
|
|
51
|
+
describe "privilege union for multiple roles" do
|
52
|
+
|
53
|
+
context "when checking privilege :update for Review in example schema" do
|
54
|
+
|
55
|
+
it "passes for admin" do
|
56
|
+
@schema.should be_allow("Review", :update, [:admin])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "fails for user" do
|
60
|
+
@schema.should_not be_allow("Review", :update, [:user])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "passes for admin and user" do
|
64
|
+
@schema.should be_allow("Review", :update, [:admin, :user])
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
51
71
|
describe "#require!" do
|
52
72
|
|
53
73
|
it "raises en error is feature is nt allowed"
|
@@ -70,7 +90,7 @@ describe AccessSchema::Schema, "errors rising" do
|
|
70
90
|
it "logs check fail with info level" do
|
71
91
|
@logger.log_only_level = "info"
|
72
92
|
@schema.allow? "Review", :mark_featured, :none
|
73
|
-
@logger.output.should == "AccessSchema: check FAILED: {:resource=>:Review, :privilege=>:mark_featured, :roles=>[:none], :options=>{}, :failed_asserts=>
|
93
|
+
@logger.output.should == "AccessSchema: check FAILED: {:resource=>:Review, :privilege=>:mark_featured, :roles=>[:none], :options=>{}, :failed_asserts=>{}}"
|
74
94
|
end
|
75
95
|
end
|
76
96
|
|
data/spec/schema_example.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
roles do
|
3
|
+
role :none
|
4
|
+
role :bulb
|
5
|
+
role :flower
|
6
|
+
role :bouquet
|
7
|
+
|
8
|
+
role :admin
|
9
|
+
role :user
|
7
10
|
end
|
8
11
|
|
9
12
|
asserts do
|
@@ -12,16 +15,24 @@ asserts do
|
|
12
15
|
subject.photos_count < limit
|
13
16
|
end
|
14
17
|
|
18
|
+
assert :false do
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
15
22
|
end
|
16
23
|
|
17
|
-
|
24
|
+
resource "Review" do
|
18
25
|
|
19
|
-
|
26
|
+
privilege :mark_featured, [:flower, :bouquet]
|
20
27
|
|
21
|
-
|
28
|
+
privilege :add_photo, [:bouquet] do
|
22
29
|
assert :photo_limit, [:none], :limit => 1
|
23
30
|
assert :photo_limit, [:bulb], :limit => 5
|
24
31
|
assert :photo_limit, [:flower], :limit => 10
|
25
32
|
end
|
26
33
|
|
34
|
+
privilege :update, [:admin] do
|
35
|
+
assert :false, [:user]
|
36
|
+
end
|
37
|
+
|
27
38
|
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.4.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-03-
|
12
|
+
date: 2012-03-26 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
|
@@ -32,19 +32,19 @@ files:
|
|
32
32
|
- lib/access_schema/builders/asserts_builder.rb
|
33
33
|
- lib/access_schema/builders/basic_builder.rb
|
34
34
|
- lib/access_schema/builders/config_builder.rb
|
35
|
-
- lib/access_schema/builders/
|
36
|
-
- lib/access_schema/builders/
|
35
|
+
- lib/access_schema/builders/privilege_builder.rb
|
36
|
+
- lib/access_schema/builders/resource_builder.rb
|
37
37
|
- lib/access_schema/builders/roles_builder.rb
|
38
38
|
- lib/access_schema/builders/schema_builder.rb
|
39
39
|
- lib/access_schema/config.rb
|
40
|
-
- lib/access_schema/element.rb
|
41
40
|
- lib/access_schema/exceptions.rb
|
42
41
|
- lib/access_schema/expectation.rb
|
43
42
|
- lib/access_schema/loggers/proxy_logger.rb
|
44
43
|
- lib/access_schema/loggers/stub_logger.rb
|
45
44
|
- lib/access_schema/loggers/test_logger.rb
|
46
|
-
- lib/access_schema/
|
45
|
+
- lib/access_schema/privilege.rb
|
47
46
|
- lib/access_schema/proxy.rb
|
47
|
+
- lib/access_schema/resource.rb
|
48
48
|
- lib/access_schema/schema.rb
|
49
49
|
- lib/access_schema/version.rb
|
50
50
|
- spec/access_schema/config_builder_spec.rb
|
@@ -69,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
69
|
version: '0'
|
70
70
|
segments:
|
71
71
|
- 0
|
72
|
-
hash: -
|
72
|
+
hash: -3729396007705609250
|
73
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
version: '0'
|
79
79
|
segments:
|
80
80
|
- 0
|
81
|
-
hash: -
|
81
|
+
hash: -3729396007705609250
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project: access_schema
|
84
84
|
rubygems_version: 1.8.16
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module AccessSchema
|
2
|
-
class NamespaceBuilder < BasicBuilder
|
3
|
-
|
4
|
-
def privilege(name, roles = [], &block)
|
5
|
-
element = Element.new(name.to_sym, roles.map(&:to_sym))
|
6
|
-
if block_given?
|
7
|
-
builder = ElementBuilder.new(element)
|
8
|
-
builder.instance_eval(&block)
|
9
|
-
end
|
10
|
-
schema.add_element(element)
|
11
|
-
end
|
12
|
-
|
13
|
-
alias :feature :privilege
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|