role_based_authorization 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +64 -63
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/lib/role_based_authorization/authorization_logger.rb +1 -1
- data/lib/role_based_authorization/role_based_authorization.rb +1 -1
- data/role_based_authorization.gemspec +27 -35
- data/test/authorization_logger_test.rb +1 -1
- data/test/test_helper.rb +7 -4
- metadata +54 -63
- data/.gitignore +0 -4
data/README.rdoc
CHANGED
@@ -5,25 +5,26 @@ This library provide a very simple authorization system. It should work fine wit
|
|
5
5
|
for my needs.
|
6
6
|
|
7
7
|
Installation:
|
8
|
+
|
8
9
|
* install the role_based_authorization by issuing:
|
9
|
-
|
10
|
+
gem install role_based_authorization
|
10
11
|
or by adding
|
11
|
-
|
12
|
+
config.gem "role_based_authorization"
|
12
13
|
to your rails config file and then running 'rake gems:install'
|
13
14
|
|
14
15
|
|
15
16
|
* in your application controller: include the module RoleBasedAuthorization:
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
class ApplicationController < ActionController::Base
|
19
|
+
[...]
|
20
|
+
include RoleBasedAuthorization
|
21
|
+
[...]
|
22
|
+
end
|
22
23
|
|
23
24
|
* in your controller classes: use the permission statements (described below) to grant and deny authorizations to the controller methods.
|
24
25
|
|
25
26
|
|
26
|
-
The inclusion of RoleBasedAuthorization serves three purposes: it allows subclasses of the application controller to use the 'permit' method during their definition, it
|
27
|
+
The inclusion of RoleBasedAuthorization serves three purposes: it allows subclasses of the application controller to use the 'permit' method during their definition, it provides an "authorized?" method that implements the authorization logic, and it creates an helper method to be used in views.
|
27
28
|
|
28
29
|
== Requirements
|
29
30
|
|
@@ -43,32 +44,33 @@ You can specify your authorization logic by adding a number of 'permit' calls to
|
|
43
44
|
An important thing to keep in mind is that role_based_authorization assumes that EVERYTHING IS FORBIDDEN unless otherwise specified. Then, if you do not specify any permission rule, you will end up with a very secure (though useless) application.
|
44
45
|
|
45
46
|
The permission statement takes the form:
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
:object_id => object_id_symbol
|
47
|
+
permit :actions => [list of actions],
|
48
|
+
:to => [list of roles],
|
49
|
+
:if => lambda_expression,
|
50
|
+
:object_id => object_id_symbol
|
51
51
|
|
52
52
|
you can add any number of these in anyone of your controller.
|
53
53
|
|
54
54
|
permit options:
|
55
55
|
|
56
|
-
<b>:to</b>::
|
57
|
-
|
56
|
+
<b>:to</b>::
|
57
|
+
the list of roles interested by this rule. The actual contents of this list depends on what your application defines to be a role. If you use integers, it could be a vector like [1,4] or as [ROOT, ADMIN], where ROOT and ADMIN are symbolic costants containing the corresponding integer values. You can specify all roles by specifying :all in place of the role list.
|
58
|
+
|
58
59
|
|
59
60
|
<b>:actions</b>::
|
60
|
-
|
61
|
+
the list of actions that are permitted to the mentioned roles. Actions are actual method names of the current controller and can be given as symbols or as strings. For instance ['index', 'show'] is equivalent to [:index, :show]. You can grant access to all actions by specifying :all instead of the action list.
|
62
|
+
|
61
63
|
|
62
64
|
<b>:if</b>::
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
a lambda expression that verifies additional conditions. The lambda expression takes two arguments: the current user and the id of an object. For instance you may want to verify that "normal" users could only modify objects that they own. You can say that by specifying:
|
66
|
+
permit :actions => [:edit, :update],
|
67
|
+
:to => [NORMAL],
|
68
|
+
:if => lambda { |user, obj_id| TheObject.find(obj_id).owner == user }
|
69
|
+
|
68
70
|
<b>:object_id</b>::
|
69
|
-
|
70
|
-
|
71
|
-
|
71
|
+
normally the object id passed to the lambda expression of the <tt>:if</tt> option is retrieved from the params hash using <tt>:id</tt> (i.e. normally <tt>obj_id = params[:id]</tt>), you can specify other identifiers using this option, e.g.:
|
72
|
+
<tt>:object_id => :product_id</tt>
|
73
|
+
specifies that :product_id should be used instead of :id.
|
72
74
|
|
73
75
|
== authorized?
|
74
76
|
|
@@ -84,21 +86,20 @@ This is a more general version of :authorized?. The difference between the two i
|
|
84
86
|
== if_authorized? helper method
|
85
87
|
|
86
88
|
It often happens that parts of a view is to be displayed only if a given action is authorized. This clutters your view with code like:
|
87
|
-
|
88
|
-
if authorize_action?(:controller => xxx, :action => yyy) .... link_to 'zzz', :controller => xxx, :action => yyy end
|
89
|
+
if authorize_action?(:controller => xxx, :action => yyy) .... link_to 'zzz', :controller => xxx, :action => yyy end
|
89
90
|
|
90
91
|
clearly there is a lot of duplication in this code. if_authorized? takes the same parameters as authorize_action? and a block. The block is called only if authorize_action? returns true and the parameters are passed to the block. This allows to clean up your view as follows:
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
if_authorized?(:controller => xxx, :action => yyy) do |opts|
|
94
|
+
...
|
95
|
+
link_to 'zzz', opts
|
96
|
+
end
|
96
97
|
|
97
98
|
This works also if you use resource paths as in:
|
98
99
|
|
99
|
-
|
100
|
-
|
101
|
-
|
100
|
+
if_authorized?( edit_product_path ) do |opts|
|
101
|
+
link_to 'zzz', opts
|
102
|
+
end
|
102
103
|
|
103
104
|
== Logging
|
104
105
|
|
@@ -109,43 +110,43 @@ The authorization system logs each access attempt to #{Rails.root}/log/authoriza
|
|
109
110
|
|
110
111
|
I usually add a Roles class to my project (I place it in the model directory even though it is not connected to any db table). It's definition is:
|
111
112
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
This allows me to write Role[:root] to specify the root role.
|
125
|
-
|
126
|
-
Example 1
|
113
|
+
class Role
|
114
|
+
# define below valid roles for your application
|
115
|
+
ROLES = { :user => 1, :administrator => 2, :root => 3 }
|
116
|
+
|
117
|
+
# call this function in your permit actions
|
118
|
+
def Role.[](role)
|
119
|
+
role = ROLES[role]
|
120
|
+
raise "given role '#{role}' is not valid" if role.nil?
|
121
|
+
return role
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
This allows me to write <tt>Role[:root]</tt> to specify the root role.
|
126
|
+
|
127
|
+
<b>Example 1:</b> Grant all powers to the root role (this rule is usually found in your application controller)
|
127
128
|
|
128
|
-
|
129
|
+
permit :actions => :all, :to => Role[:root]
|
129
130
|
|
130
|
-
Example 2
|
131
|
+
<b>Example 2:</b> Grant view actions to normal users, edit actions to administrators
|
131
132
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
133
|
+
permit :actions => [:index, :show],
|
134
|
+
:to => Role[:user]
|
135
|
+
permit :actions => [:edit, :update, :destroy],
|
136
|
+
:to => Role[:admin]
|
136
137
|
|
137
|
-
Example 3
|
138
|
+
<b>Example 3:</b> Adding a rule to allow users to edit their own data (let us assume that the controller manages objects of type Product):
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
permit :actions => [:edit, :update],
|
141
|
+
:to => Role[:user].
|
142
|
+
:if => lambda { |user, obj_id| Product.find(obj_id).owner == user }
|
142
143
|
|
143
|
-
Example 4
|
144
|
+
<b>Example 4:</b> Let us assume that the current controller does not manage products, but that you want to check for the product owner anyway. In this case, the product id will not be passed as the :id object into your params hash and the above rule will fail. Amend this problem by telling the permit action how to retrieve the correct id:
|
144
145
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
permit :actions => [:edit, :update],
|
147
|
+
:to => Role[:user].
|
148
|
+
:if => lambda { |user, obj_id| Product.find(obj_id).owner == user },
|
149
|
+
:object_id => :product_id
|
149
150
|
|
150
151
|
|
151
152
|
Copyright (c) 2010 Roberto Esposito, released under the MIT license
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
|
-
require '
|
3
|
+
require 'rdoc/task'
|
4
4
|
|
5
5
|
desc 'Default: run unit tests.'
|
6
6
|
task :default => :test
|
@@ -34,7 +34,7 @@ begin
|
|
34
34
|
gemspec.email = "boborbt@gmail.com"
|
35
35
|
gemspec.homepage = "http://github.com/boborbt/role_based_authorization"
|
36
36
|
gemspec.authors = ["Roberto Esposito"]
|
37
|
-
gemspec.add_dependency('rails', '~>
|
37
|
+
gemspec.add_dependency('rails', '~> 3')
|
38
38
|
gemspec.add_dependency('mocha', '~> 0')
|
39
39
|
end
|
40
40
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Personalizes the authorization logging by adding Auth | in front of each line.
|
2
2
|
# It also outputs the time stamp and the severity of the log message.
|
3
|
-
class AuthorizationLogger <
|
3
|
+
class AuthorizationLogger < ActiveSupport::BufferedLogger
|
4
4
|
# Prefix for each message
|
5
5
|
AUTHORIZATION_SYSTEM_LOG_MSG_PREFIX = 'Auth |'
|
6
6
|
|
@@ -35,7 +35,7 @@ module RoleBasedAuthorization
|
|
35
35
|
def RoleBasedAuthorization.path_or_options_to_options(opts)
|
36
36
|
path_cleanup_regexp = %r{(#{ActionController::Base.relative_url_root})?}
|
37
37
|
|
38
|
-
url_options = (opts.class <= String) &&
|
38
|
+
url_options = (opts.class <= String) && Rails.application.routes.recognize_path(opts.gsub(path_cleanup_regexp,''))
|
39
39
|
url_options ||= opts.dup
|
40
40
|
|
41
41
|
url_options
|
@@ -1,61 +1,53 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.
|
7
|
+
s.name = "role_based_authorization"
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Roberto Esposito"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
12
|
+
s.date = "2013-05-28"
|
13
|
+
s.description = "Provides a simple DSL for specifying the authorization logic of your application. Install the gem, add a role attribute to your user model and your almost ready to go."
|
14
|
+
s.email = "boborbt@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"README.rdoc"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
|
-
"
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
"role_based_authorization.gemspec",
|
31
|
-
"test/authorization_logger_test.rb",
|
32
|
-
"test/role_based_authorization_test.rb",
|
33
|
-
"test/test_helper.rb"
|
34
|
-
]
|
35
|
-
s.homepage = %q{http://github.com/boborbt/role_based_authorization}
|
36
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
37
|
-
s.require_paths = ["lib"]
|
38
|
-
s.rubygems_version = %q{1.3.6}
|
39
|
-
s.summary = %q{Basic authorization module for rails}
|
40
|
-
s.test_files = [
|
19
|
+
"MIT-LICENSE",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"lib/role_based_authorization.rb",
|
24
|
+
"lib/role_based_authorization/authorization_logger.rb",
|
25
|
+
"lib/role_based_authorization/class_additions.rb",
|
26
|
+
"lib/role_based_authorization/role_based_authorization.rb",
|
27
|
+
"lib/role_based_authorization/rule.rb",
|
28
|
+
"rails/init.rb",
|
29
|
+
"role_based_authorization.gemspec",
|
41
30
|
"test/authorization_logger_test.rb",
|
42
|
-
|
43
|
-
|
31
|
+
"test/role_based_authorization_test.rb",
|
32
|
+
"test/test_helper.rb"
|
44
33
|
]
|
34
|
+
s.homepage = "http://github.com/boborbt/role_based_authorization"
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = "1.8.24"
|
37
|
+
s.summary = "Basic authorization module for rails"
|
45
38
|
|
46
39
|
if s.respond_to? :specification_version then
|
47
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
48
40
|
s.specification_version = 3
|
49
41
|
|
50
|
-
if Gem::Version.new(Gem::
|
51
|
-
s.add_runtime_dependency(%q<rails>, ["~>
|
42
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
43
|
+
s.add_runtime_dependency(%q<rails>, ["~> 3"])
|
52
44
|
s.add_runtime_dependency(%q<mocha>, ["~> 0"])
|
53
45
|
else
|
54
|
-
s.add_dependency(%q<rails>, ["~>
|
46
|
+
s.add_dependency(%q<rails>, ["~> 3"])
|
55
47
|
s.add_dependency(%q<mocha>, ["~> 0"])
|
56
48
|
end
|
57
49
|
else
|
58
|
-
s.add_dependency(%q<rails>, ["~>
|
50
|
+
s.add_dependency(%q<rails>, ["~> 3"])
|
59
51
|
s.add_dependency(%q<mocha>, ["~> 0"])
|
60
52
|
end
|
61
53
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
gem 'rails', '~>
|
2
|
+
gem 'rails', '~>3'
|
3
3
|
require 'active_support'
|
4
4
|
require 'action_controller'
|
5
5
|
require 'active_support/test_case'
|
6
6
|
require 'test/unit'
|
7
|
+
require 'rails'
|
7
8
|
|
8
9
|
RAILS_ROOT='.'
|
9
10
|
AUTH_LOG_DIR = File.join(RAILS_ROOT,'log')
|
@@ -11,11 +12,13 @@ Dir.mkdir(AUTH_LOG_DIR) unless File.directory?(AUTH_LOG_DIR)
|
|
11
12
|
|
12
13
|
|
13
14
|
module Rails
|
14
|
-
def Rails.root
|
15
|
+
def Rails.root
|
15
16
|
'.'
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
-
|
20
|
+
Rails.application = Rails::Application.instance_exec { new }
|
21
|
+
|
22
|
+
Rails.application.routes.draw do
|
23
|
+
match '/dummy/very_low_security', :controller => :dummy, :action => :very_low_security
|
21
24
|
end
|
metadata
CHANGED
@@ -1,57 +1,57 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: role_based_authorization
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 2
|
8
|
-
- 1
|
9
|
-
version: 0.2.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Roberto Esposito
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
dependencies:
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-05-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: rails
|
22
|
-
|
23
|
-
|
24
|
-
requirements:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
25
19
|
- - ~>
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
|
28
|
-
- 2
|
29
|
-
- 3
|
30
|
-
version: "2.3"
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3'
|
31
22
|
type: :runtime
|
32
|
-
version_requirements: *id001
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: mocha
|
35
23
|
prerelease: false
|
36
|
-
|
37
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
38
35
|
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
|
41
|
-
- 0
|
42
|
-
version: "0"
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
43
38
|
type: :runtime
|
44
|
-
|
45
|
-
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Provides a simple DSL for specifying the authorization logic of your
|
47
|
+
application. Install the gem, add a role attribute to your user model and your almost
|
48
|
+
ready to go.
|
46
49
|
email: boborbt@gmail.com
|
47
50
|
executables: []
|
48
|
-
|
49
51
|
extensions: []
|
50
|
-
|
51
|
-
extra_rdoc_files:
|
52
|
+
extra_rdoc_files:
|
52
53
|
- README.rdoc
|
53
|
-
files:
|
54
|
-
- .gitignore
|
54
|
+
files:
|
55
55
|
- MIT-LICENSE
|
56
56
|
- README.rdoc
|
57
57
|
- Rakefile
|
@@ -66,37 +66,28 @@ files:
|
|
66
66
|
- test/authorization_logger_test.rb
|
67
67
|
- test/role_based_authorization_test.rb
|
68
68
|
- test/test_helper.rb
|
69
|
-
has_rdoc: true
|
70
69
|
homepage: http://github.com/boborbt/role_based_authorization
|
71
70
|
licenses: []
|
72
|
-
|
73
71
|
post_install_message:
|
74
|
-
rdoc_options:
|
75
|
-
|
76
|
-
require_paths:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
77
74
|
- lib
|
78
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
requirements:
|
87
|
-
- -
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
|
90
|
-
- 0
|
91
|
-
version: "0"
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ! '>='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
92
87
|
requirements: []
|
93
|
-
|
94
88
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.
|
89
|
+
rubygems_version: 1.8.24
|
96
90
|
signing_key:
|
97
91
|
specification_version: 3
|
98
92
|
summary: Basic authorization module for rails
|
99
|
-
test_files:
|
100
|
-
- test/authorization_logger_test.rb
|
101
|
-
- test/role_based_authorization_test.rb
|
102
|
-
- test/test_helper.rb
|
93
|
+
test_files: []
|
data/.gitignore
DELETED