base_auth 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +130 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/base_auth.gemspec +118 -0
- data/init.rb +1 -0
- data/lib/base_auth.rb +175 -0
- data/tasks/base_auth_tasks.rake +4 -0
- data/test/helper.rb +16 -0
- data/test/models/user.rb +3 -0
- data/test/rails_app/README +243 -0
- data/test/rails_app/Rakefile +10 -0
- data/test/rails_app/app/controllers/application_controller.rb +10 -0
- data/test/rails_app/app/helpers/application_helper.rb +3 -0
- data/test/rails_app/config/boot.rb +110 -0
- data/test/rails_app/config/database.yml +22 -0
- data/test/rails_app/config/environment.rb +41 -0
- data/test/rails_app/config/environments/development.rb +17 -0
- data/test/rails_app/config/environments/production.rb +28 -0
- data/test/rails_app/config/environments/test.rb +28 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/inflections.rb +10 -0
- data/test/rails_app/config/initializers/mime_types.rb +5 -0
- data/test/rails_app/config/initializers/new_rails_defaults.rb +21 -0
- data/test/rails_app/config/initializers/session_store.rb +15 -0
- data/test/rails_app/config/locales/en.yml +5 -0
- data/test/rails_app/config/routes.rb +43 -0
- data/test/rails_app/db/seeds.rb +7 -0
- data/test/rails_app/db/test.sqlite3 +0 -0
- data/test/rails_app/doc/README_FOR_APP +2 -0
- data/test/rails_app/log/development.log +0 -0
- data/test/rails_app/log/production.log +0 -0
- data/test/rails_app/log/server.log +0 -0
- data/test/rails_app/log/test.log +34 -0
- data/test/rails_app/public/404.html +30 -0
- data/test/rails_app/public/422.html +30 -0
- data/test/rails_app/public/500.html +30 -0
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_app/public/images/rails.png +0 -0
- data/test/rails_app/public/index.html +275 -0
- data/test/rails_app/public/javascripts/application.js +2 -0
- data/test/rails_app/public/javascripts/controls.js +963 -0
- data/test/rails_app/public/javascripts/dragdrop.js +973 -0
- data/test/rails_app/public/javascripts/effects.js +1128 -0
- data/test/rails_app/public/javascripts/prototype.js +4320 -0
- data/test/rails_app/public/robots.txt +5 -0
- data/test/rails_app/script/about +4 -0
- data/test/rails_app/script/console +3 -0
- data/test/rails_app/script/dbconsole +3 -0
- data/test/rails_app/script/destroy +3 -0
- data/test/rails_app/script/generate +3 -0
- data/test/rails_app/script/performance/benchmarker +3 -0
- data/test/rails_app/script/performance/profiler +3 -0
- data/test/rails_app/script/plugin +3 -0
- data/test/rails_app/script/runner +3 -0
- data/test/rails_app/script/server +3 -0
- data/test/rails_app/test/performance/browsing_test.rb +9 -0
- data/test/rails_app/test/test_helper.rb +38 -0
- data/test/schema.rb +5 -0
- data/test/test_base_auth.rb +20 -0
- metadata +140 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/pkg
|
data/README.rdoc
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
= BaseAuth
|
2
|
+
|
3
|
+
== 0.2 beta
|
4
|
+
|
5
|
+
=== Best Authorization System Ever
|
6
|
+
|
7
|
+
== Installation
|
8
|
+
|
9
|
+
Install it as you would any other plugin from github, i.e.
|
10
|
+
script/plugin install git://github.com/aenima/base-auth.git
|
11
|
+
|
12
|
+
== Authorization by Controller
|
13
|
+
|
14
|
+
=== Key concept
|
15
|
+
|
16
|
+
This plugin makes 2 assumptions:
|
17
|
+
|
18
|
+
- you have a current_user method in your controller which returns the currently signed in user which you want to check authorization for.
|
19
|
+
- you check authorization using instance methods of your user objects
|
20
|
+
|
21
|
+
This worked really well for me so far, so there's a slight chance it will also work for you.
|
22
|
+
|
23
|
+
=== Using as a before filter
|
24
|
+
|
25
|
+
Simple example:
|
26
|
+
|
27
|
+
class ArticleController < ApplicationController
|
28
|
+
deny :user => :is_guest?
|
29
|
+
end
|
30
|
+
|
31
|
+
The above example will deny all guest access (will call current_user.is_guest? method to determine if the user is a guest or not). If you want to allow guests to list articles, but nothing more, use:
|
32
|
+
|
33
|
+
allow :index, :user => :is_guest?
|
34
|
+
|
35
|
+
or
|
36
|
+
|
37
|
+
allow :only => :index, :user => :is_guest?
|
38
|
+
|
39
|
+
if you want to allow every user who is guest OR admin, you'd go:
|
40
|
+
|
41
|
+
allow :index, :user => [ :is_guest?, :is_admin? ]
|
42
|
+
|
43
|
+
if you give an Array as :user value, at least one condition has to be met. For more sophisticated conditions you can pass a string, which will be instance_eval'd:
|
44
|
+
|
45
|
+
allow :index, :user => 'is_guest? or ( is_admin? and is_moderator? )'
|
46
|
+
|
47
|
+
Still, there are cases when you want to check something in the controller.
|
48
|
+
In that case you can use :exec param instead of :user like this:
|
49
|
+
|
50
|
+
class ArticleController < ApplicationController
|
51
|
+
allow :exec => :check_auth
|
52
|
+
|
53
|
+
def check_auth
|
54
|
+
session[:allowed] == 'yes'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
You can also pass a string, which will be eval'd, or a Proc, which will be called.
|
59
|
+
|
60
|
+
If you pass a method which accepts arguments, an object will be passed to it as a parameter. Which obejct? By default an instance variable named after singluarized controller name. So:
|
61
|
+
|
62
|
+
class ArticleController < ApplicationController
|
63
|
+
allow :edit, :update, :user => :owns?
|
64
|
+
end
|
65
|
+
|
66
|
+
Will call current_user.owns?( @article ) to check for permission. You can override this by passing :object argument, which can be a Symbol (naming instance variable to be used) or the object itself.
|
67
|
+
|
68
|
+
By default an Authorization::PermisionDenied exception will be raised. You can also use :method parameter to specify which method should be called instead or :redirect_to to redirect user instead.
|
69
|
+
|
70
|
+
With :message parameter you can pass a message that will be stored in exception.
|
71
|
+
|
72
|
+
|
73
|
+
=== Using in actions
|
74
|
+
|
75
|
+
In actions you can use allow!, deny!, allow? and deny? methods. The ones with '!' will raise an exception, while the ones with '?' will only return true or false:
|
76
|
+
|
77
|
+
def destroy
|
78
|
+
allow! :user => :owns?
|
79
|
+
@article.destroy
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
=== Using in views
|
84
|
+
|
85
|
+
You can use allow and deny methods in your views and pass them a block to execute:
|
86
|
+
|
87
|
+
<% allow :user => :is_admin? do %>
|
88
|
+
Only admins can see that!
|
89
|
+
<% end>
|
90
|
+
|
91
|
+
<% deny :user => :is_guest? do %>
|
92
|
+
You can't see it if you're a guest.
|
93
|
+
<% end %>
|
94
|
+
|
95
|
+
|
96
|
+
== Authorization by model
|
97
|
+
|
98
|
+
Since version 0.2 the code has been modularized a bit and you can also authorize by model (single instance for now). It's usage is dead easy and straightforward. You just have to implement authorize instance method in a given model (as a parameter it takes user to authorize against). You don't even have to do it if you're satisfied with default implementation (supplied with plugin):
|
99
|
+
|
100
|
+
def authorize(user)
|
101
|
+
user.id == self.user_id
|
102
|
+
end
|
103
|
+
|
104
|
+
This method is used by authorize! instance method which works exactly like allow! - i.e. does nothing (returns the model) if authorized and throws Authorization::PermissionDenied if not authorized:
|
105
|
+
|
106
|
+
@item = ItemModel.find(35).authorize!(current_user) #throws an exception if current_user is not authorized
|
107
|
+
|
108
|
+
|
109
|
+
== Notes
|
110
|
+
|
111
|
+
If you're using rails older than 2.0 rescuing exceptions can be a pain. For rails 1.2 I recommend using exceptional plugin:
|
112
|
+
|
113
|
+
http://agilewebdevelopment.com/plugins/exceptional
|
114
|
+
|
115
|
+
|
116
|
+
== ToDo
|
117
|
+
|
118
|
+
- add support for :if parameted (should behave like the one in validations)
|
119
|
+
- make it possible to configure default behavior (so you don't have to pass :method parameter everywhere if you always want to call a method instead of raising exception)
|
120
|
+
- better documentation
|
121
|
+
- model authorization: configuration of authorize! method to allow for redirection etc. (now it can only throw exceptions)
|
122
|
+
- model authorization: authorize_for!(:actionname), i.e. let user define and use per-action authorization for a given model (different auth checks for different actions), by authorize_for_actionname methods in model
|
123
|
+
- refactor the code structure (divide into three files)
|
124
|
+
|
125
|
+
|
126
|
+
== Credits & Licensing
|
127
|
+
|
128
|
+
Copyright (c) by Robert Nasiadek at <robert@aenima.pl>. Maintenance and small modifications (model-based auth) by Tomasz Stachewicz <tomasz.stachewicz@aenima.pl>. Distributed under MIT license.
|
129
|
+
|
130
|
+
You can find more cool stuff by Aenima on our Github (http://github.com/aenima) and our blog (http://blog.aenima.pl/).
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "base_auth"
|
8
|
+
gem.summary = %Q{A simple and elegant solution to authorization suitable for most small and medium-sized projects.}
|
9
|
+
gem.description = %Q{A simple and elegant solution to authorization suitable for most small and medium-sized projects.}
|
10
|
+
gem.email = "drogus@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/drogus/base_auth"
|
12
|
+
gem.authors = ["Piotr Sarnacki"]
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
Jeweler::GemcutterTasks.new
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'rake/testtask'
|
21
|
+
Rake::TestTask.new(:test) do |test|
|
22
|
+
test.libs << 'lib' << 'test'
|
23
|
+
test.pattern = 'test/**/test_*.rb'
|
24
|
+
test.verbose = true
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'rcov/rcovtask'
|
29
|
+
Rcov::RcovTask.new do |test|
|
30
|
+
test.libs << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
rescue LoadError
|
35
|
+
task :rcov do
|
36
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :test => :check_dependencies
|
41
|
+
|
42
|
+
task :default => :test
|
43
|
+
|
44
|
+
require 'rake/rdoctask'
|
45
|
+
Rake::RDocTask.new do |rdoc|
|
46
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
47
|
+
|
48
|
+
rdoc.rdoc_dir = 'rdoc'
|
49
|
+
rdoc.title = "base_auth #{version}"
|
50
|
+
rdoc.rdoc_files.include('README*')
|
51
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.1
|
data/base_auth.gemspec
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{base_auth}
|
8
|
+
s.version = "0.2.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Piotr Sarnacki"]
|
12
|
+
s.date = %q{2010-03-15}
|
13
|
+
s.description = %q{A simple and elegant solution to authorization suitable for most small and medium-sized projects.}
|
14
|
+
s.email = %q{drogus@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"base_auth.gemspec",
|
24
|
+
"init.rb",
|
25
|
+
"lib/base_auth.rb",
|
26
|
+
"tasks/base_auth_tasks.rake",
|
27
|
+
"test/helper.rb",
|
28
|
+
"test/models/user.rb",
|
29
|
+
"test/rails_app/README",
|
30
|
+
"test/rails_app/Rakefile",
|
31
|
+
"test/rails_app/app/controllers/application_controller.rb",
|
32
|
+
"test/rails_app/app/helpers/application_helper.rb",
|
33
|
+
"test/rails_app/config/boot.rb",
|
34
|
+
"test/rails_app/config/database.yml",
|
35
|
+
"test/rails_app/config/environment.rb",
|
36
|
+
"test/rails_app/config/environments/development.rb",
|
37
|
+
"test/rails_app/config/environments/production.rb",
|
38
|
+
"test/rails_app/config/environments/test.rb",
|
39
|
+
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
40
|
+
"test/rails_app/config/initializers/inflections.rb",
|
41
|
+
"test/rails_app/config/initializers/mime_types.rb",
|
42
|
+
"test/rails_app/config/initializers/new_rails_defaults.rb",
|
43
|
+
"test/rails_app/config/initializers/session_store.rb",
|
44
|
+
"test/rails_app/config/locales/en.yml",
|
45
|
+
"test/rails_app/config/routes.rb",
|
46
|
+
"test/rails_app/db/seeds.rb",
|
47
|
+
"test/rails_app/db/test.sqlite3",
|
48
|
+
"test/rails_app/doc/README_FOR_APP",
|
49
|
+
"test/rails_app/log/development.log",
|
50
|
+
"test/rails_app/log/production.log",
|
51
|
+
"test/rails_app/log/server.log",
|
52
|
+
"test/rails_app/log/test.log",
|
53
|
+
"test/rails_app/public/404.html",
|
54
|
+
"test/rails_app/public/422.html",
|
55
|
+
"test/rails_app/public/500.html",
|
56
|
+
"test/rails_app/public/favicon.ico",
|
57
|
+
"test/rails_app/public/images/rails.png",
|
58
|
+
"test/rails_app/public/index.html",
|
59
|
+
"test/rails_app/public/javascripts/application.js",
|
60
|
+
"test/rails_app/public/javascripts/controls.js",
|
61
|
+
"test/rails_app/public/javascripts/dragdrop.js",
|
62
|
+
"test/rails_app/public/javascripts/effects.js",
|
63
|
+
"test/rails_app/public/javascripts/prototype.js",
|
64
|
+
"test/rails_app/public/robots.txt",
|
65
|
+
"test/rails_app/script/about",
|
66
|
+
"test/rails_app/script/console",
|
67
|
+
"test/rails_app/script/dbconsole",
|
68
|
+
"test/rails_app/script/destroy",
|
69
|
+
"test/rails_app/script/generate",
|
70
|
+
"test/rails_app/script/performance/benchmarker",
|
71
|
+
"test/rails_app/script/performance/profiler",
|
72
|
+
"test/rails_app/script/plugin",
|
73
|
+
"test/rails_app/script/runner",
|
74
|
+
"test/rails_app/script/server",
|
75
|
+
"test/rails_app/test/performance/browsing_test.rb",
|
76
|
+
"test/rails_app/test/test_helper.rb",
|
77
|
+
"test/schema.rb",
|
78
|
+
"test/test_base_auth.rb"
|
79
|
+
]
|
80
|
+
s.homepage = %q{http://github.com/drogus/base_auth}
|
81
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
82
|
+
s.require_paths = ["lib"]
|
83
|
+
s.rubygems_version = %q{1.3.6}
|
84
|
+
s.summary = %q{A simple and elegant solution to authorization suitable for most small and medium-sized projects.}
|
85
|
+
s.test_files = [
|
86
|
+
"test/helper.rb",
|
87
|
+
"test/models/user.rb",
|
88
|
+
"test/rails_app/app/controllers/application_controller.rb",
|
89
|
+
"test/rails_app/app/helpers/application_helper.rb",
|
90
|
+
"test/rails_app/config/boot.rb",
|
91
|
+
"test/rails_app/config/environment.rb",
|
92
|
+
"test/rails_app/config/environments/development.rb",
|
93
|
+
"test/rails_app/config/environments/production.rb",
|
94
|
+
"test/rails_app/config/environments/test.rb",
|
95
|
+
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
96
|
+
"test/rails_app/config/initializers/inflections.rb",
|
97
|
+
"test/rails_app/config/initializers/mime_types.rb",
|
98
|
+
"test/rails_app/config/initializers/new_rails_defaults.rb",
|
99
|
+
"test/rails_app/config/initializers/session_store.rb",
|
100
|
+
"test/rails_app/config/routes.rb",
|
101
|
+
"test/rails_app/db/seeds.rb",
|
102
|
+
"test/rails_app/test/performance/browsing_test.rb",
|
103
|
+
"test/rails_app/test/test_helper.rb",
|
104
|
+
"test/schema.rb",
|
105
|
+
"test/test_base_auth.rb"
|
106
|
+
]
|
107
|
+
|
108
|
+
if s.respond_to? :specification_version then
|
109
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
110
|
+
s.specification_version = 3
|
111
|
+
|
112
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
113
|
+
else
|
114
|
+
end
|
115
|
+
else
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'base_auth'
|
data/lib/base_auth.rb
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
# BaseAuth
|
2
|
+
|
3
|
+
module Authorization
|
4
|
+
|
5
|
+
DEFAULT_PERMISSION_DENIED_MESSAGE = 'You have no permissions to access this page.'
|
6
|
+
|
7
|
+
def self.included( base )
|
8
|
+
base.extend( ClassMethods )
|
9
|
+
base.send( :include, InstanceMethods )
|
10
|
+
end
|
11
|
+
|
12
|
+
class PermissionDenied < Exception
|
13
|
+
attr :message
|
14
|
+
def initialize( message = nil )
|
15
|
+
@message = message || DEFAULT_PERMISSION_DENIED_MESSAGE
|
16
|
+
end
|
17
|
+
def clean_message
|
18
|
+
@message
|
19
|
+
end
|
20
|
+
def to_s
|
21
|
+
@message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module InstanceMethods
|
26
|
+
|
27
|
+
def eval_authorization_conditions( conditions, user_for_auth )
|
28
|
+
exec = conditions[:exec]
|
29
|
+
if exec
|
30
|
+
case exec.class.name
|
31
|
+
when 'Symbol':
|
32
|
+
send( exec )
|
33
|
+
when 'String':
|
34
|
+
eval( exec )
|
35
|
+
when 'Proc':
|
36
|
+
exec.call
|
37
|
+
else
|
38
|
+
raise ArgumentError( ":exec doesn't accept values of class #{exec.class.name}" )
|
39
|
+
end
|
40
|
+
elsif conditions[:user]
|
41
|
+
if conditions[:user].is_a?( String )
|
42
|
+
return user_for_auth.instance_eval conditions[:user]
|
43
|
+
end
|
44
|
+
o = conditions[:object] || controller_name.singularize.to_sym
|
45
|
+
object = o.is_a?( Symbol ) ? eval("@#{o}") : o
|
46
|
+
|
47
|
+
methods = conditions[:user]
|
48
|
+
methods = [ methods ] if not methods.is_a?( Array )
|
49
|
+
|
50
|
+
for method in methods
|
51
|
+
if user_for_auth.respond_to?( method ) and
|
52
|
+
user_for_auth.method( method ).arity == 0
|
53
|
+
return true if user_for_auth.send( method )
|
54
|
+
else
|
55
|
+
return true if user_for_auth.send( method, object )
|
56
|
+
end
|
57
|
+
end
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def allow?( conditions )
|
63
|
+
eval_authorization_conditions( conditions )
|
64
|
+
end
|
65
|
+
|
66
|
+
def deny?( conditions )
|
67
|
+
!eval_authorization_conditions( conditions )
|
68
|
+
end
|
69
|
+
|
70
|
+
def allow!( conditions )
|
71
|
+
invoke_permission_denied_action( conditions ) unless allow?( conditions )
|
72
|
+
end
|
73
|
+
|
74
|
+
def deny!( conditions )
|
75
|
+
invoke_permission_denied_action( conditions ) unless deny?( conditions )
|
76
|
+
end
|
77
|
+
|
78
|
+
def allow( conditions )
|
79
|
+
if allow?( conditions )
|
80
|
+
yield
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def deny( conditions )
|
85
|
+
if deny?( conditions )
|
86
|
+
yield
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def invoke_permission_denied_action( config )
|
91
|
+
if config[:redirect_to]
|
92
|
+
redirect_to config[:redirect_to]
|
93
|
+
elsif config[:method]
|
94
|
+
send( config[:method] )
|
95
|
+
else
|
96
|
+
raise Authorization::PermissionDenied.new( config[:message] )
|
97
|
+
end
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
module ClassMethods
|
104
|
+
|
105
|
+
def authorization_filter( action, attrs )
|
106
|
+
config = { }
|
107
|
+
config.update( attrs.pop ) if attrs.last.is_a?( Hash )
|
108
|
+
|
109
|
+
opts = {}
|
110
|
+
opts[:only] = config[:only]
|
111
|
+
opts[:only] ||= attrs unless attrs.blank?
|
112
|
+
opts[:except] = config[:except]
|
113
|
+
|
114
|
+
if config[:if]
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
before_filter opts do |controller|
|
119
|
+
if action == :allow
|
120
|
+
controller.allow! config
|
121
|
+
else
|
122
|
+
controller.deny! config
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def allow( *attrs )
|
128
|
+
authorization_filter :allow, attrs
|
129
|
+
end
|
130
|
+
|
131
|
+
def deny( *attrs )
|
132
|
+
authorization_filter :deny, attrs
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
module ControllerAuthorization
|
140
|
+
|
141
|
+
def self.included( base )
|
142
|
+
base.send( :include, Authorization )
|
143
|
+
base.send( :include, InstanceMethods )
|
144
|
+
end
|
145
|
+
|
146
|
+
module InstanceMethods
|
147
|
+
def eval_authorization_conditions( conditions )
|
148
|
+
super( conditions, current_user )
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
module ModelAuthorization
|
154
|
+
|
155
|
+
def self.included( base )
|
156
|
+
base.send( :include, Authorization )
|
157
|
+
base.send( :include, InstanceMethods )
|
158
|
+
end
|
159
|
+
|
160
|
+
module InstanceMethods
|
161
|
+
def authorize!(for_user)
|
162
|
+
invoke_permission_denied_action( {} ) unless self.authorize(for_user)
|
163
|
+
self
|
164
|
+
end
|
165
|
+
|
166
|
+
#re-implement this in your model if you check authorization in a different way
|
167
|
+
def authorize(user)
|
168
|
+
user.id == self.user_id
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
ActiveRecord::Base.send( :include, ModelAuthorization )
|
174
|
+
ActionController::Base.send( :include, ControllerAuthorization )
|
175
|
+
ActionController::Base.send( :helper_method, [ :allow, :deny ] )
|