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 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 plan
25
+ def role
28
26
  AccessSchema.schema(:plans).with_options({
29
- :plan => Rails.development? && params[:debug_plan] || current_user.try(:plan) || :none
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
- plan.require! review, :mark_featured
46
+ role.require! review, :mark_privileged
49
47
 
50
48
  ```
51
49
 
52
50
  Or views:
53
51
 
54
52
  ```ruby
55
- - if plan.allow? review, :add_photo
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 mark_featured(review_id, options)
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(:role => options[:actor].roles)
74
- acl.require! review, :mark_featured
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(:plan => options[:actor].plan)
77
- plans.require! review, :mark_featured
74
+ plans = AccessSchema.schema(:plans).with_options(:plans => options[:actor].plans)
75
+ plans.require! review, :mark_privileged
78
76
 
79
- review.featured = true
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(:role => options[:actor].roles)
86
+ acl = AccessSchema.schema(:acl).with_options(:roles => options[:actor].roles)
89
87
  acl.require! review, :edit
90
88
 
91
- plans = AccessSchema.schema(:plans).with_options(:plan => options[:actor].plan)
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/plans.rb
103
+ # config/roles.rb
106
104
 
107
- plans do
108
- plan :none
109
- plan :bulb
110
- plan :flower
111
- plan :bouquet
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
- namespace "Review" do
124
+ resource "Review" do
127
125
 
128
- feature :mark_featured, [:flower, :bouquet]
126
+ privilege :mark_privileged, [:flower, :bouquet]
129
127
 
130
- feature :add_photo, [:bouquet] do
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
- # Important fields from plans aspect:
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
- namespace "Review" do
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/namespace'
8
- require 'access_schema/element'
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/namespace_builder'
20
- require 'access_schema/builders/element_builder'
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'
@@ -1,5 +1,5 @@
1
1
  module AccessSchema
2
- class ElementBuilder < BasicBuilder
2
+ class PrivilegeBuilder < BasicBuilder
3
3
 
4
4
  def assert(name, roles = [], options = {})
5
5
  expectation = Expectation.new(name.to_sym, roles.map(&:to_sym), options)
@@ -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
@@ -5,7 +5,5 @@ module AccessSchema
5
5
  schema.add_role(role.to_sym)
6
6
  end
7
7
 
8
- alias :plan :role
9
-
10
8
  end
11
9
  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 namespace(name, &block)
29
- namespace = Namespace.new(name.to_sym)
30
- builder = NamespaceBuilder.new(namespace)
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.add_namespace(namespace)
30
+ schema.add_resource(resource)
33
31
  end
34
32
 
35
- alias :resource :namespace
36
-
37
33
  end
38
34
  end
@@ -1,5 +1,5 @@
1
1
  module AccessSchema
2
- class Element
2
+ class Privilege
3
3
  attr_reader :name
4
4
 
5
5
  def initialize(name, roles, &block)
@@ -29,8 +29,8 @@ module AccessSchema
29
29
  private
30
30
 
31
31
  def normalize_args(args)
32
- namespace = args[0]
33
- feature = args[1]
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
- [namespace, feature, roles, options_to_pass.merge(options)]
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
@@ -7,7 +7,7 @@ module AccessSchema
7
7
  def initialize
8
8
  @roles = []
9
9
  @asserts = {}
10
- @namespaces = {}
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 add_namespace(namespace)
22
- @namespaces[namespace.name] = namespace
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
- namespace = args[0].to_sym
53
- [namespace, privilege, roles, options]
53
+ resource = args[0].to_sym
54
+ [resource, privilege, roles, options]
54
55
  else
55
- namespace = args[0].class.name.to_sym
56
- [namespace, privilege, roles, options.merge(:subject => args[0])]
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 check!(namespace_name, element_name, roles, options)
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
- existent_element = false
64
- failed_asserts = []
85
+ failed_asserts = Hash.new{|h, k| h[k] = []}
65
86
 
66
- allowed = for_element(namespace_name, element_name) do |element|
67
- existent_element = true
68
- element.allow?(roles) do |expectation|
69
- check_assert(expectation, options).tap do |result|
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 => namespace_name,
79
- :privilege => element_name,
96
+ :resource => resource_name,
97
+ :privilege => privilege_name,
80
98
  :roles => roles,
81
99
  :options => options
82
100
  }
83
101
 
84
- unless allowed
85
- log_payload[:failed_asserts] = failed_asserts.map(&:name)
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
@@ -1,3 +1,3 @@
1
1
  module AccessSchema
2
- VERSION = "0.3.5"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -9,7 +9,7 @@ describe AccessSchema::ConfigBuilder do
9
9
  schema :acl, :file => 'spec/schema_example.rb'
10
10
  end
11
11
 
12
- config.schema(:acl).plans.should_not be_nil
12
+ config.schema(:acl).roles.should_not be_nil
13
13
  end
14
14
 
15
15
  it "can specify logger" do
@@ -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
- plans do
11
- plan :none
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 plans" do
40
- @schema.plans.should == [:none, :bulb, :flower, :bouquet]
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 namespace" do
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
 
@@ -1,9 +1,12 @@
1
1
 
2
- plans do
3
- plan :none
4
- plan :bulb
5
- plan :flower
6
- plan :bouquet
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
- namespace "Review" do
24
+ resource "Review" do
18
25
 
19
- feature :mark_featured, [:flower, :bouquet]
26
+ privilege :mark_featured, [:flower, :bouquet]
20
27
 
21
- feature :add_photo, [:bouquet] do
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.3.5
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-23 00:00:00.000000000 Z
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/element_builder.rb
36
- - lib/access_schema/builders/namespace_builder.rb
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/namespace.rb
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: -1329279297250315893
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: -1329279297250315893
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
@@ -1,16 +0,0 @@
1
- module AccessSchema
2
- class Namespace
3
- attr_reader :name
4
- attr_reader :elements
5
-
6
- def initialize(name)
7
- @name = name
8
- @elements = []
9
- end
10
-
11
- def add_element(element)
12
- @elements << element
13
- end
14
-
15
- end
16
- end