be9-acl9 0.9.2 → 0.9.3

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/CHANGELOG.textile CHANGED
@@ -1,3 +1,9 @@
1
+ h2. 0.9.3 (04-Feb-2009)
2
+
3
+ * Fix bug in delete_role - didn't work with custom class names
4
+ * Add @:helper@ option for @access_control@.
5
+ * Ability to generate helper methods directly (place @include Acl9Helpers@ in your helper module).
6
+
1
7
  h2. 0.9.2 (11-Jan-2009)
2
8
 
3
9
  * @access_control :method do end@ as shorter form for @access_control :as_method => :method do end@.
data/Manifest CHANGED
@@ -1,22 +1,26 @@
1
- init.rb
2
- Manifest
3
- lib/acl9/model_extensions.rb
4
- lib/acl9/version.rb
1
+ lib/acl9/helpers.rb
2
+ lib/acl9/config.rb
5
3
  lib/acl9/model_extensions/subject.rb
6
4
  lib/acl9/model_extensions/object.rb
5
+ lib/acl9/controller_extensions.rb
7
6
  lib/acl9/controller_extensions/generators.rb
8
7
  lib/acl9/controller_extensions/dsl_base.rb
9
- lib/acl9/config.rb
10
- lib/acl9/controller_extensions.rb
8
+ lib/acl9/version.rb
9
+ lib/acl9/model_extensions.rb
11
10
  lib/acl9.rb
12
- README.textile
13
- acl9.gemspec
14
- CHANGELOG.textile
15
- MIT-LICENSE
16
- Rakefile
11
+ TODO
17
12
  spec/db/schema.rb
18
- spec/dsl_base_spec.rb
13
+ spec/helpers_spec.rb
19
14
  spec/spec_helper.rb
15
+ spec/models.rb
16
+ spec/dsl_base_spec.rb
20
17
  spec/access_control_spec.rb
18
+ spec/controllers.rb
21
19
  spec/roles_spec.rb
22
- spec/models.rb
20
+ acl9.gemspec
21
+ Manifest
22
+ MIT-LICENSE
23
+ Rakefile
24
+ README.textile
25
+ init.rb
26
+ CHANGELOG.textile
data/README.textile CHANGED
@@ -763,6 +763,33 @@ you may not only call @lolcats?@ with no arguments, which will basically return
763
763
  but also as @lolcats?(:lol => Lol.find(params[:lol]))@. The hash will be looked into first,
764
764
  even if you have an instance variable @lol@.
765
765
 
766
+ h3. :helper
767
+
768
+ Sometimes you want to have a boolean method (like @:filter => false@) accessible
769
+ in your views. Acl9 can call @helper_method@ for you:
770
+
771
+ <pre><code>
772
+ class LolController < ApplicationController
773
+ access_control :helper => :lolcats? do
774
+ allow :cats, :by => :lol
775
+ # ...
776
+ end
777
+ end
778
+ </code></pre>
779
+
780
+ That's equivalent to
781
+
782
+ <pre><code>
783
+ class LolController < ApplicationController
784
+ access_control :lolcats?, :filter => false do
785
+ allow :cats, :by => :lol
786
+ # ...
787
+ end
788
+
789
+ helper_method :lolcats?
790
+ end
791
+ </code></pre>
792
+
766
793
  h3. Other options
767
794
 
768
795
  Other options will be passed to @before_filter@. As such, you may use @:only@ and @:except@ to narrow
@@ -796,6 +823,32 @@ is basically equivalent to
796
823
  end
797
824
  </code></pre>
798
825
 
826
+ h2. access_control in your helpers
827
+
828
+ Apart from using @:helper@ option for @access_control@ call inside controller, there's a
829
+ way to generate helper methods directly, like this:
830
+
831
+ <pre><code>
832
+ module SettingsHelper
833
+ include Acl9Helpers
834
+
835
+ access_control :show_settings? do
836
+ allow :admin
837
+ allow :settings_manager
838
+ end
839
+ end
840
+ </code></pre>
841
+
842
+ Here we mix in @Acl9Helpers@ module which brings in @access_control@ method and call it,
843
+ obtaining @show_settings?@ method.
844
+
845
+ An imaginary view:
846
+
847
+ <pre><code>
848
+ <% if show_settings? %>
849
+ <%= link_to 'Settings', settings_path %>
850
+ <% end %>
851
+ </code></pre>
799
852
 
800
853
  Copyright (c) 2009 Oleg Dashevskii, released under the MIT license.
801
854
 
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ begin
17
17
  p.summary = "Yet another role-based authorization system for Rails with a nice DSL for access control lists."
18
18
  p.url = "http://github.com/be9/acl9"
19
19
  p.ignore_pattern = ["spec/db/*.sqlite3", "spec/debug.log"]
20
- p.development_dependencies = ["rspec >=1.1.11", "rspec-rails >=1.1.11"]
20
+ p.development_dependencies = ["rspec >=1.1.12", "rspec-rails >=1.1.12"]
21
21
  end
22
22
  rescue LoadError => boom
23
23
  puts "You are missing a dependency required for meta-operations on this gem."
data/TODO ADDED
@@ -0,0 +1,42 @@
1
+ * Complex roles with ANDing.
2
+
3
+ Something like:
4
+
5
+ access_control do
6
+ allow all, :except => :destroy
7
+ allow complex_role, :to => :destroy do
8
+ is :strong
9
+ is :decisive
10
+ is :owner, :of => :object
11
+ is_not :banned
12
+ is_not :fake
13
+ end
14
+ end
15
+
16
+ * Acl9-based menu generator.
17
+
18
+ If you get Access Denied on /secrets/index, probably you shouldn't see "Secrets" item
19
+ in the menu at all.
20
+
21
+ It can be very DRY. Say, we introduce :menu => true option to access_control method which
22
+ will make it register a lambda (can see/cannot see) in some global hash (indexed by controller name).
23
+
24
+ Then, given an URL, you'll be able to check it against this hash. /secrets/index is mapped to
25
+ SecretsController#index, so you run access_control_hash['SecretsController'].call('index') and
26
+ show the link only if true is returned.
27
+
28
+ The problem here is with objects. SecretsController's access_control block can reference instance
29
+ variables during the permission check, but we have only current instantiated controller which can be any.
30
+
31
+ Another option is to distinguish visible part from access control part.
32
+
33
+ menu do
34
+ item 'Home', home_path
35
+ item 'Secrets', secrets_path do
36
+ allow :trusted
37
+ end
38
+
39
+ # ...
40
+ end
41
+
42
+ Here only "trusted" users will see "Secrets" item.
data/acl9.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{acl9}
5
- s.version = "0.9.2"
5
+ s.version = "0.9.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Oleg Dashevskii"]
9
- s.date = %q{2009-01-14}
9
+ s.date = %q{2009-02-04}
10
10
  s.description = %q{Yet another role-based authorization system for Rails with a nice DSL for access control lists.}
11
11
  s.email = %q{olegdashevskii@gmail.com}
12
- s.extra_rdoc_files = ["lib/acl9/model_extensions.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/config.rb", "lib/acl9/controller_extensions.rb", "lib/acl9.rb", "README.textile", "CHANGELOG.textile"]
13
- s.files = ["init.rb", "Manifest", "lib/acl9/model_extensions.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/config.rb", "lib/acl9/controller_extensions.rb", "lib/acl9.rb", "README.textile", "acl9.gemspec", "CHANGELOG.textile", "MIT-LICENSE", "Rakefile", "spec/db/schema.rb", "spec/dsl_base_spec.rb", "spec/spec_helper.rb", "spec/access_control_spec.rb", "spec/roles_spec.rb", "spec/models.rb"]
12
+ s.extra_rdoc_files = ["lib/acl9/helpers.rb", "lib/acl9/config.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions.rb", "lib/acl9.rb", "TODO", "README.textile", "CHANGELOG.textile"]
13
+ s.files = ["lib/acl9/helpers.rb", "lib/acl9/config.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions.rb", "lib/acl9.rb", "TODO", "spec/db/schema.rb", "spec/helpers_spec.rb", "spec/spec_helper.rb", "spec/models.rb", "spec/dsl_base_spec.rb", "spec/access_control_spec.rb", "spec/controllers.rb", "spec/roles_spec.rb", "acl9.gemspec", "Manifest", "MIT-LICENSE", "Rakefile", "README.textile", "init.rb", "CHANGELOG.textile"]
14
14
  s.has_rdoc = true
15
15
  s.homepage = %q{http://github.com/be9/acl9}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acl9", "--main", "README.textile"]
@@ -24,14 +24,14 @@ Gem::Specification.new do |s|
24
24
  s.specification_version = 2
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
- s.add_development_dependency(%q<rspec>, [">= 1.1.11"])
28
- s.add_development_dependency(%q<rspec-rails>, [">= 1.1.11"])
27
+ s.add_development_dependency(%q<rspec>, [">= 1.1.12"])
28
+ s.add_development_dependency(%q<rspec-rails>, [">= 1.1.12"])
29
29
  else
30
- s.add_dependency(%q<rspec>, [">= 1.1.11"])
31
- s.add_dependency(%q<rspec-rails>, [">= 1.1.11"])
30
+ s.add_dependency(%q<rspec>, [">= 1.1.12"])
31
+ s.add_dependency(%q<rspec-rails>, [">= 1.1.12"])
32
32
  end
33
33
  else
34
- s.add_dependency(%q<rspec>, [">= 1.1.11"])
35
- s.add_dependency(%q<rspec-rails>, [">= 1.1.11"])
34
+ s.add_dependency(%q<rspec>, [">= 1.1.12"])
35
+ s.add_dependency(%q<rspec-rails>, [">= 1.1.12"])
36
36
  end
37
37
  end
data/lib/acl9.rb CHANGED
@@ -9,6 +9,8 @@ end
9
9
 
10
10
  if defined? ActionController::Base
11
11
  require File.join(File.dirname(__FILE__), 'acl9', 'controller_extensions')
12
+ require File.join(File.dirname(__FILE__), 'acl9', 'helpers')
12
13
 
13
14
  ActionController::Base.send(:include, Acl9::ControllerExtensions)
15
+ Acl9Helpers = Acl9::Helpers unless defined?(Acl9Helpers)
14
16
  end
@@ -8,11 +8,7 @@ module Acl9
8
8
 
9
9
  module ClassMethods
10
10
  def access_control(*args, &block)
11
- opts = if args.last.is_a? Hash
12
- args.pop
13
- else
14
- {}
15
- end
11
+ opts = args.extract_options!
16
12
 
17
13
  case args.size
18
14
  when 0 then true
@@ -22,20 +18,33 @@ module Acl9
22
18
  if meth.is_a? Symbol
23
19
  opts[:as_method] = meth
24
20
  else
25
- raise ArgumentError, "access control argument must be a :symbol!"
21
+ raise ArgumentError, "access_control argument must be a :symbol!"
26
22
  end
27
23
  else
28
24
  raise ArgumentError, "Invalid arguments for access_control"
29
25
  end
30
26
 
31
- subject_method = opts.delete(:subject_method) || Acl9::config[:default_subject_method]
27
+ subject_method = opts[:subject_method] || Acl9::config[:default_subject_method]
32
28
 
33
29
  raise ArgumentError, "Block must be supplied to access_control" unless block
34
30
 
35
- filter = opts.delete(:filter)
31
+ filter = opts[:filter]
36
32
  filter = true if filter.nil?
37
33
 
38
- method = opts.delete(:as_method)
34
+ case helper = opts[:helper]
35
+ when true
36
+ raise ArgumentError, "you should specify :helper => :method_name" if !opts[:as_method]
37
+ when nil then nil
38
+ else
39
+ if opts[:as_method]
40
+ raise ArgumentError, "you can't specify both method name and helper name"
41
+ else
42
+ opts[:as_method] = helper
43
+ filter = false
44
+ end
45
+ end
46
+
47
+ method = opts[:as_method]
39
48
 
40
49
  generator = case
41
50
  when method && filter
@@ -48,12 +57,6 @@ module Acl9
48
57
 
49
58
  generator.acl_block!(&block)
50
59
 
51
- if opts.delete(:debug)
52
- Rails::logger.debug "=== Acl9 access_control expression dump (#{self.to_s})"
53
- Rails::logger.debug generator.to_s
54
- Rails::logger.debug "======"
55
- end
56
-
57
60
  generator.install_on(self, opts)
58
61
  end
59
62
  end
@@ -34,6 +34,16 @@ module Acl9
34
34
  def _controller_ref
35
35
  @controller ? "#{@controller}." : ''
36
36
  end
37
+
38
+ def install_on(controller_class, options)
39
+ debug_dump(controller_class) if options[:debug]
40
+ end
41
+
42
+ def debug_dump(klass)
43
+ Rails::logger.debug "=== Acl9 access_control expression dump (#{klass.to_s})"
44
+ Rails::logger.debug self.to_s
45
+ Rails::logger.debug "======"
46
+ end
37
47
  end
38
48
 
39
49
  class FilterLambda < BaseGenerator
@@ -44,6 +54,8 @@ module Acl9
44
54
  end
45
55
 
46
56
  def install_on(controller_class, options)
57
+ super
58
+
47
59
  controller_class.send(:before_filter, options, &self.to_proc)
48
60
  end
49
61
 
@@ -71,6 +83,7 @@ module Acl9
71
83
  end
72
84
 
73
85
  def install_on(controller_class, options)
86
+ super
74
87
  _add_method(controller_class)
75
88
  controller_class.send(:before_filter, @method_name, options)
76
89
  end
@@ -96,8 +109,14 @@ module Acl9
96
109
  end
97
110
 
98
111
  class BooleanMethod < FilterMethod
99
- def install_on(controller_class, *_)
112
+ def install_on(controller_class, opts)
113
+ debug_dump(controller_class) if opts[:debug]
114
+
100
115
  _add_method(controller_class)
116
+
117
+ if opts[:helper]
118
+ controller_class.send(:helper_method, @method_name)
119
+ end
101
120
  end
102
121
 
103
122
  protected
@@ -114,6 +133,14 @@ module Acl9
114
133
  "(options[:#{object}] || #{super})"
115
134
  end
116
135
  end
136
+
137
+ class HelperMethod < BooleanMethod
138
+ def initialize(subject_method, method)
139
+ super
140
+
141
+ @controller = 'controller'
142
+ end
143
+ end
117
144
  end
118
145
  end
119
146
  end
@@ -0,0 +1,19 @@
1
+ module Acl9
2
+ module Helpers
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def access_control(method, opts = {}, &block)
9
+ subject_method = opts.delete(:subject_method) || Acl9::config[:default_subject_method]
10
+ raise ArgumentError, "Block must be supplied to access_control" unless block
11
+
12
+ generator = Acl9::Dsl::Generators::HelperMethod.new(subject_method, method)
13
+
14
+ generator.acl_block!(&block)
15
+ generator.install_on(self, opts)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -93,7 +93,7 @@ module Acl9
93
93
  if role
94
94
  self.roles.delete role
95
95
 
96
- role.destroy if role.users.empty?
96
+ role.destroy if role.send(self.class.to_s.tableize).empty?
97
97
  end
98
98
  end
99
99
 
data/lib/acl9/version.rb CHANGED
@@ -44,7 +44,7 @@ module Acl9 # :nodoc:
44
44
 
45
45
  MAJOR = 0
46
46
  MINOR = 9
47
- TINY = 2
47
+ TINY = 3
48
48
 
49
49
  # The current version as a Version instance
50
50
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -1,93 +1,32 @@
1
1
  require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
  require File.join(File.dirname(__FILE__), '..', 'lib', 'acl9')
3
+ require File.join(File.dirname(__FILE__), 'controllers')
3
4
 
4
- class EmptyController < ActionController::Base
5
- attr_accessor :current_user
6
- before_filter :set_current_user
7
-
8
- [:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
9
- define_method(act) {}
10
- end
11
-
12
- private
13
-
14
- def set_current_user
15
- if params[:user]
16
- self.current_user = params[:user]
17
- end
18
- end
19
- end
20
-
21
- class Admin
22
- def has_role?(role, obj = nil)
23
- role == "admin"
24
- end
25
- end
26
-
27
- # all these controllers behave the same way
28
-
29
- class ACLBlock < EmptyController
30
- access_control do
31
- allow all, :to => [:index, :show]
32
- allow :admin
33
- end
34
- end
35
-
36
- class ACLMethod < EmptyController
37
- access_control :as_method => :acl do
38
- allow all, :to => [:index, :show]
39
- allow :admin, :except => [:index, :show]
40
- end
41
- end
42
-
43
- class ACLMethod2 < EmptyController
44
- access_control :acl do
45
- allow all, :to => [:index, :show]
46
- allow :admin, :except => [:index, :show]
47
- end
48
- end
49
-
50
- class ACLArguments < EmptyController
51
- access_control :except => [:index, :show] do
52
- allow :admin
53
- end
54
- end
55
-
56
- class ACLBooleanMethod < EmptyController
57
- access_control :acl, :filter => false do
58
- allow all, :to => [:index, :show]
59
- allow :admin
60
- end
61
-
62
- before_filter :check_acl
63
-
64
- def check_acl
65
- if self.acl
66
- true
67
- else
68
- raise Acl9::AccessDenied
5
+ describe "permit anonymous to index and show and admin everywhere else", :shared => true do
6
+ class Admin
7
+ def has_role?(role, obj = nil)
8
+ role == "admin"
69
9
  end
70
10
  end
71
- end
72
11
 
73
- describe "permit anonymous to index and show and admin everywhere else", :shared => true do
74
12
  [:index, :show].each do |act|
75
13
  it "should permit anonymous to #{act}" do
76
14
  get act
15
+ response.body.should == 'OK'
77
16
  end
78
17
  end
79
18
 
80
19
  [:new, :edit, :update, :delete, :destroy].each do |act|
81
20
  it "should forbid anonymous to #{act}" do
82
- lambda do
83
- get act
84
- end.should raise_error(Acl9::AccessDenied)
21
+ get act
22
+ response.body.should == 'AccessDenied'
85
23
  end
86
24
  end
87
25
 
88
26
  [:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
89
27
  it "should permit admin to #{act}" do
90
28
  get act, :user => Admin.new
29
+ response.body.should == 'OK'
91
30
  end
92
31
  end
93
32
  end
@@ -120,29 +59,6 @@ describe ACLBooleanMethod, :type => :controller do
120
59
  it_should_behave_like "permit anonymous to index and show and admin everywhere else"
121
60
  end
122
61
 
123
- class MyDearFoo
124
- include Singleton
125
- end
126
-
127
- class VenerableBar; end
128
-
129
- class ACLIvars < EmptyController
130
- before_filter :set_ivars
131
-
132
- access_control do
133
- action :destroy do
134
- allow :owner, :of => :foo
135
- allow :bartender, :at => VenerableBar
136
- end
137
- end
138
-
139
- private
140
-
141
- def set_ivars
142
- @foo = MyDearFoo.instance
143
- end
144
- end
145
-
146
62
  describe ACLIvars, :type => :controller do
147
63
  class OwnerOfFoo
148
64
  def has_role?(role, obj)
@@ -152,77 +68,68 @@ describe ACLIvars, :type => :controller do
152
68
 
153
69
  class Bartender
154
70
  def has_role?(role, obj)
155
- role == 'bartender' && obj == VenerableBar
71
+ role == 'bartender' && obj == ACLIvars::VenerableBar
156
72
  end
157
73
  end
158
74
 
159
75
  it "should allow owner of foo to destroy" do
160
76
  delete :destroy, :user => OwnerOfFoo.new
77
+ response.body.should == 'OK'
161
78
  end
162
79
 
163
80
  it "should allow bartender to destroy" do
164
81
  delete :destroy, :user => Bartender.new
82
+ response.body.should == 'OK'
165
83
  end
166
84
  end
167
85
 
168
- class TheOnlyUser
169
- include Singleton
170
-
171
- def has_role?(role, subj)
172
- role == "the_only_one"
173
- end
174
- end
175
-
176
- class ACLSubjectMethod < ActionController::Base
177
- access_control :subject_method => :the_only_user do
178
- allow :the_only_one
179
- end
180
-
181
- def index; end
182
-
183
- private
86
+ describe ACLSubjectMethod, :type => :controller do
87
+ class TheOnlyUser
88
+ include Singleton
184
89
 
185
- def the_only_user
186
- params[:user]
90
+ def has_role?(role, subj)
91
+ role == "the_only_one"
92
+ end
187
93
  end
188
- end
189
94
 
190
- describe ACLSubjectMethod, :type => :controller do
191
95
  it "should allow the only user to index" do
192
96
  get :index, :user => TheOnlyUser.instance
97
+ response.body.should == 'OK'
193
98
  end
194
99
 
195
100
  it "should deny anonymous to index" do
196
- lambda do
197
- get :index
198
- end.should raise_error(Acl9::AccessDenied)
101
+ get :index
102
+ response.body.should == 'AccessDenied'
199
103
  end
200
104
  end
201
105
 
202
- class ACLObjectsHash < ActionController::Base
203
- access_control :allowed?, :filter => false do
204
- allow :owner, :of => :foo
106
+ class FooOwner
107
+ def has_role?(role_name, obj)
108
+ role_name == 'owner' && obj == MyDearFoo.instance
205
109
  end
110
+ end
206
111
 
207
- def allow
208
- @foo = nil
209
- raise unless allowed?(:foo => MyDearFoo.instance)
112
+ describe ACLObjectsHash, :type => :controller do
113
+ it "should consider objects hash and prefer it to @ivar" do
114
+ get :allow, :user => FooOwner.new
115
+ response.body.should == 'OK'
210
116
  end
211
117
 
212
- def current_user
213
- params[:user]
118
+ it "should return AccessDenied when not logged in" do
119
+ get :allow
120
+ response.body.should == 'AccessDenied'
214
121
  end
215
122
  end
216
123
 
217
- describe ACLObjectsHash, :type => :controller do
218
- class FooOwner
219
- def has_role?(role_name, obj)
220
- role_name == 'owner' && obj == MyDearFoo.instance
221
- end
222
- end
223
-
224
- it "should consider objects hash and prefer it to @ivar" do
124
+ describe ACLHelperMethod, :type => :controller do
125
+ it "should return OK checking helper method" do
225
126
  get :allow, :user => FooOwner.new
127
+ response.body.should == 'OK'
128
+ end
129
+
130
+ it "should return AccessDenied when not logged in" do
131
+ get :allow
132
+ response.body.should == 'AccessDenied'
226
133
  end
227
134
  end
228
135
 
@@ -235,7 +142,7 @@ describe "Argument checking" do
235
142
 
236
143
  it "should raise ArgumentError without a block" do
237
144
  arg_err do
238
- class FailureController < ActionController::Base
145
+ class FailureController < ApplicationController
239
146
  access_control
240
147
  end
241
148
  end
@@ -243,7 +150,7 @@ describe "Argument checking" do
243
150
 
244
151
  it "should raise ArgumentError with 1st argument which is not a symbol" do
245
152
  arg_err do
246
- class FailureController < ActionController::Base
153
+ class FailureController < ApplicationController
247
154
  access_control 123 do end
248
155
  end
249
156
  end
@@ -251,9 +158,25 @@ describe "Argument checking" do
251
158
 
252
159
  it "should raise ArgumentError with more than 1 positional argument" do
253
160
  arg_err do
254
- class FailureController < ActionController::Base
161
+ class FailureController < ApplicationController
255
162
  access_control :foo, :bar do end
256
163
  end
257
164
  end
258
165
  end
166
+
167
+ it "should raise ArgumentError with :helper => true and no method name" do
168
+ arg_err do
169
+ class FailureController < ApplicationController
170
+ access_control :helper => true do end
171
+ end
172
+ end
173
+ end
174
+
175
+ it "should raise ArgumentError with :helper => :method and a method name" do
176
+ arg_err do
177
+ class FailureController < ApplicationController
178
+ access_control :meth, :helper => :another_meth do end
179
+ end
180
+ end
181
+ end
259
182
  end
@@ -0,0 +1,139 @@
1
+ class ApplicationController
2
+ rescue_from Acl9::AccessDenied do |e|
3
+ render :text => 'AccessDenied'
4
+ end
5
+ end
6
+
7
+ class EmptyController < ApplicationController
8
+ attr_accessor :current_user
9
+ before_filter :set_current_user
10
+
11
+ [:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
12
+ define_method(act) { render :text => 'OK' }
13
+ end
14
+
15
+ private
16
+
17
+ def set_current_user
18
+ if params[:user]
19
+ self.current_user = params[:user]
20
+ end
21
+ end
22
+ end
23
+
24
+ # all these controllers behave the same way
25
+
26
+ class ACLBlock < EmptyController
27
+ access_control :debug => true do
28
+ allow all, :to => [:index, :show]
29
+ allow :admin
30
+ end
31
+ end
32
+
33
+ class ACLMethod < EmptyController
34
+ access_control :as_method => :acl do
35
+ allow all, :to => [:index, :show]
36
+ allow :admin, :except => [:index, :show]
37
+ end
38
+ end
39
+
40
+ class ACLMethod2 < EmptyController
41
+ access_control :acl do
42
+ allow all, :to => [:index, :show]
43
+ allow :admin, :except => [:index, :show]
44
+ end
45
+ end
46
+
47
+ class ACLArguments < EmptyController
48
+ access_control :except => [:index, :show] do
49
+ allow :admin
50
+ end
51
+ end
52
+
53
+ class ACLBooleanMethod < EmptyController
54
+ access_control :acl, :filter => false do
55
+ allow all, :to => [:index, :show]
56
+ allow :admin
57
+ end
58
+
59
+ before_filter :check_acl
60
+
61
+ def check_acl
62
+ if self.acl
63
+ true
64
+ else
65
+ raise Acl9::AccessDenied
66
+ end
67
+ end
68
+ end
69
+
70
+ ###########################################
71
+ class MyDearFoo
72
+ include Singleton
73
+ end
74
+
75
+ class ACLIvars < EmptyController
76
+ class VenerableBar; end
77
+
78
+ before_filter :set_ivars
79
+
80
+ access_control do
81
+ action :destroy do
82
+ allow :owner, :of => :foo
83
+ allow :bartender, :at => VenerableBar
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ def set_ivars
90
+ @foo = MyDearFoo.instance
91
+ end
92
+ end
93
+
94
+ class ACLSubjectMethod < ApplicationController
95
+ access_control :subject_method => :the_only_user do
96
+ allow :the_only_one
97
+ end
98
+
99
+ def index
100
+ render :text => 'OK'
101
+ end
102
+
103
+ private
104
+
105
+ def the_only_user
106
+ params[:user]
107
+ end
108
+ end
109
+
110
+ class ACLObjectsHash < ApplicationController
111
+ access_control :allowed?, :filter => false do
112
+ allow :owner, :of => :foo
113
+ end
114
+
115
+ def allow
116
+ @foo = nil
117
+ render :text => (allowed?(:foo => MyDearFoo.instance) ? 'OK' : 'AccessDenied')
118
+ end
119
+
120
+ def current_user
121
+ params[:user]
122
+ end
123
+ end
124
+
125
+ class ACLHelperMethod < ApplicationController
126
+ access_control :helper => :foo? do
127
+ allow :owner, :of => :foo
128
+ end
129
+
130
+ def allow
131
+ @foo = MyDearFoo.instance
132
+
133
+ render :inline => "<%= foo? ? 'OK' : 'AccessDenied' %>"
134
+ end
135
+
136
+ def current_user
137
+ params[:user]
138
+ end
139
+ end
@@ -0,0 +1,92 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'acl9')
3
+
4
+ module SomeHelper
5
+ include Acl9Helpers
6
+
7
+ access_control :the_question do
8
+ allow :hamlet, :to => :be
9
+ allow :hamlet, :except => :be
10
+ end
11
+ end
12
+
13
+ describe SomeHelper do
14
+ module Hamlet
15
+ def current_user
16
+ user = Object.new
17
+
18
+ class <<user
19
+ def has_role?(role, obj=nil)
20
+ role == 'hamlet'
21
+ end
22
+ end
23
+
24
+ user
25
+ end
26
+ end
27
+
28
+ module NotLoggedIn
29
+ def current_user; nil end
30
+ end
31
+
32
+ module Noone
33
+ def current_user
34
+ user = Object.new
35
+
36
+ class <<user
37
+ def has_role?(*_); false end
38
+ end
39
+
40
+ user
41
+ end
42
+ end
43
+
44
+ class Base
45
+ include SomeHelper
46
+
47
+ attr_accessor :action_name
48
+ def controller
49
+ self
50
+ end
51
+ end
52
+
53
+ class Klass1 < Base
54
+ include Hamlet
55
+ end
56
+
57
+ class Klass2 < Base
58
+ include NotLoggedIn
59
+ end
60
+
61
+ class Klass3 < Base
62
+ include Noone
63
+ end
64
+
65
+ it "has :the_question method" do
66
+ Base.new.should respond_to(:the_question)
67
+ end
68
+
69
+ it "role :hamlet is allowed to be" do
70
+ k = Klass1.new
71
+ k.action_name = 'be'
72
+ k.the_question.should be_true
73
+ end
74
+
75
+ it "role :hamlet is allowed to not_be" do
76
+ k = Klass1.new
77
+ k.action_name = 'not_be'
78
+ k.the_question.should be_true
79
+ end
80
+
81
+ it "not logged in is not allowed to be" do
82
+ k = Klass2.new
83
+ k.action_name = 'be'
84
+ k.the_question.should == false
85
+ end
86
+
87
+ it "noone is not allowed to be" do
88
+ k = Klass3.new
89
+ k.action_name = 'be'
90
+ k.the_question.should == false
91
+ end
92
+ end
data/spec/roles_spec.rb CHANGED
@@ -256,5 +256,8 @@ describe "Roles with custom class names" do
256
256
 
257
257
  @subj.has_role?(:user, @foobar).should be_true
258
258
  @subj2.has_role?(:user, @foobar).should be_false
259
+
260
+ @subj.has_no_roles!
261
+ @subj2.has_no_roles!
259
262
  end
260
263
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'activesupport'
2
3
  require 'spec'
3
4
  require 'activerecord'
4
5
  require 'action_controller'
@@ -8,15 +9,22 @@ require 'action_controller/integration'
8
9
 
9
10
  require 'active_record/fixtures'
10
11
 
11
- class ApplicationController < ActionController::Base
12
- end
13
-
14
12
  require 'rails/version'
15
13
 
16
14
  require 'spec/rails/matchers'
17
15
  require 'spec/rails/mocks'
16
+
17
+ class ApplicationController < ActionController::Base
18
+ end
19
+
18
20
  require 'spec/rails/example'
19
- require 'spec/rails/extensions'
21
+
22
+ begin
23
+ require 'spec/rails/extensions'
24
+ rescue MissingSourceFile
25
+ # it tries to load application.rb
26
+ end
27
+
20
28
  #require 'spec/rails/interop/testcase'
21
29
 
22
30
  this_dir = File.dirname(__FILE__)
@@ -32,3 +40,9 @@ load(File.join(this_dir, "db", "schema.rb"))
32
40
  ActionController::Routing::Routes.draw do |map|
33
41
  map.connect ":controller/:action/:id"
34
42
  end
43
+
44
+ module Rails
45
+ mattr_accessor :logger
46
+ end
47
+
48
+ Rails.logger = ActiveRecord::Base.logger
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: be9-acl9
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oleg Dashevskii
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-14 00:00:00 -08:00
12
+ date: 2009-02-04 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -19,7 +19,7 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.1.11
22
+ version: 1.1.12
23
23
  version:
24
24
  - !ruby/object:Gem::Dependency
25
25
  name: rspec-rails
@@ -28,7 +28,7 @@ dependencies:
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 1.1.11
31
+ version: 1.1.12
32
32
  version:
33
33
  description: Yet another role-based authorization system for Rails with a nice DSL for access control lists.
34
34
  email: olegdashevskii@gmail.com
@@ -37,40 +37,46 @@ executables: []
37
37
  extensions: []
38
38
 
39
39
  extra_rdoc_files:
40
- - lib/acl9/model_extensions.rb
41
- - lib/acl9/version.rb
40
+ - lib/acl9/helpers.rb
41
+ - lib/acl9/config.rb
42
42
  - lib/acl9/model_extensions/subject.rb
43
43
  - lib/acl9/model_extensions/object.rb
44
+ - lib/acl9/controller_extensions.rb
44
45
  - lib/acl9/controller_extensions/generators.rb
45
46
  - lib/acl9/controller_extensions/dsl_base.rb
46
- - lib/acl9/config.rb
47
- - lib/acl9/controller_extensions.rb
47
+ - lib/acl9/version.rb
48
+ - lib/acl9/model_extensions.rb
48
49
  - lib/acl9.rb
50
+ - TODO
49
51
  - README.textile
50
52
  - CHANGELOG.textile
51
53
  files:
52
- - init.rb
53
- - Manifest
54
- - lib/acl9/model_extensions.rb
55
- - lib/acl9/version.rb
54
+ - lib/acl9/helpers.rb
55
+ - lib/acl9/config.rb
56
56
  - lib/acl9/model_extensions/subject.rb
57
57
  - lib/acl9/model_extensions/object.rb
58
+ - lib/acl9/controller_extensions.rb
58
59
  - lib/acl9/controller_extensions/generators.rb
59
60
  - lib/acl9/controller_extensions/dsl_base.rb
60
- - lib/acl9/config.rb
61
- - lib/acl9/controller_extensions.rb
61
+ - lib/acl9/version.rb
62
+ - lib/acl9/model_extensions.rb
62
63
  - lib/acl9.rb
63
- - README.textile
64
- - acl9.gemspec
65
- - CHANGELOG.textile
66
- - MIT-LICENSE
67
- - Rakefile
64
+ - TODO
68
65
  - spec/db/schema.rb
69
- - spec/dsl_base_spec.rb
66
+ - spec/helpers_spec.rb
70
67
  - spec/spec_helper.rb
68
+ - spec/models.rb
69
+ - spec/dsl_base_spec.rb
71
70
  - spec/access_control_spec.rb
71
+ - spec/controllers.rb
72
72
  - spec/roles_spec.rb
73
- - spec/models.rb
73
+ - acl9.gemspec
74
+ - Manifest
75
+ - MIT-LICENSE
76
+ - Rakefile
77
+ - README.textile
78
+ - init.rb
79
+ - CHANGELOG.textile
74
80
  has_rdoc: true
75
81
  homepage: http://github.com/be9/acl9
76
82
  post_install_message: