consul 0.3.0 → 0.4.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.

Files changed (53) hide show
  1. data/README.md +49 -2
  2. data/Rakefile +26 -6
  3. data/consul.gemspec +8 -7
  4. data/lib/consul.rb +1 -0
  5. data/lib/consul/active_record.rb +5 -1
  6. data/lib/consul/controller.rb +18 -11
  7. data/lib/consul/errors.rb +1 -0
  8. data/lib/consul/power.rb +29 -4
  9. data/lib/consul/version.rb +1 -1
  10. data/spec/rails-2.3/Gemfile +12 -0
  11. data/spec/rails-2.3/Rakefile +11 -0
  12. data/spec/{app_root → rails-2.3/app_root}/app/controllers/application_controller.rb +0 -0
  13. data/spec/{app_root → rails-2.3/app_root}/app/controllers/cakes_controller.rb +0 -0
  14. data/spec/{app_root → rails-2.3/app_root}/app/controllers/dashboards_controller.rb +0 -0
  15. data/spec/{app_root → rails-2.3/app_root}/app/controllers/risks_controller.rb +0 -0
  16. data/spec/{app_root → rails-2.3/app_root}/app/controllers/songs_controller.rb +0 -0
  17. data/spec/{app_root → rails-2.3/app_root}/app/controllers/users_controller.rb +0 -0
  18. data/spec/{app_root → rails-2.3/app_root}/app/models/client.rb +0 -0
  19. data/spec/{app_root → rails-2.3/app_root}/app/models/note.rb +0 -0
  20. data/spec/{app_root → rails-2.3/app_root}/app/models/power.rb +25 -1
  21. data/spec/{app_root → rails-2.3/app_root}/app/models/user.rb +0 -0
  22. data/spec/{app_root → rails-2.3/app_root}/config/boot.rb +14 -0
  23. data/spec/{app_root → rails-2.3/app_root}/config/database.yml +0 -0
  24. data/spec/{app_root → rails-2.3/app_root}/config/environment.rb +0 -0
  25. data/spec/{app_root → rails-2.3/app_root}/config/environments/in_memory.rb +0 -0
  26. data/spec/{app_root → rails-2.3/app_root}/config/environments/mysql.rb +0 -0
  27. data/spec/{app_root → rails-2.3/app_root}/config/environments/postgresql.rb +0 -0
  28. data/spec/{app_root → rails-2.3/app_root}/config/environments/sqlite.rb +0 -0
  29. data/spec/{app_root → rails-2.3/app_root}/config/environments/sqlite3.rb +0 -0
  30. data/spec/rails-2.3/app_root/config/preinitializer.rb +20 -0
  31. data/spec/{app_root → rails-2.3/app_root}/config/routes.rb +0 -0
  32. data/spec/{app_root → rails-2.3/app_root}/db/migrate/001_create_users.rb +0 -0
  33. data/spec/{app_root → rails-2.3/app_root}/db/migrate/002_create_clients.rb +0 -0
  34. data/spec/{app_root → rails-2.3/app_root}/db/migrate/003_create_notes.rb +0 -0
  35. data/spec/{app_root → rails-2.3/app_root}/lib/console_with_fixtures.rb +0 -0
  36. data/spec/rails-2.3/app_root/log/.gitignore +1 -0
  37. data/spec/{app_root → rails-2.3/app_root}/script/console +0 -0
  38. data/spec/{rcov.opts → rails-2.3/rcov.opts} +0 -0
  39. data/spec/{spec.opts → rails-2.3/spec.opts} +0 -0
  40. data/spec/{spec_helper.rb → rails-2.3/spec_helper.rb} +9 -6
  41. data/spec/{consul → shared/consul}/active_record_spec.rb +0 -0
  42. data/spec/shared/consul/power_spec.rb +361 -0
  43. data/spec/{controllers → shared/controllers}/cakes_controller_spec.rb +1 -1
  44. data/spec/{controllers → shared/controllers}/dashboards_controller_spec.rb +1 -1
  45. data/spec/{controllers → shared/controllers}/risks_controller_spec.rb +1 -1
  46. data/spec/{controllers → shared/controllers}/songs_controller_spec.rb +1 -1
  47. data/spec/shared/controllers/users_controller_spec.rb +25 -0
  48. metadata +46 -119
  49. data/Gemfile +0 -3
  50. data/spec/consul/power_spec.rb +0 -127
  51. data/spec/controllers/users_controller_spec.rb +0 -13
  52. data/spec/support/spec.opts +0 -4
  53. data/spec/support/spec_candy.rb +0 -179
data/README.md CHANGED
@@ -259,7 +259,7 @@ You can not only authorize scalar attributes like strings or integers that way,
259
259
  class Power
260
260
  ...
261
261
 
262
- def assignable_story_projects(story)
262
+ power :assignable_story_projects do |story|
263
263
  user.account.projects
264
264
  end
265
265
  end
@@ -269,6 +269,53 @@ The `authorize_values_for` macro comes with many useful options and details best
269
269
  assignable_values_for :field, :through => lambda { Power.current }
270
270
 
271
271
 
272
+ Testing
273
+ -------
274
+
275
+ This section Some hints for testing authorization with Consul.
276
+
277
+ ### Test that a controller checks against a power
278
+
279
+ You can say this in any controller spec:
280
+
281
+ describe CakesController do
282
+
283
+ it { should check_power(:cakes) }
284
+
285
+ end
286
+
287
+ You can test against all options of the `power` macro:
288
+
289
+ describe CakesController do
290
+
291
+ it { should check_power(:cakes, :map => { [:edit, :update] => :updatable_cakes }) }
292
+
293
+ end
294
+
295
+ ### Temporarily change the current power
296
+
297
+ When you set `Power.current` to a power in an RSpec example, you must remember to nilify it afterwards. Otherwise other examples will see your global changes.
298
+
299
+ A better way is to use the `.with_power` method to change the current power for the duration of a block:
300
+
301
+ admin = User.new(:role => 'admin')
302
+ admin_power = Power.new(admin)
303
+
304
+ Power.with_power(admin_power) do
305
+ # run code that uses Power.current
306
+ end
307
+
308
+ `Power.current` will be `nil` (or its former value) after the block has ended.
309
+
310
+ A nice shortcut is that when you call `with_power` with an argument that is not already a `Power`, Consul will instantiate a `Power` for you:
311
+
312
+ admin = User.new(:role => 'admin')
313
+
314
+ Power.with_power(admin) do
315
+ # run code that uses Power.current
316
+ end
317
+
318
+
272
319
  Installation
273
320
  ------------
274
321
 
@@ -292,7 +339,7 @@ If you would like to contribute:
292
339
  - Push your changes **with specs**.
293
340
  - Send me a pull request.
294
341
 
295
- I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](henning.koch@makandra.de).
342
+ I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:henning.koch@makandra.de).
296
343
 
297
344
 
298
345
  Credits
data/Rakefile CHANGED
@@ -1,12 +1,32 @@
1
1
  require 'rake'
2
- require 'spec/rake/spectask'
3
2
  require 'bundler/gem_tasks'
4
3
 
5
4
  desc 'Default: Run all specs.'
6
- task :default => :spec
5
+ task :default => 'all:spec'
7
6
 
8
- desc "Run all specs"
9
- Spec::Rake::SpecTask.new() do |t|
10
- t.spec_opts = ['--options', "\"spec/support/spec.opts\""]
11
- t.spec_files = FileList['spec/**/*_spec.rb']
7
+ namespace :all do
8
+
9
+ desc "Run specs on all spec apps"
10
+ task :spec do
11
+ for_each_directory_of('spec/**/Rakefile') do |directory|
12
+ env = "SPEC=../../#{ENV['SPEC']} " if ENV['SPEC']
13
+ system("cd #{directory} && #{env} bundle exec rake spec")
14
+ end
15
+ end
16
+
17
+ desc "Bundle all spec apps"
18
+ task :bundle do
19
+ for_each_directory_of('spec/**/Gemfile') do |directory|
20
+ system("cd #{directory} && bundle install")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ def for_each_directory_of(path, &block)
27
+ Dir[path].sort.each do |rakefile|
28
+ directory = File.dirname(rakefile)
29
+ puts '', "\033[44m#{directory}\033[0m", ''
30
+ block.call(directory)
31
+ end
12
32
  end
@@ -15,13 +15,14 @@ Gem::Specification.new do |s|
15
15
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  s.require_paths = ["lib"]
17
17
 
18
+ s.add_dependency('memoizer')
18
19
  s.add_dependency('rails')
19
- s.add_dependency('assignable_values')
20
20
 
21
- # s.add_development_dependency('assignable_values')
22
- s.add_development_dependency('rails', '~>2.3')
23
- s.add_development_dependency('rspec', '~>1.3')
24
- s.add_development_dependency('rspec-rails', '~>1.3')
25
- s.add_development_dependency('shoulda-matchers')
26
- s.add_development_dependency('sqlite3')
21
+ ## s.add_development_dependency('assignable_values')
22
+ #s.add_development_dependency('assignable_values')
23
+ #s.add_development_dependency('rails', '~>2.3')
24
+ #s.add_development_dependency('rspec', '~>1.3')
25
+ #s.add_development_dependency('rspec-rails', '~>1.3')
26
+ #s.add_development_dependency('shoulda-matchers')
27
+ #s.add_development_dependency('sqlite3')
27
28
  end
@@ -1,3 +1,4 @@
1
+ require 'memoizer'
1
2
  require 'consul/power'
2
3
  require 'consul/errors'
3
4
  require 'consul/controller'
@@ -4,7 +4,11 @@ module Consul
4
4
  private
5
5
 
6
6
  def authorize_values_for(property, options = {})
7
- assignable_values_for property, options.merge(:through => lambda { ::Power.current })
7
+ if defined?(AssignableValues)
8
+ assignable_values_for property, options.merge(:through => lambda { ::Power.current })
9
+ else
10
+ raise "To use .authorize_values_for, add the gem 'assignable_values' to your Gemfile"
11
+ end
8
12
  end
9
13
 
10
14
  end
@@ -69,17 +69,8 @@ module Consul
69
69
 
70
70
  before_filter :check_power, filter_options
71
71
 
72
- private
73
-
74
- define_method :check_power do
75
- send(power_method).include!(power_method_for_action)
76
- end
77
-
78
- define_method direct_access_method do
79
- send(power_method).send(power_method_for_action)
80
- end if direct_access_method
81
-
82
- define_method :power_method_for_action do
72
+ singleton_class.send(:define_method, :power_name_for_action) do |action_name|
73
+ action_name = action_name.to_s
83
74
  key = actions_map.keys.detect do |actions|
84
75
  Array(actions).collect(&:to_s).include?(action_name)
85
76
  end
@@ -92,6 +83,22 @@ module Consul
92
83
  end
93
84
  end
94
85
 
86
+ private
87
+
88
+ define_method :check_power do
89
+ send(power_method).include!(power_name_for_current_action)
90
+ end
91
+
92
+ if direct_access_method
93
+ define_method direct_access_method do
94
+ send(power_method).send(power_name_for_current_action)
95
+ end
96
+ end
97
+
98
+ define_method :power_name_for_current_action do
99
+ self.class.power_name_for_action(action_name)
100
+ end
101
+
95
102
  end
96
103
 
97
104
  end
@@ -4,4 +4,5 @@ module Consul
4
4
  class UncheckedPower < Error; end
5
5
  class UnmappedAction < Error; end
6
6
  class UnreachablePower < Error; end
7
+ class NoCollection < Error; end
7
8
  end
@@ -2,19 +2,25 @@ module Consul
2
2
  module Power
3
3
 
4
4
  def self.included(base)
5
- base.extend ActiveSupport::Memoizable
6
5
  base.extend ClassMethods
6
+ base.send :include, Memoizer
7
7
  end
8
8
 
9
9
  def include?(name, *args)
10
10
  args = args.dup
11
11
  record = args.shift
12
12
  power_value = send(name)
13
- if record.nil? || boolean_or_nil?(power_value)
13
+ if record.nil?
14
14
  !!power_value
15
15
  else
16
- power_ids_name = self.class.power_ids_name(name)
17
- send(power_ids_name, *args).include?(record.id)
16
+ if scope?(power_value)
17
+ power_ids_name = self.class.power_ids_name(name)
18
+ send(power_ids_name, *args).include?(record.id)
19
+ elsif collection?(power_value)
20
+ power_value.include?(record)
21
+ else
22
+ raise Consul::NoCollection, "can only call #include? on a collection, but power was of type #{power_value.class.name}"
23
+ end
18
24
  end
19
25
  end
20
26
 
@@ -28,6 +34,14 @@ module Consul
28
34
  [TrueClass, FalseClass, NilClass].include?(value.class)
29
35
  end
30
36
 
37
+ def scope?(value)
38
+ value.respond_to?(:scoped)
39
+ end
40
+
41
+ def collection?(value)
42
+ value.is_a?(Array) || value.is_a?(Set)
43
+ end
44
+
31
45
  module ClassMethods
32
46
 
33
47
  def power(name, &block)
@@ -57,6 +71,17 @@ module Consul
57
71
 
58
72
  attr_accessor :current
59
73
 
74
+ def with_power(inner_power, &block)
75
+ unless inner_power.is_a?(self)
76
+ inner_power = new(inner_power)
77
+ end
78
+ old_power = current
79
+ self.current = inner_power
80
+ block.call
81
+ ensure
82
+ self.current = old_power
83
+ end
84
+
60
85
  end
61
86
 
62
87
  end
@@ -1,3 +1,3 @@
1
1
  module Consul
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gem 'assignable_values'
4
+ gem 'rails', '~>2.3'
5
+ gem 'rspec', '~>1.3'
6
+ gem 'rspec-rails', '~>1.3'
7
+ gem 'shoulda-matchers'
8
+ gem 'sqlite3'
9
+ gem 'rspec_candy'
10
+ gem 'ruby-debug'
11
+
12
+ gem 'consul', :path => '../..'
@@ -0,0 +1,11 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ desc 'Default: Run all specs for a specific rails version.'
5
+ task :default => :spec
6
+
7
+ desc "Run all specs for a specific rails version"
8
+ Spec::Rake::SpecTask.new() do |t|
9
+ t.spec_opts = ['--options', "\"spec.opts\""]
10
+ t.spec_files = defined?(SPEC) ? SPEC : FileList['**/*_spec.rb', '../shared/**/*_spec.rb']
11
+ end
@@ -6,7 +6,7 @@ class Power
6
6
  end
7
7
 
8
8
  power :clients do
9
- Client.active
9
+ Client.active unless guest?
10
10
  end
11
11
 
12
12
  power :client_notes do |client|
@@ -49,4 +49,28 @@ class Power
49
49
  %w[guest admin]
50
50
  end
51
51
 
52
+ power :key_figures do
53
+ %w[amount working_costs] unless guest?
54
+ end
55
+
56
+ power :api_key do
57
+ 'secret-api-key' unless guest?
58
+ end
59
+
60
+ private
61
+
62
+ attr_accessor :user
63
+
64
+ def role
65
+ user.role
66
+ end
67
+
68
+ def admin?
69
+ user.role == 'admin'
70
+ end
71
+
72
+ def guest?
73
+ user.role == 'guest'
74
+ end
75
+
52
76
  end
@@ -110,5 +110,19 @@ module Rails
110
110
  end
111
111
  end
112
112
 
113
+ class Rails::Boot
114
+ def run
115
+ load_initializer
116
+
117
+ Rails::Initializer.class_eval do
118
+ def load_gems
119
+ @bundler_loaded ||= Bundler.require :default, Rails.env
120
+ end
121
+ end
122
+
123
+ Rails::Initializer.run(:set_load_path)
124
+ end
125
+ end
126
+
113
127
  # All that for this:
114
128
  Rails.boot!
@@ -0,0 +1,20 @@
1
+ begin
2
+ require "rubygems"
3
+ require "bundler"
4
+ rescue LoadError
5
+ raise "Could not load the bundler gem. Install it with `gem install bundler`."
6
+ end
7
+
8
+ if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24")
9
+ raise RuntimeError, "Your bundler version is too old for Rails 2.3." +
10
+ "Run `gem install bundler` to upgrade."
11
+ end
12
+
13
+ begin
14
+ # Set up load paths for all bundled gems
15
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
16
+ Bundler.setup
17
+ rescue Bundler::GemNotFound
18
+ raise RuntimeError, "Bundler couldn't find some gems." +
19
+ "Did you run `bundle install`?"
20
+ end
File without changes
File without changes
@@ -7,12 +7,15 @@ ENV['RAILS_ENV'] ||= 'in_memory'
7
7
  require "#{File.dirname(__FILE__)}/app_root/config/environment"
8
8
  require 'spec/rails'
9
9
 
10
- # Load dependencies
11
- require 'assignable_values'
12
- require 'shoulda-matchers'
13
-
14
- # Load the gem itself
15
- require "#{File.dirname(__FILE__)}/../lib/consul"
10
+ ### Load dependencies
11
+ #require 'memoizer'
12
+ #require 'shoulda-matchers'
13
+ #require 'assignable_values'
14
+ #
15
+ ## Load the gem itself
16
+ #require "#{File.dirname(__FILE__)}/../../lib/consul"
17
+
18
+ require 'rspec_candy/helpers'
16
19
 
17
20
  # Undo changes to RAILS_ENV
18
21
  silence_warnings {RAILS_ENV = ENV['RAILS_ENV']}