authoritah 0.0.5 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
data/lib/authoritah.rb
CHANGED
@@ -28,6 +28,9 @@ module Authoritah
|
|
28
28
|
options = args.extract_options!
|
29
29
|
args.each {|a| options[a] = nil}
|
30
30
|
actions = options.delete(action_identifier)
|
31
|
+
on_reject = options.delete(:on_reject) || :render_404
|
32
|
+
|
33
|
+
raise ":on_reject must be a symbol or a Proc" unless on_reject.is_a?(Symbol) || on_reject.is_a?(Proc)
|
31
34
|
|
32
35
|
check_role_selectors(options)
|
33
36
|
|
@@ -35,8 +38,13 @@ module Authoritah
|
|
35
38
|
role_predicate = options.to_a.first[1]
|
36
39
|
|
37
40
|
controller_permissions[controller_name.to_sym] ||= PermissionSet.new
|
38
|
-
controller_permissions[controller_name.to_sym] <<
|
39
|
-
|
41
|
+
controller_permissions[controller_name.to_sym] << {
|
42
|
+
:type => perm_type,
|
43
|
+
:role_method => role_method,
|
44
|
+
:role_predicate => role_predicate,
|
45
|
+
:actions => actions ? Array(actions) : nil,
|
46
|
+
:on_reject => on_reject
|
47
|
+
}
|
40
48
|
end
|
41
49
|
|
42
50
|
def this_controllers_permissions
|
@@ -61,16 +69,18 @@ module Authoritah
|
|
61
69
|
module InstanceMethods
|
62
70
|
|
63
71
|
def check_permissions
|
64
|
-
|
65
|
-
render(:file => File.join(RAILS_ROOT, 'public', '404.html'), :status => 404)
|
66
|
-
false
|
72
|
+
permitted?(action_name.to_sym)
|
67
73
|
end
|
68
74
|
|
69
75
|
protected
|
70
76
|
|
77
|
+
def render_404
|
78
|
+
render(:file => File.join(RAILS_ROOT, 'public', '404.html'), :status => 404)
|
79
|
+
end
|
80
|
+
|
71
81
|
def permitted?(action)
|
72
82
|
return true unless permissions = self.class.this_controllers_permissions
|
73
|
-
permissions.permits?(self, action)
|
83
|
+
permissions.permits?(self, action)
|
74
84
|
end
|
75
85
|
end
|
76
86
|
|
@@ -90,39 +100,52 @@ module Authoritah
|
|
90
100
|
end
|
91
101
|
|
92
102
|
def permits?(controller, action)
|
93
|
-
|
103
|
+
permitted, on_reject_action = apply_rule_chain(:permit, controller, action)
|
104
|
+
if permitted
|
105
|
+
return true
|
106
|
+
else
|
107
|
+
if on_reject_action.is_a?(Proc)
|
108
|
+
# debugger
|
109
|
+
# on_reject_action.call(controller)
|
110
|
+
controller.instance_eval(&on_reject_action)
|
111
|
+
else
|
112
|
+
controller.send(on_reject_action)
|
113
|
+
end
|
114
|
+
return false
|
115
|
+
end
|
94
116
|
end
|
95
117
|
|
96
|
-
def forbids?(controller, action)
|
97
|
-
apply_rules(:forbid, controller, action).include?(true)
|
98
|
-
end
|
99
|
-
|
100
118
|
def permissions
|
101
119
|
@permissions ||= []
|
102
120
|
end
|
103
121
|
|
104
122
|
protected
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
p[:actions].include?(action) || p[:actions].include?(:all)
|
111
|
-
}.map do |permission|
|
123
|
+
|
124
|
+
# Returns [true, nil] if the rule chain applied without a problem.
|
125
|
+
# Returns [false, :reject_to]
|
126
|
+
def apply_rule_chain(rule_type, controller, action)
|
127
|
+
select_permissions_for(action).each do |permission|
|
112
128
|
begin
|
113
|
-
if permission[:role_predicate].is_a? Symbol
|
129
|
+
response = if permission[:role_predicate].is_a? Symbol
|
114
130
|
controller.send(permission[:role_method]).send(permission[:role_predicate])
|
115
131
|
elsif permission[:role_predicate].is_a? Proc
|
116
132
|
permission[:role_predicate].call(controller.send(permission[:role_method]))
|
117
133
|
elsif permission[:role_predicate] == nil
|
118
134
|
controller.send(permission[:role_method])
|
119
|
-
else
|
120
|
-
false
|
121
135
|
end
|
136
|
+
response = !response if permission[:type] == :forbid
|
137
|
+
return [false, permission[:on_reject]] unless response
|
122
138
|
rescue
|
123
|
-
|
139
|
+
return [permission[:type] == :forbid, permission[:on_reject]]
|
124
140
|
end
|
125
141
|
end
|
142
|
+
[true, nil]
|
143
|
+
end
|
144
|
+
|
145
|
+
def select_permissions_for(action)
|
146
|
+
permissions.select{|p|
|
147
|
+
p[:actions].include?(action) || p[:actions].include?(:all)
|
148
|
+
}
|
126
149
|
end
|
127
150
|
end
|
128
151
|
|
data/spec/authoritah_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
|
2
|
+
require 'ruby-debug'
|
3
3
|
describe Authoritah::Controller do
|
4
4
|
|
5
5
|
before(:each) do
|
@@ -200,6 +200,9 @@ describe TestAuthorizerController, :type => :controller do
|
|
200
200
|
end
|
201
201
|
end
|
202
202
|
context "an unauthenticated user" do
|
203
|
+
before(:each) do
|
204
|
+
controller.stubs(:current_user => false)
|
205
|
+
end
|
203
206
|
it "should render index" do get :index; response.should render_template('index') end
|
204
207
|
end
|
205
208
|
end
|
@@ -245,15 +248,73 @@ describe TestAuthorizerController, :type => :controller do
|
|
245
248
|
end
|
246
249
|
end
|
247
250
|
|
248
|
-
describe "
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
251
|
+
describe "specifying a different action to run on failure" do
|
252
|
+
|
253
|
+
it "should check that :on_reject is a Proc or Symbol" do
|
254
|
+
lambda do
|
255
|
+
TestAuthorizerController.permits(:current_user => :logged_in?, :on_reject => :method)
|
256
|
+
end.should_not raise_error
|
257
|
+
lambda do
|
258
|
+
TestAuthorizerController.permits(:current_user => :logged_in?, :on_reject => Proc.new {})
|
259
|
+
end.should_not raise_error
|
260
|
+
lambda do
|
261
|
+
TestAuthorizerController.permits(:current_user => :logged_in?, :on_reject => 5)
|
262
|
+
end.should raise_error
|
263
|
+
end
|
264
|
+
|
265
|
+
context "when :on_reject => :set_flash_and_redirect" do
|
266
|
+
before(:each) do
|
267
|
+
TestAuthorizerController.permits(:current_user => :logged_in?, :on_reject => :set_flash_and_redirect)
|
268
|
+
TestAuthorizerController.send(:define_method, :set_flash_and_redirect) do
|
269
|
+
flash[:error] = "You need to be logged in to do that"
|
270
|
+
redirect_to root_url
|
271
|
+
end
|
272
|
+
end
|
273
|
+
context "an unauthenticated user" do
|
274
|
+
it "should redirect to /" do
|
275
|
+
get :index
|
276
|
+
response.should redirect_to(root_url)
|
277
|
+
end
|
278
|
+
it "should set the flash" do
|
279
|
+
get :index
|
280
|
+
flash[:error].should == "You need to be logged in to do that"
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
context "when :on_reject => Proc" do
|
286
|
+
before(:each) do
|
287
|
+
TestAuthorizerController.permits(:current_user => :logged_in?, :on_reject => Proc.new { redirect_to root_url })
|
288
|
+
end
|
289
|
+
context "an unauthenticated user" do
|
290
|
+
it "should redirect to /" do
|
291
|
+
get :index
|
292
|
+
response.should redirect_to(root_url)
|
293
|
+
end
|
255
294
|
end
|
256
295
|
end
|
257
|
-
|
296
|
+
|
297
|
+
context "with multiple rules" do
|
298
|
+
before(:each) do
|
299
|
+
TestAuthorizerController.permits(:current_user => :logged_in?)
|
300
|
+
TestAuthorizerController.forbids(:current_user => :blacklisted?, :on_reject => :set_blacklisted)
|
301
|
+
TestAuthorizerController.send(:define_method, :set_blacklisted) do
|
302
|
+
flash[:error] = "You can't be blacklisted to do that"
|
303
|
+
redirect_to '/blacklisted'
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
context "as a blacklisted user" do
|
308
|
+
before(:each) do
|
309
|
+
controller.stubs(:current_user => stub(:logged_in? => true, :blacklisted? => true))
|
310
|
+
end
|
311
|
+
it 'should redirect to /blacklisted' do
|
312
|
+
get :index
|
313
|
+
response.should redirect_to('/blacklisted')
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
end
|
258
318
|
end
|
319
|
+
|
259
320
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authoritah
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steven Mohapi-Banks
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-11-04 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.2.
|
23
|
+
version: 1.2.9
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec-rails
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.2.
|
33
|
+
version: 1.2.9
|
34
34
|
version:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: mocha
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
requirements: []
|
81
81
|
|
82
82
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.3.
|
83
|
+
rubygems_version: 1.3.5
|
84
84
|
signing_key:
|
85
85
|
specification_version: 3
|
86
86
|
summary: A really simple authorization plugin for Rails.
|
@@ -91,9 +91,7 @@ test_files:
|
|
91
91
|
- spec/railsenv/config/boot.rb
|
92
92
|
- spec/railsenv/config/database.yml
|
93
93
|
- spec/railsenv/config/environment.rb
|
94
|
-
- spec/railsenv/config/environments/cucumber.rb
|
95
94
|
- spec/railsenv/config/environments/development.rb
|
96
|
-
- spec/railsenv/config/environments/production.rb
|
97
95
|
- spec/railsenv/config/environments/test.rb
|
98
96
|
- spec/railsenv/config/initializers/backtrace_silencers.rb
|
99
97
|
- spec/railsenv/config/initializers/inflections.rb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
config.cache_classes = true # This must be true for Cucumber to operate correctly!
|
2
|
-
|
3
|
-
# Log error messages when you accidentally call methods on nil.
|
4
|
-
config.whiny_nils = true
|
5
|
-
|
6
|
-
# Show full error reports and disable caching
|
7
|
-
config.action_controller.consider_all_requests_local = true
|
8
|
-
config.action_controller.perform_caching = false
|
9
|
-
|
10
|
-
# Disable request forgery protection in test environment
|
11
|
-
config.action_controller.allow_forgery_protection = false
|
12
|
-
|
13
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
14
|
-
# The :test delivery method accumulates sent emails in the
|
15
|
-
# ActionMailer::Base.deliveries array.
|
16
|
-
config.action_mailer.delivery_method = :test
|
17
|
-
|
18
|
-
config.gem 'cucumber', :lib => false, :version => '>=0.3.100' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber'))
|
19
|
-
config.gem 'webrat', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
|
20
|
-
config.gem 'rspec', :lib => false, :version => '>=1.2.6' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
|
21
|
-
config.gem 'rspec-rails', :lib => 'spec/rails', :version => '>=1.2.6' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
|
22
|
-
|
23
|
-
config.gem 'spork', :lib => false, :version => '>=0.5.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/spork'))
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# Settings specified here will take precedence over those in config/environment.rb
|
2
|
-
|
3
|
-
# The production environment is meant for finished, "live" apps.
|
4
|
-
# Code is not reloaded between requests
|
5
|
-
config.cache_classes = true
|
6
|
-
|
7
|
-
# Full error reports are disabled and caching is turned on
|
8
|
-
config.action_controller.consider_all_requests_local = false
|
9
|
-
config.action_controller.perform_caching = true
|
10
|
-
config.action_view.cache_template_loading = true
|
11
|
-
|
12
|
-
# See everything in the log (default is :info)
|
13
|
-
# config.log_level = :debug
|
14
|
-
|
15
|
-
# Use a different logger for distributed setups
|
16
|
-
# config.logger = SyslogLogger.new
|
17
|
-
|
18
|
-
# Use a different cache store in production
|
19
|
-
# config.cache_store = :mem_cache_store
|
20
|
-
|
21
|
-
# Enable serving of images, stylesheets, and javascripts from an asset server
|
22
|
-
# config.action_controller.asset_host = "http://assets.example.com"
|
23
|
-
|
24
|
-
# Disable delivery errors, bad email addresses will be ignored
|
25
|
-
# config.action_mailer.raise_delivery_errors = false
|
26
|
-
|
27
|
-
# Enable threaded mode
|
28
|
-
# config.threadsafe!
|