access_schema 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +110 -21
- data/lib/access_schema/builders/config_builder.rb +36 -0
- data/lib/access_schema/builders/schema_builder.rb +2 -2
- data/lib/access_schema/config.rb +17 -0
- data/lib/access_schema/proxy.rb +14 -1
- data/lib/access_schema/version.rb +1 -1
- data/lib/access_schema.rb +9 -2
- data/spec/access_schema_spec.rb +7 -29
- data/spec/assess_schema/config_builder_spec.rb +15 -0
- data/spec/assess_schema/proxy_spec.rb +30 -0
- metadata +6 -2
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# AccessSchema gem - ACL/plans for your app
|
2
2
|
|
3
|
-
AccessSchema provides
|
3
|
+
AccessSchema provides decoupled from Rails and ORM agnostic tool
|
4
|
+
to define ACL schemas with realy simple DSL.
|
5
|
+
|
4
6
|
Inspired by [ya_acl](https://github.com/kaize/ya_acl)
|
5
7
|
|
6
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,21 +11,99 @@ With a couple of aliases in DSL it enables you to deal with tariff plans. Plan a
|
|
9
11
|
gem install access_schema
|
10
12
|
```
|
11
13
|
|
12
|
-
## An example of
|
14
|
+
## An example of use
|
15
|
+
|
16
|
+
|
17
|
+
### Accessing from application code
|
18
|
+
|
19
|
+
In Rails controllers we usualy have a current_user and we can
|
20
|
+
add some default options in helpers:
|
13
21
|
|
14
22
|
```ruby
|
15
|
-
#
|
23
|
+
#access_schema_helper.rb
|
16
24
|
|
17
|
-
|
25
|
+
class AccessSchemaHelper
|
18
26
|
|
19
|
-
|
27
|
+
def plan
|
28
|
+
AccessSchema.schema(:plans).with_options({
|
29
|
+
:plan => Rails.development? && params[:debug_plan] || current_user.try(:plan) || :none
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
def acl
|
34
|
+
AccessSchema.schema(:acl).with_options({
|
35
|
+
:role => current_user.try(:role) || :none,
|
36
|
+
:user_id => current_user.try(:id)
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
20
41
|
|
42
|
+
```
|
43
|
+
|
44
|
+
So at may be used in controllers:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
acl.require! review, :edit
|
21
48
|
plan.require! review, :mark_featured
|
22
49
|
|
23
50
|
```
|
24
51
|
|
52
|
+
Or views:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
- if plan.allow? review, :add_photo
|
56
|
+
= render :partial => "add_photo"
|
57
|
+
```
|
58
|
+
|
59
|
+
|
60
|
+
On the ather side there are no any current_user accessible. In a Service Layer for
|
61
|
+
example. So we have to pass extra options:
|
62
|
+
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
#./app/services/review_service.rb
|
66
|
+
|
67
|
+
class ReviewService < BaseSevice
|
68
|
+
|
69
|
+
def mark_featured(review_id, options)
|
70
|
+
|
71
|
+
review = Review.find(review_id)
|
72
|
+
|
73
|
+
acl = AccessSchema.schema(:acl).with_options(:role => options[:actor].roles)
|
74
|
+
acl.require! review, :mark_featured
|
75
|
+
|
76
|
+
plans = AccessSchema.schema(:plans).with_options(:plan => options[:actor].plan)
|
77
|
+
plans.require! review, :mark_featured
|
78
|
+
|
79
|
+
review.featured = true
|
80
|
+
review.save!
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def update(review_id, attrs)
|
85
|
+
|
86
|
+
review = Review.find(review_id)
|
87
|
+
|
88
|
+
acl = AccessSchema.schema(:acl).with_options(:role => options[:actor].roles)
|
89
|
+
acl.require! review, :edit
|
90
|
+
|
91
|
+
plans = AccessSchema.schema(:plans).with_options(:plan => options[:actor].plan)
|
92
|
+
plans.require! review, :edit, :new_attrs => attrs
|
93
|
+
|
94
|
+
review.update_attributes(attrs)
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
```
|
101
|
+
|
102
|
+
### Definition
|
103
|
+
|
25
104
|
```ruby
|
26
105
|
# config/plans.rb
|
106
|
+
|
27
107
|
plans do
|
28
108
|
plan :none
|
29
109
|
plan :bulb
|
@@ -37,6 +117,10 @@ With a couple of aliases in DSL it enables you to deal with tariff plans. Plan a
|
|
37
117
|
subject.photos_count < limit
|
38
118
|
end
|
39
119
|
|
120
|
+
assert :attrs, [:new_attrs, :disallow] do
|
121
|
+
# check if any disallowed attributes are changing in subject with new_attrs
|
122
|
+
end
|
123
|
+
|
40
124
|
end
|
41
125
|
|
42
126
|
namespace "Review" do
|
@@ -49,6 +133,16 @@ With a couple of aliases in DSL it enables you to deal with tariff plans. Plan a
|
|
49
133
|
assert :photo_limit, [:flower], :limit => 10
|
50
134
|
end
|
51
135
|
|
136
|
+
# Important fields from plans aspect:
|
137
|
+
# greeting
|
138
|
+
# logo
|
139
|
+
# site_url
|
140
|
+
#
|
141
|
+
feature :edit, [:bouquet] do
|
142
|
+
assert :attrs, [:bulb], :disallow => [:greeting, :logo, :site_url]
|
143
|
+
assert :attrs, [:flower], :disallow => [:site_url]
|
144
|
+
end
|
145
|
+
|
52
146
|
end
|
53
147
|
```
|
54
148
|
|
@@ -76,27 +170,22 @@ With a couple of aliases in DSL it enables you to deal with tariff plans. Plan a
|
|
76
170
|
end
|
77
171
|
```
|
78
172
|
|
173
|
+
## Configuration
|
79
174
|
|
80
|
-
|
81
|
-
|
175
|
+
Configured schema can be accessed with AccessSchema.schema(name)
|
176
|
+
anywhere in app. Alternatively it can be assempled with ServiceLocator.
|
82
177
|
|
83
|
-
class AccessSchemaHelper
|
84
178
|
|
85
|
-
|
86
|
-
|
87
|
-
AccessSchema.with_options(@plan, {
|
88
|
-
:plan => Rails.development? && params[:debug_plan] || current_user.try(:plan) || :none
|
89
|
-
})
|
90
|
-
end
|
179
|
+
```ruby
|
180
|
+
#config/initializers/access_schema.rb
|
91
181
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
:user_id => current_user.try(:id)
|
97
|
-
})
|
98
|
-
end
|
182
|
+
AccessSchema.configure do
|
183
|
+
|
184
|
+
schema :plans, AccessSchema.build_file('config/plans.rb')
|
185
|
+
schema :acl, AccessSchema.build_file('config/acl.rb')
|
99
186
|
|
100
187
|
end
|
101
188
|
|
102
189
|
```
|
190
|
+
|
191
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module AccessSchema
|
2
|
+
class ConfigBuilder
|
3
|
+
|
4
|
+
attr_reader :config
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.build(&block)
|
11
|
+
builder = new(Config.new)
|
12
|
+
builder.instance_eval(&block)
|
13
|
+
builder.config.freeze
|
14
|
+
end
|
15
|
+
|
16
|
+
def schema(name, schema)
|
17
|
+
if schema.is_a?(Hash)
|
18
|
+
schema = schema_from_options(schema)
|
19
|
+
end
|
20
|
+
@config.add_schema(name, schema)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def schema_from_options(options)
|
26
|
+
|
27
|
+
if options[:file]
|
28
|
+
AccessSchema.build_file(options[:file])
|
29
|
+
else
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -4,13 +4,13 @@ module AccessSchema
|
|
4
4
|
def self.build(&block)
|
5
5
|
builder = new(Schema.new)
|
6
6
|
builder.instance_eval(&block)
|
7
|
-
builder.schema
|
7
|
+
Proxy.new(builder.schema)
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.build_file(filename)
|
11
11
|
builder = new(Schema.new)
|
12
12
|
builder.instance_eval(File.read(filename))
|
13
|
-
builder.schema
|
13
|
+
Proxy.new(builder.schema)
|
14
14
|
end
|
15
15
|
|
16
16
|
def roles(&block)
|
data/lib/access_schema/proxy.rb
CHANGED
@@ -1,14 +1,23 @@
|
|
1
1
|
module AccessSchema
|
2
2
|
class Proxy
|
3
3
|
|
4
|
-
def initialize(schema, options)
|
4
|
+
def initialize(schema, options = {})
|
5
5
|
@schema = schema
|
6
6
|
@options = options
|
7
7
|
end
|
8
8
|
|
9
|
+
def roles
|
10
|
+
@schema.roles
|
11
|
+
end
|
12
|
+
|
13
|
+
def plans
|
14
|
+
@schema.plans
|
15
|
+
end
|
16
|
+
|
9
17
|
def allow?(*args)
|
10
18
|
namespace = args[0]
|
11
19
|
feature = args[1]
|
20
|
+
|
12
21
|
role, options = case args[2]
|
13
22
|
when Symbol, String
|
14
23
|
[args[2], args[3]]
|
@@ -23,5 +32,9 @@ module AccessSchema
|
|
23
32
|
@schema.require!(*args)
|
24
33
|
end
|
25
34
|
|
35
|
+
def with_options(options)
|
36
|
+
Proxy.new(@schema, options)
|
37
|
+
end
|
38
|
+
|
26
39
|
end
|
27
40
|
end
|
data/lib/access_schema.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require 'access_schema/version'
|
2
2
|
require 'access_schema/exceptions'
|
3
3
|
|
4
|
+
require 'access_schema/config'
|
4
5
|
require 'access_schema/schema'
|
5
6
|
require 'access_schema/assert'
|
6
7
|
require 'access_schema/namespace'
|
7
8
|
require 'access_schema/element'
|
8
9
|
require 'access_schema/expectation'
|
9
10
|
|
11
|
+
require 'access_schema/builders/config_builder'
|
12
|
+
|
10
13
|
require 'access_schema/builders/basic_builder'
|
11
14
|
require 'access_schema/builders/roles_builder'
|
12
15
|
require 'access_schema/builders/asserts_builder'
|
@@ -26,8 +29,12 @@ module AccessSchema
|
|
26
29
|
SchemaBuilder.build_file(*args)
|
27
30
|
end
|
28
31
|
|
29
|
-
def self.
|
30
|
-
|
32
|
+
def self.configure(&block)
|
33
|
+
@config = ConfigBuilder.build(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.schema(name)
|
37
|
+
@config.schema(name)
|
31
38
|
end
|
32
39
|
|
33
40
|
end
|
data/spec/access_schema_spec.rb
CHANGED
@@ -2,42 +2,20 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe AccessSchema do
|
4
4
|
|
5
|
-
describe "
|
5
|
+
describe ".build" do
|
6
6
|
it "returns schema"
|
7
7
|
end
|
8
8
|
|
9
|
-
describe "
|
9
|
+
describe ".build_file" do
|
10
10
|
it "returns schema"
|
11
11
|
end
|
12
12
|
|
13
|
-
describe "
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
it "takes schema and options" do
|
20
|
-
lambda {
|
21
|
-
AccessSchema.with_options(@schema, {:plan => :none})
|
22
|
-
}.should_not raise_error
|
23
|
-
end
|
24
|
-
|
25
|
-
it "returns schema" do
|
26
|
-
result = AccessSchema.with_options(@schema, {:plan => :none})
|
27
|
-
%w{allow? require!}.should be_all{|m| result.respond_to?(m)}
|
13
|
+
describe ".configure" do
|
14
|
+
it "passess given block to ConfigBuilder.build method" do
|
15
|
+
block = proc {}
|
16
|
+
AccessSchema::ConfigBuilder.should_receive(:build).with(&block)
|
17
|
+
AccessSchema.configure(&block)
|
28
18
|
end
|
29
|
-
|
30
|
-
it "allows to not specify plan for schema calls" do
|
31
|
-
schema = AccessSchema.with_options(@schema, {:plan => :flower})
|
32
|
-
schema.allow?("Review", :mark_featured).should be_true
|
33
|
-
end
|
34
|
-
|
35
|
-
it "but it accepts plan too" do
|
36
|
-
schema = AccessSchema.with_options(@schema, {})
|
37
|
-
schema.allow?("Review", :mark_featured, :flower).should be_true
|
38
|
-
schema.allow?("Review", :mark_featured, :none).should be_false
|
39
|
-
end
|
40
|
-
|
41
19
|
end
|
42
20
|
|
43
21
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe AccessSchema::ConfigBuilder do
|
5
|
+
|
6
|
+
it "can define schemas directly from file" do
|
7
|
+
|
8
|
+
config = AccessSchema::ConfigBuilder.build do
|
9
|
+
schema :acl, :file => 'spec/schema_example.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
config.schema(:acl).plans.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AccessSchema::Proxy do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@proxy = AccessSchema::Proxy.new(AccessSchema.build_file('spec/schema_example.rb'))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "responds to allow? and require!" do
|
10
|
+
%w{allow? require!}.should be_all{|m| @proxy.respond_to?(m)}
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#with_options" do
|
14
|
+
|
15
|
+
before do
|
16
|
+
@schema = @proxy.with_options(:plan => :flower)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "allows to not specify plan for schema calls" do
|
20
|
+
@schema.allow?("Review", :mark_featured).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "but it accepts plan too" do
|
24
|
+
@schema.allow?("Review", :mark_featured, :flower).should be_true
|
25
|
+
@schema.allow?("Review", :mark_featured, :none).should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
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.0
|
4
|
+
version: 0.1.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-02-
|
12
|
+
date: 2012-02-29 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
|
@@ -31,10 +31,12 @@ files:
|
|
31
31
|
- lib/access_schema/assert.rb
|
32
32
|
- lib/access_schema/builders/asserts_builder.rb
|
33
33
|
- lib/access_schema/builders/basic_builder.rb
|
34
|
+
- lib/access_schema/builders/config_builder.rb
|
34
35
|
- lib/access_schema/builders/element_builder.rb
|
35
36
|
- lib/access_schema/builders/namespace_builder.rb
|
36
37
|
- lib/access_schema/builders/roles_builder.rb
|
37
38
|
- lib/access_schema/builders/schema_builder.rb
|
39
|
+
- lib/access_schema/config.rb
|
38
40
|
- lib/access_schema/element.rb
|
39
41
|
- lib/access_schema/exceptions.rb
|
40
42
|
- lib/access_schema/expectation.rb
|
@@ -43,6 +45,7 @@ files:
|
|
43
45
|
- lib/access_schema/schema.rb
|
44
46
|
- lib/access_schema/version.rb
|
45
47
|
- spec/access_schema_spec.rb
|
48
|
+
- spec/assess_schema/config_builder_spec.rb
|
46
49
|
- spec/assess_schema/proxy_spec.rb
|
47
50
|
- spec/assess_schema/schema_builder_spec.rb
|
48
51
|
- spec/assess_schema/schema_spec.rb
|
@@ -74,6 +77,7 @@ specification_version: 3
|
|
74
77
|
summary: AccessSchema is an ACL tool
|
75
78
|
test_files:
|
76
79
|
- spec/access_schema_spec.rb
|
80
|
+
- spec/assess_schema/config_builder_spec.rb
|
77
81
|
- spec/assess_schema/proxy_spec.rb
|
78
82
|
- spec/assess_schema/schema_builder_spec.rb
|
79
83
|
- spec/assess_schema/schema_spec.rb
|