kibali 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +110 -0
- data/LICENSE.txt +20 -0
- data/README.md +183 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/lib/kibali/access_control.rb +89 -0
- data/lib/kibali/base.rb +79 -0
- data/lib/kibali/control.rb +39 -0
- data/lib/kibali/railtie.rb +17 -0
- data/lib/kibali/subject_extensions.rb +91 -0
- data/lib/kibali.rb +28 -0
- data/markdown.rb +38 -0
- data/test/app/controllers/application_controller.rb +21 -0
- data/test/app/controllers/empty_controller.rb +34 -0
- data/test/config/routes.rb +6 -0
- data/test/config.ru +0 -0
- data/test/ctlr_helper.rb +77 -0
- data/test/factories/units_factory.rb +39 -0
- data/test/helper.rb +61 -0
- data/test/script/rails +0 -0
- data/test/support/models.rb +8 -0
- data/test/support/schema.rb +25 -0
- data/test/test_access.rb +142 -0
- data/test/test_kibali.rb +140 -0
- metadata +140 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem 'rails', '~> 3.2.8'
|
6
|
+
|
7
|
+
# Add dependencies to develop your gem here.
|
8
|
+
# Include everything needed to run rake, tests, features, etc.
|
9
|
+
group :development, :test do
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "jeweler", "~> 1.8.4"
|
12
|
+
gem 'sqlite3'
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem "factory_girl"
|
17
|
+
gem "shoulda"
|
18
|
+
# Pretty printed test output
|
19
|
+
gem 'turn', :require => false
|
20
|
+
end
|
21
|
+
|
22
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (3.2.9)
|
5
|
+
actionpack (= 3.2.9)
|
6
|
+
mail (~> 2.4.4)
|
7
|
+
actionpack (3.2.9)
|
8
|
+
activemodel (= 3.2.9)
|
9
|
+
activesupport (= 3.2.9)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
journey (~> 1.0.4)
|
13
|
+
rack (~> 1.4.0)
|
14
|
+
rack-cache (~> 1.2)
|
15
|
+
rack-test (~> 0.6.1)
|
16
|
+
sprockets (~> 2.2.1)
|
17
|
+
activemodel (3.2.9)
|
18
|
+
activesupport (= 3.2.9)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
activerecord (3.2.9)
|
21
|
+
activemodel (= 3.2.9)
|
22
|
+
activesupport (= 3.2.9)
|
23
|
+
arel (~> 3.0.2)
|
24
|
+
tzinfo (~> 0.3.29)
|
25
|
+
activeresource (3.2.9)
|
26
|
+
activemodel (= 3.2.9)
|
27
|
+
activesupport (= 3.2.9)
|
28
|
+
activesupport (3.2.9)
|
29
|
+
i18n (~> 0.6)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
ansi (1.4.3)
|
32
|
+
arel (3.0.2)
|
33
|
+
builder (3.0.4)
|
34
|
+
erubis (2.7.0)
|
35
|
+
factory_girl (4.1.0)
|
36
|
+
activesupport (>= 3.0.0)
|
37
|
+
git (1.2.5)
|
38
|
+
hike (1.2.1)
|
39
|
+
i18n (0.6.1)
|
40
|
+
jeweler (1.8.4)
|
41
|
+
bundler (~> 1.0)
|
42
|
+
git (>= 1.2.5)
|
43
|
+
rake
|
44
|
+
rdoc
|
45
|
+
journey (1.0.4)
|
46
|
+
json (1.7.5)
|
47
|
+
mail (2.4.4)
|
48
|
+
i18n (>= 0.4.0)
|
49
|
+
mime-types (~> 1.16)
|
50
|
+
treetop (~> 1.4.8)
|
51
|
+
mime-types (1.19)
|
52
|
+
multi_json (1.3.7)
|
53
|
+
polyglot (0.3.3)
|
54
|
+
rack (1.4.1)
|
55
|
+
rack-cache (1.2)
|
56
|
+
rack (>= 0.4)
|
57
|
+
rack-ssl (1.3.2)
|
58
|
+
rack
|
59
|
+
rack-test (0.6.2)
|
60
|
+
rack (>= 1.0)
|
61
|
+
rails (3.2.9)
|
62
|
+
actionmailer (= 3.2.9)
|
63
|
+
actionpack (= 3.2.9)
|
64
|
+
activerecord (= 3.2.9)
|
65
|
+
activeresource (= 3.2.9)
|
66
|
+
activesupport (= 3.2.9)
|
67
|
+
bundler (~> 1.0)
|
68
|
+
railties (= 3.2.9)
|
69
|
+
railties (3.2.9)
|
70
|
+
actionpack (= 3.2.9)
|
71
|
+
activesupport (= 3.2.9)
|
72
|
+
rack-ssl (~> 1.3.2)
|
73
|
+
rake (>= 0.8.7)
|
74
|
+
rdoc (~> 3.4)
|
75
|
+
thor (>= 0.14.6, < 2.0)
|
76
|
+
rake (10.0.2)
|
77
|
+
rdoc (3.12)
|
78
|
+
json (~> 1.4)
|
79
|
+
shoulda (3.3.2)
|
80
|
+
shoulda-context (~> 1.0.1)
|
81
|
+
shoulda-matchers (~> 1.4.1)
|
82
|
+
shoulda-context (1.0.1)
|
83
|
+
shoulda-matchers (1.4.1)
|
84
|
+
activesupport (>= 3.0.0)
|
85
|
+
sprockets (2.2.1)
|
86
|
+
hike (~> 1.2)
|
87
|
+
multi_json (~> 1.0)
|
88
|
+
rack (~> 1.0)
|
89
|
+
tilt (~> 1.1, != 1.3.0)
|
90
|
+
sqlite3 (1.3.6)
|
91
|
+
thor (0.16.0)
|
92
|
+
tilt (1.3.3)
|
93
|
+
treetop (1.4.12)
|
94
|
+
polyglot
|
95
|
+
polyglot (>= 0.3.1)
|
96
|
+
turn (0.9.6)
|
97
|
+
ansi
|
98
|
+
tzinfo (0.3.35)
|
99
|
+
|
100
|
+
PLATFORMS
|
101
|
+
ruby
|
102
|
+
|
103
|
+
DEPENDENCIES
|
104
|
+
factory_girl
|
105
|
+
jeweler (~> 1.8.4)
|
106
|
+
rails (~> 3.2.8)
|
107
|
+
rdoc (~> 3.12)
|
108
|
+
shoulda
|
109
|
+
sqlite3
|
110
|
+
turn
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Daudi Amani
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
# kibali
|
2
|
+
|
3
|
+
Kibali is a simple replacement for ACL9, a role-based authentication gem.
|
4
|
+
Kibali is primarily oriented for functioning as a before\_filter role authentication
|
5
|
+
scheme for Rails controllers.
|
6
|
+
|
7
|
+
## Basic concepts
|
8
|
+
Authentication is often called for on a controller-by-controller basis, restricting
|
9
|
+
actions to users who possess certain roles. Kibali (current version) assumes only one role
|
10
|
+
per user. Kibali requires a _current\_user_ method accessible at the controller level
|
11
|
+
and which returns a User object.
|
12
|
+
|
13
|
+
Kibali adds, to the User model, role accessor methods: has\_role?, has\_role!, get\_role
|
14
|
+
|
15
|
+
## Structure
|
16
|
+
|
17
|
+
* necessary models: user, roles, roles\_users (join table)
|
18
|
+
* necessary migrations (for kibali): roles, roles\_users (join table)
|
19
|
+
|
20
|
+
## Dependency requirements
|
21
|
+
|
22
|
+
* Rails 3.2 or higher
|
23
|
+
|
24
|
+
## Installation
|
25
|
+
|
26
|
+
Either install the gem manually:
|
27
|
+
|
28
|
+
```
|
29
|
+
$ gem install
|
30
|
+
```
|
31
|
+
|
32
|
+
Or use bundler and place in your Gemfile
|
33
|
+
|
34
|
+
```
|
35
|
+
gem 'kibali'
|
36
|
+
```
|
37
|
+
|
38
|
+
## Setup
|
39
|
+
|
40
|
+
### Defaults assumed
|
41
|
+
|
42
|
+
**User** is the subject model:
|
43
|
+
indicate by inserting the following macro after the class definition:
|
44
|
+
|
45
|
+
```
|
46
|
+
acts_as_authorization_subject
|
47
|
+
```
|
48
|
+
|
49
|
+
**Role** is the role model:
|
50
|
+
indicate by inserting the following macro after the class definition:
|
51
|
+
|
52
|
+
```
|
53
|
+
acts_as_authorization_role
|
54
|
+
```
|
55
|
+
|
56
|
+
Note: the gem allows the default model/table names to be changed, but I haven't built tests
|
57
|
+
for verifying that the changes will work.
|
58
|
+
|
59
|
+
```
|
60
|
+
class Role < ActiveRecord::Base
|
61
|
+
acts_as_authorization_role
|
62
|
+
end
|
63
|
+
|
64
|
+
class User < ActiveRecord::Base
|
65
|
+
acts_as_authorization_subject
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
### Migrations required
|
70
|
+
|
71
|
+
The roles table must be created (sorry, no generator yet)
|
72
|
+
Some of the fields are legacy from acl9 and currently are not used.
|
73
|
+
|
74
|
+
```
|
75
|
+
create_table "roles", :force => true do |t|
|
76
|
+
t.string "name", :limit => 40
|
77
|
+
t.string "authorizable_type", :limit => 40
|
78
|
+
t.string "authorizable_id"
|
79
|
+
t.boolean "system", :default=>false
|
80
|
+
t.datetime "created_at"
|
81
|
+
t.datetime "updated_at"
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
and the join table
|
86
|
+
|
87
|
+
```
|
88
|
+
create_table :roles_users, :id => false, :force => true do |t|
|
89
|
+
t.column :user_id, :integer
|
90
|
+
t.column :role_id, :integer
|
91
|
+
end
|
92
|
+
add_index :roles_users, :user_id
|
93
|
+
```
|
94
|
+
|
95
|
+
|
96
|
+
## Usage
|
97
|
+
|
98
|
+
At the head of every controller for which you wish to control user access,
|
99
|
+
you'll need to place an _access_control_ macro which is used to generate a
|
100
|
+
before_filter for the authorization checks. In the testing, I had to place the
|
101
|
+
parameter in a seperate statement because syntax errors were encountered. That
|
102
|
+
might be due to the limited test structure used. I'll show both forms here.
|
103
|
+
|
104
|
+
Unauthorized access yields an exception: Kibali::AccessDenied .
|
105
|
+
Syntax errors in formulating the control parameters will also raise an exception: Kibali::SyntaxError .
|
106
|
+
You'll probably want to catch those exceptions and handle them gracefully, probably in your ApplicationController.
|
107
|
+
|
108
|
+
Notice that roles, limit_types, and controller actions are all expected to be symbols.
|
109
|
+
|
110
|
+
You have complete freedom to define roles to be whatever you want: except for the reserved words: :all, :anonymous.
|
111
|
+
|
112
|
+
The access limitation types are:
|
113
|
+
|
114
|
+
* :allow, :to, :only -- control what access is allowed; all else will be denied
|
115
|
+
* :deny, :except -- control what is denied; all else will be permitted
|
116
|
+
|
117
|
+
The action list can be empty; in which case, for :allow, all actions are permitted; and for :deny, no actions are permitted.
|
118
|
+
If both limit_type and action_list are missing, then :allow => [] will be assumed.
|
119
|
+
|
120
|
+
```
|
121
|
+
class AnyController < ApplicationController
|
122
|
+
|
123
|
+
access_control {
|
124
|
+
:admin => { :allow => [] },
|
125
|
+
:manager => { :deny => [ :delete, :edit ] },
|
126
|
+
:member => { :allow => [ :index, :show ] }
|
127
|
+
}
|
128
|
+
```
|
129
|
+
|
130
|
+
alternatively
|
131
|
+
|
132
|
+
```
|
133
|
+
class AnyController < ApplicationController
|
134
|
+
|
135
|
+
control_parameters = {
|
136
|
+
:admin => { :allow => [] },
|
137
|
+
:manager => { :deny => [ :delete, :edit ] },
|
138
|
+
:member => { :allow => [ :index, :show ] }
|
139
|
+
}
|
140
|
+
access_control control_parameters
|
141
|
+
```
|
142
|
+
|
143
|
+
Catch exceptions:
|
144
|
+
|
145
|
+
```
|
146
|
+
class ApplicationController < ActionController::Base
|
147
|
+
rescue_from Kibali::AccessDenied do |e|
|
148
|
+
# do something here
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
|
153
|
+
## Examples
|
154
|
+
|
155
|
+
Please see the examples in the test folder
|
156
|
+
|
157
|
+
## Acknowledgements
|
158
|
+
|
159
|
+
Kibali was influenced by the acl9 gem (https://github.com/be9/acl9).
|
160
|
+
I used acl9 for a number of years until it broke under Rails 3.2.x with a SystemStack error.
|
161
|
+
Trying to fix the bug proved to be difficult due to the extent of meta programming. Noting that Rails now
|
162
|
+
had a simple way to designate a class to handle before_filters
|
163
|
+
(Gavin Morrice's excellent tutorial: http://gavinmorrice.com/blog/posts/15-dryer-neater-rails-before_filters-using-classes),
|
164
|
+
I decided that a simpler role-based authorization Rails 3.2.x gem would be valuable. As I already had a production app based
|
165
|
+
on acl9, I wanted the conversion to be as seamless as possible. I've kept the same tables and naming. And I've made
|
166
|
+
the access_control syntax similar (though not the same). I did keep the same model macro names and config default variables,
|
167
|
+
but all access_control code has changed. The tests are all different.
|
168
|
+
|
169
|
+
|
170
|
+
## Contributing to kibali
|
171
|
+
|
172
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
173
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
174
|
+
* Fork the project
|
175
|
+
* Start a feature/bugfix branch
|
176
|
+
* Commit and push until you are happy with your contribution
|
177
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
178
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
179
|
+
|
180
|
+
## Copyright
|
181
|
+
|
182
|
+
Copyright (c) 2012 Daudi Amani. See LICENSE.txt for further details.
|
183
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "kibali"
|
18
|
+
gem.homepage = "http://github.com/dsaronin@gmail.com/kibali"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{rails role authentication}
|
21
|
+
gem.description = %Q{simple Rails role authentication}
|
22
|
+
gem.email = "dsaronin@gmail.com"
|
23
|
+
gem.authors = ["Daudi Amani"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
# ------------------------------------------------------------------------
|
30
|
+
# don't use normal Rake test routine because of double factory_girl
|
31
|
+
# ------------------------------------------------------------------------
|
32
|
+
task :test do
|
33
|
+
ruby '-I test "test/test_kibali.rb"'
|
34
|
+
ruby '-I test "test/test_access.rb"'
|
35
|
+
end # test task
|
36
|
+
|
37
|
+
task :default => :test
|
38
|
+
|
39
|
+
require 'rdoc/task'
|
40
|
+
Rake::RDocTask.new do |rdoc|
|
41
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "kibali #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Kibali
|
2
|
+
class AccessControl < Struct.new( :role_control_hash )
|
3
|
+
|
4
|
+
# #############################################################################
|
5
|
+
# #############################################################################
|
6
|
+
|
7
|
+
# ------------------------------------------------------------------------------
|
8
|
+
# EXCEPTION:
|
9
|
+
# Kibali::AccessDenied -- execution denied
|
10
|
+
# Kibali::SyntaxError -- unexpected limit_type, or action_type
|
11
|
+
# #############################################################################
|
12
|
+
# see test/app/controllers/empty_controller.rb for sample syntax
|
13
|
+
|
14
|
+
# ---------------------------------------------------------------------------------
|
15
|
+
# possible states and resultant handlings
|
16
|
+
# limit_type action_list permitted handling
|
17
|
+
# ---------------------------------------------------------------------------------
|
18
|
+
# :allow, :to, :only [] empty, action matched permitted
|
19
|
+
# action not matched denied
|
20
|
+
#
|
21
|
+
# :deny, :except [] empty, action matched denied
|
22
|
+
# action not matched permitted
|
23
|
+
#
|
24
|
+
# ---------------------------------------------------------------------------------
|
25
|
+
# ------------------------------------------------------------------------------
|
26
|
+
def before( controller )
|
27
|
+
|
28
|
+
my_role = controller.current_user.get_role.name.to_sym
|
29
|
+
|
30
|
+
# if current_user's role not present; check if anonymous is
|
31
|
+
unless self.role_control_hash.member?( my_role )
|
32
|
+
# here if current_user's role not specificied in control list
|
33
|
+
|
34
|
+
if self.role_control_hash.member?( :anonymous ) # if anonymous is...
|
35
|
+
my_role = :anonymous # ...then handle anonymously
|
36
|
+
else # unauthorized access of controller
|
37
|
+
raise Kibali::AccessDenied
|
38
|
+
end # if..then..else anonymous check
|
39
|
+
|
40
|
+
end # unless current_user has a role to be checked
|
41
|
+
|
42
|
+
expected_action = controller.action_name.to_sym # action being attempted
|
43
|
+
|
44
|
+
permitted = true # presume authorized
|
45
|
+
|
46
|
+
# now check the action_hash for action access
|
47
|
+
# shown as a loop, but only the first entry is meaningful
|
48
|
+
self.role_control_hash[my_role].each do |limit_type, action_list|
|
49
|
+
|
50
|
+
permitted = ( action_list.empty? || action_list.include?( expected_action ) )
|
51
|
+
|
52
|
+
case limit_type
|
53
|
+
when :allow, :to, :only then permitted
|
54
|
+
when :deny, :except then permitted = !permitted
|
55
|
+
else
|
56
|
+
raise Kibali::SyntaxError, "Unrecognized access_control limit_type: #{limit_type}"
|
57
|
+
end # case
|
58
|
+
|
59
|
+
|
60
|
+
unless permitted # ... figure out the type of exception
|
61
|
+
if action_list.any?{ |actn| actn.class.name != "Symbol" }
|
62
|
+
raise Kibali::SyntaxError, "all actions should be symbols"
|
63
|
+
else
|
64
|
+
raise Kibali::AccessDenied
|
65
|
+
end # syntax checking
|
66
|
+
end # unless
|
67
|
+
|
68
|
+
break # always break the loop at success
|
69
|
+
|
70
|
+
end # do check if role
|
71
|
+
|
72
|
+
return permitted
|
73
|
+
end
|
74
|
+
|
75
|
+
# ------------------------------------------------------------------------------
|
76
|
+
# ------------------------------------------------------------------------------
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# ------------------------------------------------------------------------------
|
81
|
+
# ------------------------------------------------------------------------------
|
82
|
+
|
83
|
+
# ------------------------------------------------------------------------------
|
84
|
+
# ------------------------------------------------------------------------------
|
85
|
+
|
86
|
+
# #############################################################################
|
87
|
+
# #############################################################################
|
88
|
+
end
|
89
|
+
end
|
data/lib/kibali/base.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module Kibali
|
2
|
+
module Base
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
# #############################################################################
|
9
|
+
# @example
|
10
|
+
# class Role < ActiveRecord::Base
|
11
|
+
# acts_as_authorization_role
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @see Kibali::ModelExtensions::Subject#has_role!
|
15
|
+
# @see Kibali::ModelExtensions::Subject#has_role?
|
16
|
+
# @see Kibali::ModelExtensions::Subject#has_no_role!
|
17
|
+
# #############################################################################
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
|
21
|
+
# ------------------------------------------------------------------------
|
22
|
+
# acts_as_authorization_subject -- designates model to be user subject
|
23
|
+
# ------------------------------------------------------------------------
|
24
|
+
def acts_as_authorization_subject(options = {})
|
25
|
+
|
26
|
+
assoc = options[:association_name] || Kibali::config[:default_roles_collection_name]
|
27
|
+
role = options[:role_class_name] || Kibali::config[:default_role_class_name]
|
28
|
+
join_table = options[:join_table_name] || Kibali::config[:default_join_table_name]
|
29
|
+
|
30
|
+
has_and_belongs_to_many assoc, :class_name => role, :join_table => join_table
|
31
|
+
|
32
|
+
cattr_accessor :_auth_role_class_name, :_auth_subject_class_name, :_auth_role_assoc_name
|
33
|
+
|
34
|
+
self._auth_role_class_name = role
|
35
|
+
self._auth_subject_class_name = self.to_s
|
36
|
+
self._auth_role_assoc_name = assoc
|
37
|
+
|
38
|
+
include Kibali::SubjectExtensions
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
# ------------------------------------------------------------------------
|
43
|
+
# ------------------------------------------------------------------------
|
44
|
+
def acts_as_authorization_role(options = {})
|
45
|
+
|
46
|
+
assoc = options[:association_name] || Kibali::config[:default_users_collection_name]
|
47
|
+
subject = options[:subject_class_name] || Kibali::config[:default_subject_class_name]
|
48
|
+
join_table = options[:join_table_name] || Kibali::config[:default_join_table_name]
|
49
|
+
|
50
|
+
has_and_belongs_to_many assoc, :class_name => subject, :join_table => join_table
|
51
|
+
|
52
|
+
cattr_accessor :_auth_role_class_name, :_auth_subject_class_name, :_auth_role_assoc_name
|
53
|
+
|
54
|
+
self._auth_role_class_name = self.to_s
|
55
|
+
self._auth_subject_class_name = subject
|
56
|
+
self._auth_role_assoc_name = assoc
|
57
|
+
|
58
|
+
scope :named_role, lambda { |role_name| where(["name = ?", role_name.to_s]) }
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# ------------------------------------------------------------------------
|
63
|
+
# ------------------------------------------------------------------------
|
64
|
+
|
65
|
+
# ------------------------------------------------------------------------
|
66
|
+
# ------------------------------------------------------------------------
|
67
|
+
|
68
|
+
# ------------------------------------------------------------------------
|
69
|
+
# ------------------------------------------------------------------------
|
70
|
+
|
71
|
+
# ------------------------------------------------------------------------
|
72
|
+
# ------------------------------------------------------------------------
|
73
|
+
|
74
|
+
end # module ClassMethods
|
75
|
+
# #############################################################################
|
76
|
+
# #############################################################################
|
77
|
+
|
78
|
+
end # module Base
|
79
|
+
end # module Kibali
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Kibali
|
2
|
+
module Control
|
3
|
+
|
4
|
+
# #############################################################################
|
5
|
+
# #############################################################################
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.extend ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
# #############################################################################
|
12
|
+
# #############################################################################
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
def access_control( role_control_hash, options = {} )
|
16
|
+
before_filter Kibali::AccessControl.new( role_control_hash ), options
|
17
|
+
end
|
18
|
+
|
19
|
+
end # module ClassMethods
|
20
|
+
|
21
|
+
# #############################################################################
|
22
|
+
# #############################################################################
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# ------------------------------------------------------------------------------
|
27
|
+
# ------------------------------------------------------------------------------
|
28
|
+
|
29
|
+
# ------------------------------------------------------------------------------
|
30
|
+
# ------------------------------------------------------------------------------
|
31
|
+
|
32
|
+
# ------------------------------------------------------------------------------
|
33
|
+
# ------------------------------------------------------------------------------
|
34
|
+
|
35
|
+
# #############################################################################
|
36
|
+
# #############################################################################
|
37
|
+
|
38
|
+
end # module Control
|
39
|
+
end # module Kibali
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'kibali'
|
2
|
+
require 'rails'
|
3
|
+
|
4
|
+
module Kibali
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
initializer :after_initialize do
|
7
|
+
|
8
|
+
ActiveRecord::Base.send(:include, Kibali::Base)
|
9
|
+
ActionController::Base.send(:include, Kibali::Control)
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
# rake_tasks do
|
14
|
+
# load 'kibali/tasks.rb'
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
end
|