be9-acl9 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
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: