consul 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of consul might be problematic. Click here for more details.

data/README.md CHANGED
@@ -1,19 +1,25 @@
1
- Consul - A scope-based authorization solution
2
- =============================================
1
+ Consul - A next gen authorization solution
2
+ ==========================================
3
3
 
4
4
  [![Build Status](https://secure.travis-ci.org/makandra/consul.png?branch=master)](https://travis-ci.org/makandra/consul)
5
5
 
6
- Consul is a authorization solution for Ruby on Rails that uses scopes to control what a user can see or edit.
6
+ Consul is a authorization solution for Ruby on Rails where you describe *sets of accessible things* to control what a user can see or edit.
7
7
 
8
8
  We have used Consul in combination with [assignable_values](https://github.com/makandra/assignable_values) to solve a variety of authorization requirements ranging from boring to bizarre.
9
-
10
9
  Also see our crash course video: [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/).
11
10
 
12
11
 
13
- Describing a power for your application
14
- ---------------------------------------
12
+ Describing access to your application
13
+ -------------------------------------
14
+
15
+ You describe access to your application by putting a `Power` model into `app/models/power.rb`.
16
+ Inside your `Power` you can talk about what is accessible for the current user, e.g.
17
+
18
+ - [A scope of records a user may see](#scope-powers-relations)
19
+ - [Whether the user is allowed to use a particular screen](#boolean-powers)
20
+ - [A list of values a user may assign to a particular attribute](#validating-assignable-values)
15
21
 
16
- You describe access to your application by putting a `Power` model into `app/models/power.rb`:
22
+ A `Power` might look like this:
17
23
 
18
24
  class Power
19
25
  include Consul::Power
@@ -22,46 +28,101 @@ You describe access to your application by putting a `Power` model into `app/mod
22
28
  @user = user
23
29
  end
24
30
 
25
- power :notes do
26
- Note.by_author(@user)
27
- end
28
-
29
31
  power :users do
30
32
  User if @user.admin?
31
33
  end
32
34
 
35
+ power :notes do
36
+ Note.by_author(@user)
37
+ end
38
+
33
39
  power :dashboard do
34
40
  true # not a scope, but a boolean power. This is useful to control access to stuff that doesn't live in the database.
35
41
  end
36
42
 
37
43
  end
38
44
 
39
- There are no restrictions on the name or constructor arguments of your power class.
45
+ There are no restrictions on the name or constructor arguments of your this class.
46
+
47
+ You can deposit all kinds of objects in your power. See the sections below for details.
40
48
 
41
49
 
42
- Querying a power
43
- ----------------
50
+ ### Scope powers (relations)
44
51
 
45
- Common things you might want from a power:
46
52
 
47
- 1. Get its scope
48
- 2. Ask whether it is there
49
- 3. Raise an error unless it its there
50
- 4. Ask whether a given record is included in its scope
51
- 5. Raise an error unless a given record is included in its scope
53
+ A typical use case in a Rails application is to restrict access to your ActiveRecord models. For example:
54
+
55
+ - Anonymous visitors may only see public posts
56
+ - Users may only see their own notes
57
+ - Only admins may edit users
58
+
59
+ You do this by making your powers return an ActiveRecord scope (or "relation"):
60
+
61
+ class Power
62
+ ...
63
+
64
+ power :notes do
65
+ Note.by_author(@user)
66
+ end
67
+
68
+ power :users do
69
+ User if @user.admin?
70
+ end
71
+
72
+ end
52
73
 
53
- Here is how to do all of that:
74
+ You can now query these powers in order to retrieve the scope:
54
75
 
55
76
  power = Power.new(user)
56
- power.notes # => returns an ActiveRecord::Scope
57
- power.notes? # => returns true if Power#notes returns a scope
58
- power.notes! # => raises Consul::Powerless unless Power#notes returns a scope
77
+ power.notes # => returns an ActiveRecord::Scope
78
+
79
+ Or you can ask if the power is given (meaning it's not `nil`):
80
+
81
+ power.notes? # => returns true if Power#notes returns a scope and not nil
82
+
83
+ Or you can raise an error unless a power its given, e.g. to guard access into a controller action:
84
+
85
+ power.notes? # => returns true if Power#notes returns a scope, even if it's empty
86
+
87
+ Or you ask whether a given record is included in its scope (can be [optimized](#optimizing-record-checks-for-scope-powers)):
88
+
59
89
  power.note?(Note.last) # => returns whether the given Note is in the Power#notes scope. Caches the result for subsequent queries.
90
+
91
+ Or you can raise an error unless a given record is included in its scope:
92
+
60
93
  power.note!(Note.last) # => raises Consul::Powerless unless the given Note is in the Power#notes scope
61
94
 
95
+ See our crash course video [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/) for many different use cases you can cover with this pattern.
96
+
62
97
 
63
- Boolean powers
64
- --------------
98
+
99
+ ### Defining different powers for different actions
100
+
101
+ If you have different access rights for e.g. viewing or updating posts, simply use different powers:
102
+
103
+
104
+ class Power
105
+ ...
106
+
107
+ power :notes do
108
+ Note.published
109
+ end
110
+
111
+ power :updatable_notes do
112
+ Note.by_author(@user)
113
+ end
114
+
115
+ power :destroyable_notes do
116
+ Note if @user.admin?
117
+ end
118
+
119
+ end
120
+
121
+ There is also a [shortcut to map different powers to RESTful controller actions](#protect-entry-into-controller-actions).
122
+
123
+
124
+
125
+ ### Boolean powers
65
126
 
66
127
  Boolean powers are useful to control access to stuff that doesn't live in the database:
67
128
 
@@ -76,12 +137,12 @@ Boolean powers are useful to control access to stuff that doesn't live in the da
76
137
 
77
138
  You can query it like the other powers:
78
139
 
140
+ power = Power.new(@user)
79
141
  power.dashboard? # => true
80
142
  power.dashboard! # => raises Consul::Powerless unless Power#dashboard? returns true
81
143
 
82
144
 
83
- Powers that give no access at all
84
- ---------------------------------
145
+ ### Powers that give no access at all
85
146
 
86
147
  Note that there is a difference between having access to an empty list of records, and having no access at all.
87
148
  If you want to express that a user has no access at all, make the respective power return `nil`.
@@ -99,15 +160,40 @@ Note how the power in the example below returns `nil` unless the user is an admi
99
160
 
100
161
  When a non-admin queries the `:users` power, she will get the following behavior:
101
162
 
102
- power.notes # => returns nil
103
- power.notes? # => returns false
104
- power.notes! # => raises Consul::Powerless
105
- power.note?(Note.last) # => returns false
106
- power.note!(Note.last) # => raises Consul::Powerless
163
+ power = Power.new(@user)
164
+ power.users # => returns nil
165
+ power.users? # => returns false
166
+ power.users! # => raises Consul::Powerless
167
+ power.user?(User.last) # => returns false
168
+ power.user!(User.last) # => raises Consul::Powerless
169
+
170
+
171
+
172
+ ### Powers that only check a given object
173
+
174
+ Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
175
+ checks whether a given object is accessible.
107
176
 
177
+ To do so, simply define a power that ends in a question mark:
108
178
 
109
- Other types of powers
110
- ---------------------
179
+
180
+ class Power
181
+ ...
182
+
183
+ power :updatable_post? do |post|
184
+ post.author == @user
185
+ end
186
+
187
+ end
188
+
189
+ You can query such an power as always:
190
+
191
+ power = Power.new(@user)
192
+ power.updatable_post?(Post.last) # return true if the author of the post is @user
193
+ power.updatable_post!(Post.last) # raises Consul::Powerless unless the author of the post is @user
194
+
195
+
196
+ ### Other types of powers
111
197
 
112
198
  A power can return any type of object. For instance, you often want to return an array:
113
199
 
@@ -134,23 +220,21 @@ You can query it like any other power. E.g. if a non-admin queries this power sh
134
220
  power.assignable_note_state!('published') # => raises Consul::Powerless
135
221
 
136
222
 
137
- Defining multiple powers at once
138
- --------------------------------
223
+ ### Defining multiple powers at once
139
224
 
140
225
  You can define multiple powers at once by giving multiple power names:
141
226
 
142
227
  class Power
143
228
  ...
144
229
 
145
- power :destroyable_users, updatable_users do
230
+ power :destroyable_users, :updatable_users do
146
231
  User if admin?
147
232
  end
148
233
 
149
234
  end
150
235
 
151
236
 
152
- Powers that require context (arguments)
153
- ---------------------------------------
237
+ ### Powers that require context (arguments)
154
238
 
155
239
  Sometimes it can be useful to define powers that require context. To do so, just take an argument in your `power` block:
156
240
 
@@ -164,11 +248,52 @@ Sometimes it can be useful to define powers that require context. To do so, just
164
248
  %w[committed started finished]
165
249
  end
166
250
  end
251
+
252
+ end
167
253
 
168
254
  When querying such a power, you always need to provide the context, e.g.:
169
255
 
170
256
  story = ...
171
- Power.current_assignable_story_state?(story, 'finished')
257
+ Power.current.assignable_story_state?(story, 'finished')
258
+
259
+
260
+ ### Optimizing record checks for scope powers
261
+
262
+ You can query a scope power for a given record, e.g.
263
+
264
+ class Power
265
+ ...
266
+
267
+ power :posts do |post|
268
+ Post.where(:author_id => @user.id)
269
+ end
270
+ end
271
+
272
+ power = Power.new(@user)
273
+ power.post?(Post.last)
274
+
275
+ What Consul does internally is fetch **all** the IDs of the `power.posts` scope and test if the given
276
+ record's ID is among them. This list of IDs is cached for subsequent calls, so you will only touch the database once.
277
+
278
+ As scary as it might sound, fetching all IDs of a scope scales quiet nicely for many thousand records. There will
279
+ however be the point where you want to optimize this.
280
+
281
+ What you can do in Consul is to define a second power that checks a given record in plain Ruby:
282
+
283
+ class Power
284
+ ...
285
+
286
+ power :posts do |post|
287
+ Post.where(:author_id => @user.id)
288
+ end
289
+
290
+ power :post? do |post|
291
+ post.author_id == @user.id
292
+ end
293
+
294
+ end
295
+
296
+ This way you do not need to touch the database at all.
172
297
 
173
298
 
174
299
  Role-based permissions
@@ -379,10 +504,10 @@ You can find a full list of available dynamic calls below:
379
504
  | Dynamic call | Equivalent |
380
505
  |---------------------------------------------------------|--------------------------------------------|
381
506
  | `Power.current.send(:notes)` | `Power.current.notes` |
382
- | `Power.current.include?(:notes)` | `Power.current.notes?` |
383
- | `Power.current.include!(:notes)` | `Power.current.notes!` |
384
- | `Power.current.include?(:notes, Note.last)` | `Power.current.note?(Note.last)` |
385
- | `Power.current.include!(:notes, Note.last)` | `Power.current.note!(Note.last)` |
507
+ | `Power.current.include_power?(:notes)` | `Power.current.notes?` |
508
+ | `Power.current.include_power!(:notes)` | `Power.current.notes!` |
509
+ | `Power.current.include_object?(:notes, Note.last)` | `Power.current.note?(Note.last)` |
510
+ | `Power.current.include_object!(:notes, Note.last)` | `Power.current.note!(Note.last)` |
386
511
  | `Power.current.for_record(Note.last)` | `Power.current.notes` |
387
512
  | `Power.current.for_record(:updatable, Note.last)` | `Power.current.updatable_notes` |
388
513
  | `Power.current.for_model(Note)` | `Power.current.notes` |
data/Rakefile CHANGED
@@ -31,7 +31,7 @@ namespace :all do
31
31
  desc "Bundle all spec apps"
32
32
  task :bundle do
33
33
  for_each_directory_of('spec/**/Gemfile') do |directory|
34
- system("cd #{directory} && rm -f Gemfile.lock && bundle install")
34
+ system("cd #{directory} && bundle install")
35
35
  end
36
36
  end
37
37
 
@@ -86,7 +86,7 @@ module Consul
86
86
  private
87
87
 
88
88
  define_method :check_power do
89
- send(power_method).include!(power_name_for_current_action)
89
+ send(power_method).include_power!(power_name_for_current_action)
90
90
  end
91
91
 
92
92
  if direct_access_method
@@ -7,48 +7,41 @@ module Consul
7
7
  base.send :include, Memoizer
8
8
  end
9
9
 
10
- def include?(name, *args)
11
- args = args.dup
10
+ private
12
11
 
13
- context, record = context_and_record_from_args(args, name)
12
+ def default_include_power?(power_name, *context)
13
+ # Everything that is not nil is considered as included
14
+ !!send(power_name, *context)
15
+ end
14
16
 
15
- power_value = send(name, *context)
16
- if record.nil?
17
- !!power_value
18
- else
19
- # record is given
20
- if power_value.nil?
21
- false
22
- elsif Util.scope?(power_value)
23
- if Util.scope_selects_all_records?(power_value)
24
- true
25
- else
26
- power_ids_name = self.class.power_ids_name(name)
27
- send(power_ids_name, *context).include?(record.id)
28
- end
29
- elsif Util.collection?(power_value)
30
- power_value.include?(record)
17
+ def default_include_object?(power_name, *args)
18
+ object = args.pop
19
+ context = args
20
+ power_value = send(power_name, *context)
21
+ if power_value.nil?
22
+ false
23
+ elsif Util.scope?(power_value)
24
+ if Util.scope_selects_all_records?(power_value)
25
+ true
31
26
  else
32
- raise Consul::NoCollection, "can only call #include? on a collection, but power was of type #{power_value.class.name}"
27
+ power_ids_name = self.class.power_ids_name(power_name)
28
+ send(power_ids_name, *context).include?(object.id)
33
29
  end
30
+ elsif Util.collection?(power_value)
31
+ power_value.include?(object)
32
+ else
33
+ raise Consul::NoCollection, "can only call #include_object? on a collection, but power was of type #{power_value.class.name}"
34
34
  end
35
35
  end
36
36
 
37
- def include!(*args)
38
- include?(*args) or raise Consul::Powerless.new("No power to #{args.inspect}")
37
+ def default_power_ids(power_name, *args)
38
+ scope = send(power_name, *args)
39
+ database_touched
40
+ scope.collect_ids
39
41
  end
40
42
 
41
- private
42
-
43
- def context_and_record_from_args(args, name)
44
- context_count = send(self.class.context_count_name(name))
45
- context = []
46
- context_count.times do
47
- arg = args.shift or raise Consul::InsufficientContext, "Insufficient context for parametrized power: #{name}"
48
- context << arg
49
- end
50
- record = args.shift
51
- [context, record]
43
+ def powerless!(*args)
44
+ raise Consul::Powerless.new("No power to #{[*args].inspect}")
52
45
  end
53
46
 
54
47
  def boolean_or_nil?(value)
@@ -89,28 +82,31 @@ module Consul
89
82
  self.current = old_power
90
83
  end
91
84
 
92
- private
85
+ def define_query_and_bang_methods(name, &query)
86
+ query_method = "#{name}?"
87
+ bang_method = "#{name}!"
88
+ define_method(query_method, &query)
89
+ define_method(bang_method) { |*args| send(query_method, *args) or powerless!(name, *args) }
90
+ end
93
91
 
94
92
  def define_power(name, &block)
95
- define_method(name, &block)
96
- define_method("#{name.to_s}?") { |*args| include?(name, *args) }
97
- define_method("#{name.to_s}!") { |*args| include!(name, *args) }
98
- define_method("#{name.to_s.singularize}?") { |*args| include?(name, *args) }
99
- define_method("#{name.to_s.singularize}!") { |*args| include!(name, *args) }
100
- context_count_method = context_count_name(name)
101
- define_method(context_count_method) { block.arity >= 0 ? block.arity : 0 }
102
- private context_count_method
103
- ids_method = power_ids_name(name)
104
- define_method(ids_method) do |*args|
105
- scope = send(name, *args)
106
- database_touched
107
- scope.collect_ids
93
+ name = name.to_s
94
+ if name.ends_with?('?')
95
+ name_without_suffix = name.chop
96
+ define_query_and_bang_methods(name_without_suffix, &block)
97
+ else
98
+ define_method(name, &block)
99
+ define_query_and_bang_methods(name) { |*args| default_include_power?(name, *args) }
100
+ if name.singularize != name
101
+ define_query_and_bang_methods(name.singularize) { |*args| default_include_object?(name, *args) }
102
+ end
103
+ ids_method = power_ids_name(name)
104
+ define_method(ids_method) { |*args| default_power_ids(name, *args) }
105
+ memoize ids_method
108
106
  end
109
- memoize ids_method
110
107
  name
111
108
  end
112
109
 
113
110
  end
114
-
115
111
  end
116
112
  end
@@ -4,18 +4,54 @@ module Consul
4
4
 
5
5
  module InstanceMethods
6
6
 
7
+ def include?(power_name, *args)
8
+ warn "#include? ist deprececated. Use #include_power? and #include_object? instead."
9
+ if args.size == 0
10
+ include_power?(power_name, *args)
11
+ else
12
+ include_object?(power_name, *args)
13
+ end
14
+ end
15
+
16
+ def include!(power_name, *args)
17
+ warn "#include! ist deprececated. Use #include_power! and #include_object! instead."
18
+ if args.size == 0
19
+ include_power!(power_name, *args)
20
+ else
21
+ include_object!(power_name, *args)
22
+ end
23
+ end
24
+
25
+ def include_power?(power_name, *context)
26
+ send("#{power_name}?", *context)
27
+ end
28
+
29
+ def include_power!(power_name, *context)
30
+ send("#{power_name}!", *context)
31
+ end
32
+
33
+ def include_object?(power_name, *context_and_object)
34
+ power_name = power_name.to_s
35
+ send("#{power_name.singularize}?", *context_and_object)
36
+ end
37
+
38
+ def include_object!(power_name, *context_and_object)
39
+ power_name = power_name.to_s
40
+ send("#{power_name.singularize}!", *context_and_object)
41
+ end
42
+
7
43
  def for_record(*args)
8
44
  send(name_for_record(*args))
9
45
  end
10
46
 
11
47
  def include_record?(*args)
12
48
  adjective, record = Util.adjective_and_argument(*args)
13
- include?(name_for_record(*args), record)
49
+ include_object?(name_for_record(*args), record)
14
50
  end
15
51
 
16
52
  def include_record!(*args)
17
53
  adjective, record = Util.adjective_and_argument(*args)
18
- include!(name_for_record(*args), record)
54
+ include_object!(name_for_record(*args), record)
19
55
  end
20
56
 
21
57
  def name_for_model(*args)
@@ -29,11 +65,11 @@ module Consul
29
65
  end
30
66
 
31
67
  def include_model?(*args)
32
- include?(name_for_model(*args))
68
+ include_power?(name_for_model(*args))
33
69
  end
34
70
 
35
71
  def include_model!(*args)
36
- include!(name_for_model(*args))
72
+ include_power!(name_for_model(*args))
37
73
  end
38
74
 
39
75
  def name_for_record(*args)
@@ -1,3 +1,3 @@
1
1
  module Consul
2
- VERSION = '0.8.0'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.7.0)
4
+ consul (0.8.0)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.7.0)
4
+ consul (0.8.0)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.7.0)
4
+ consul (0.8.0)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -13,10 +13,30 @@ class Power
13
13
  Client
14
14
  end
15
15
 
16
+ power :fast_clients do
17
+ Client.active
18
+ end
19
+
20
+ power :fast_client? do |client|
21
+ !client.deleted?
22
+ end
23
+
16
24
  power :client_notes do |client|
17
25
  client.notes
18
26
  end
19
27
 
28
+ power :fast_client_notes do |client|
29
+ client.notes
30
+ end
31
+
32
+ power :fast_client_note? do |client, note|
33
+ note.client_id == client.id
34
+ end
35
+
36
+ power :fast_client_note_without_collection? do |client, note|
37
+ note.client_id == client.id
38
+ end
39
+
20
40
  power :notes do
21
41
  Note.scoped(:joins => :client)
22
42
  end
@@ -24,7 +24,7 @@ describe Consul::Power do
24
24
 
25
25
  context 'nil powers' do
26
26
 
27
- describe '#include?' do
27
+ describe 'query methods' do
28
28
 
29
29
  context 'when no record is given' do
30
30
 
@@ -49,7 +49,7 @@ describe Consul::Power do
49
49
 
50
50
  end
51
51
 
52
- describe '#include!' do
52
+ describe 'bang methods' do
53
53
 
54
54
  context 'when no record is given' do
55
55
 
@@ -86,7 +86,7 @@ describe Consul::Power do
86
86
  @user.power.client_notes(@client1).should == [@client1_note1, @client1_note2]
87
87
  end
88
88
 
89
- describe '#include?' do
89
+ describe 'query methods' do
90
90
 
91
91
  context 'when no record is given' do
92
92
 
@@ -137,19 +137,55 @@ describe Consul::Power do
137
137
  @user.power.client_note?(@client1, @client2_note1).should be_false
138
138
  end
139
139
 
140
- end
140
+ context 'optimization through additional definition of a Ruby method' do
141
+
142
+ it 'should not affect collection access' do
143
+ @user.power.fast_clients.to_a.should =~ [@client1, @client2]
144
+ @user.power.fast_client_ids.to_a.should =~ [@client1.id, @client2.id]
145
+ @user.power.fast_clients?.should be_true
146
+ end
147
+
148
+ it 'should no longer access the database when checking inclusion of a single record' do
149
+ @user.power.should_not_receive(:database_touched)
150
+ @user.power.fast_client?(@client1).should be_true
151
+ @user.power.fast_client?(@deleted_client).should be_false
152
+ end
141
153
 
142
- context 'when a power with arguments is given insufficient context' do
154
+ it 'is used by and bang methods' do
155
+ @user.power.should_not_receive(:database_touched)
156
+ expect { @user.power.fast_client!(@client1) }.to_not raise_error
157
+ expect { @user.power.fast_client!(@deleted_client) }.to raise_error(Consul::Powerless)
158
+ end
159
+
160
+ it 'works with parametrized powers' do
161
+ @user.power.should_not_receive(:database_touched)
162
+ @user.power.fast_client_note?(@client1, @client1_note1).should be_true
163
+ @user.power.fast_client_note?(@client1, @client2_note1).should be_false
164
+ expect { @user.power.fast_client_note!(@client1, @client1_note1) }.to_not raise_error
165
+ expect { @user.power.fast_client_note!(@client1, @client2_note1) }.to raise_error(Consul::Powerless)
166
+ end
167
+
168
+ it 'works when only the optimized power is defined, without a collection power' do
169
+ @user.power.should_not_receive(:database_touched)
170
+ @user.power.fast_client_note_without_collection?(@client1, @client1_note1).should be_true
171
+ @user.power.fast_client_note_without_collection?(@client1, @client2_note1).should be_false
172
+ end
143
173
 
144
- it 'should raise an error' do
145
- expect { @user.power.client_notes? }.to raise_error(Consul::InsufficientContext)
146
174
  end
147
175
 
148
176
  end
149
177
 
178
+ #context 'when a power with arguments is given insufficient context' do
179
+ #
180
+ # it 'should raise an error' do
181
+ # expect { @user.power.client_notes? }.to raise_error(ArgumentError)
182
+ # end
183
+ #
184
+ #end
185
+
150
186
  end
151
187
 
152
- describe '#include!' do
188
+ describe 'bang methods' do
153
189
 
154
190
  context 'when no record is given' do
155
191
 
@@ -207,7 +243,7 @@ describe Consul::Power do
207
243
  @user.power.key_figures.should == %w[amount working_costs]
208
244
  end
209
245
 
210
- describe '#include?' do
246
+ describe 'query methods' do
211
247
 
212
248
  context 'when no record is given' do
213
249
 
@@ -237,7 +273,7 @@ describe Consul::Power do
237
273
 
238
274
  end
239
275
 
240
- describe '#include!' do
276
+ describe 'bang methods' do
241
277
 
242
278
  context 'when no record is given' do
243
279
 
@@ -275,7 +311,7 @@ describe Consul::Power do
275
311
  @user.power.always_false.should == false
276
312
  end
277
313
 
278
- describe '#include?' do
314
+ describe 'query methods' do
279
315
 
280
316
  context 'when no record is given' do
281
317
 
@@ -295,15 +331,15 @@ describe Consul::Power do
295
331
 
296
332
  context 'with a given record' do
297
333
 
298
- it 'should raise Consul::NoCollection' do
299
- expect { @user.power.always_true?('foo') }.to raise_error(Consul::NoCollection)
300
- end
334
+ #it 'should raise Consul::NoCollection' do
335
+ # expect { @user.power.always_true?('foo') }.to raise_error(Consul::NoCollection)
336
+ #end
301
337
 
302
338
  end
303
339
 
304
340
  end
305
341
 
306
- describe '#include!' do
342
+ describe 'bang methods' do
307
343
 
308
344
  context 'when no record is given' do
309
345
 
@@ -323,9 +359,10 @@ describe Consul::Power do
323
359
 
324
360
  context 'with a given record' do
325
361
 
326
- it 'should raise Consul::NoCollection' do
327
- expect { @user.power.always_true!('foo') }.to raise_error(Consul::NoCollection)
328
- end
362
+ #it 'should raise Consul::NoCollection' do
363
+ # expect { @user.power.always_true!('foo') }.to raise_error(Consul::NoCollection)
364
+ #end
365
+
329
366
  end
330
367
 
331
368
  end
@@ -339,7 +376,7 @@ describe Consul::Power do
339
376
  @user.power.api_key.should == 'secret-api-key'
340
377
  end
341
378
 
342
- describe '#include?' do
379
+ describe 'query methods' do
343
380
 
344
381
  context 'when no record is given' do
345
382
 
@@ -357,15 +394,15 @@ describe Consul::Power do
357
394
 
358
395
  context 'with a given record' do
359
396
 
360
- it 'should raise Consul::NoCollection' do
361
- expect { @user.power.api_key?('foo') }.to raise_error(Consul::NoCollection)
362
- end
397
+ #it 'should raise Consul::NoCollection' do
398
+ # expect { @user.power.api_key?('foo') }.to raise_error(Consul::NoCollection)
399
+ #end
363
400
 
364
401
  end
365
402
 
366
403
  end
367
404
 
368
- describe '#include!' do
405
+ describe 'bang methods' do
369
406
 
370
407
  context 'when no record is given' do
371
408
 
@@ -383,9 +420,9 @@ describe Consul::Power do
383
420
 
384
421
  context 'with a given record' do
385
422
 
386
- it 'should raise Consul::NoCollection' do
387
- expect { @user.power.api_key!('foo') }.to raise_error(Consul::NoCollection)
388
- end
423
+ #it 'should raise Consul::NoCollection' do
424
+ # expect { @user.power.api_key!('foo') }.to raise_error(Consul::NoCollection)
425
+ #end
389
426
 
390
427
  end
391
428
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consul
3
3
  version: !ruby/object:Gem::Version
4
- hash: 63
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 8
8
+ - 9
9
9
  - 0
10
- version: 0.8.0
10
+ version: 0.9.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Henning Koch
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-05-22 00:00:00 +02:00
18
+ date: 2013-07-19 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency