kibali 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +21 -16
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/kibali.gemspec +77 -0
- data/lib/kibali/access_control.rb +16 -9
- data/test/app/controllers/anon_controller.rb +28 -0
- data/test/app/controllers/application_controller.rb +3 -1
- data/test/test_access.rb +9 -0
- data/test/test_anon.rb +61 -0
- metadata +6 -3
data/README.md
CHANGED
@@ -97,9 +97,12 @@ and the join table
|
|
97
97
|
|
98
98
|
At the head of every controller for which you wish to control user access,
|
99
99
|
you'll need to place an _access_control_ macro which is used to generate a
|
100
|
-
before_filter for the authorization checks.
|
101
|
-
|
102
|
-
|
100
|
+
before_filter for the authorization checks. The macro takes a hash of role
|
101
|
+
specification parameters. These must be specified prior to the macro and
|
102
|
+
then referenced as the macro's parameter parameter. I cannot be specified
|
103
|
+
in-line because Rails is treating it as a before_filter and so expects a
|
104
|
+
before_filter type of ( :only =>, :except => ) hash which would then apply
|
105
|
+
to the before_filter itself and thus bypass any explicit checking.
|
103
106
|
|
104
107
|
Unauthorized access yields an exception: Kibali::AccessDenied .
|
105
108
|
Syntax errors in formulating the control parameters will also raise an exception: Kibali::SyntaxError .
|
@@ -108,7 +111,18 @@ You'll probably want to catch those exceptions and handle them gracefully, proba
|
|
108
111
|
Notice that roles, limit_types, and controller actions are all expected to be symbols.
|
109
112
|
|
110
113
|
You have complete freedom to define roles to be whatever you want: except for the reserved words: :all, :anonymous.
|
114
|
+
The usage of :all, :anonymous is explained with the following logic.
|
111
115
|
|
116
|
+
* if current_user.nil?, then proceed as :anonymous if :anonymous is referenced in the role_control_hash
|
117
|
+
* if user's role is not referenced, then proceed as :all if :all is referenced in the role_control_hash
|
118
|
+
* else proceed and evaluate the role_control_hash with user's role
|
119
|
+
|
120
|
+
This means that :all will **only** be invoked if a user has a role which is **NOT** specified in the role_control_hash and
|
121
|
+
if :all **is** specified in the hash. In that sense :unspecified would be more accurate than :all, but :all is shorter and
|
122
|
+
handier to work with.
|
123
|
+
And it means that :anonymous will **only** be invoked if current_user.nil? is true and
|
124
|
+
if :anonymous **is** specified in the hash.
|
125
|
+
|
112
126
|
The access limitation types are:
|
113
127
|
|
114
128
|
* :allow, :to, :only -- control what access is allowed; all else will be denied
|
@@ -117,26 +131,17 @@ The access limitation types are:
|
|
117
131
|
The action list can be empty; in which case, for :allow, all actions are permitted; and for :deny, no actions are permitted.
|
118
132
|
If both limit_type and action_list are missing, then :allow => [] will be assumed.
|
119
133
|
|
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
134
|
```
|
133
135
|
class AnyController < ApplicationController
|
134
136
|
|
135
137
|
control_parameters = {
|
136
138
|
:admin => { :allow => [] },
|
137
139
|
:manager => { :deny => [ :delete, :edit ] },
|
138
|
-
:member => { :allow => [ :index, :show ] }
|
140
|
+
:member => { :allow => [ :index, :show ] },
|
141
|
+
:anonymous => { :allow => [:index ] },
|
142
|
+
:all => { :deny => [:edit, :update] }
|
139
143
|
}
|
144
|
+
|
140
145
|
access_control control_parameters
|
141
146
|
```
|
142
147
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/kibali.gemspec
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "kibali"
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Daudi Amani"]
|
12
|
+
s.date = "2012-11-24"
|
13
|
+
s.description = "simple Rails role authentication"
|
14
|
+
s.email = "dsaronin@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"kibali.gemspec",
|
28
|
+
"lib/kibali.rb",
|
29
|
+
"lib/kibali/access_control.rb",
|
30
|
+
"lib/kibali/base.rb",
|
31
|
+
"lib/kibali/control.rb",
|
32
|
+
"lib/kibali/railtie.rb",
|
33
|
+
"lib/kibali/subject_extensions.rb",
|
34
|
+
"markdown.rb",
|
35
|
+
"test/app/controllers/anon_controller.rb",
|
36
|
+
"test/app/controllers/application_controller.rb",
|
37
|
+
"test/app/controllers/empty_controller.rb",
|
38
|
+
"test/config.ru",
|
39
|
+
"test/config/routes.rb",
|
40
|
+
"test/ctlr_helper.rb",
|
41
|
+
"test/factories/units_factory.rb",
|
42
|
+
"test/helper.rb",
|
43
|
+
"test/script/rails",
|
44
|
+
"test/support/models.rb",
|
45
|
+
"test/support/schema.rb",
|
46
|
+
"test/test_access.rb",
|
47
|
+
"test/test_anon.rb",
|
48
|
+
"test/test_kibali.rb"
|
49
|
+
]
|
50
|
+
s.homepage = "http://github.com/dsaronin@gmail.com/kibali"
|
51
|
+
s.licenses = ["MIT"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = "1.8.24"
|
54
|
+
s.summary = "rails role authentication"
|
55
|
+
|
56
|
+
if s.respond_to? :specification_version then
|
57
|
+
s.specification_version = 3
|
58
|
+
|
59
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
60
|
+
s.add_runtime_dependency(%q<rails>, ["~> 3.2.8"])
|
61
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
62
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
63
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<rails>, ["~> 3.2.8"])
|
66
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
67
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
68
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
69
|
+
end
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<rails>, ["~> 3.2.8"])
|
72
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
74
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -22,26 +22,33 @@ module Kibali
|
|
22
22
|
# action not matched permitted
|
23
23
|
#
|
24
24
|
# ---------------------------------------------------------------------------------
|
25
|
+
# if current_user.nil?, proceed as :anonymous if so referenced in role_control_hash
|
26
|
+
# if user's role is not referenced, proceed as :all if so referenced in role_control_hash
|
27
|
+
# else proceed with user's role
|
25
28
|
# ------------------------------------------------------------------------------
|
26
29
|
def before( controller )
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
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...
|
31
|
+
if controller.current_user.nil? # no user defined; anonymous permitted?
|
32
|
+
|
33
|
+
if self.role_control_hash.member?( :anonymous ) # if anonymous is referenced, continue...
|
35
34
|
my_role = :anonymous # ...then handle anonymously
|
36
35
|
else # unauthorized access of controller
|
37
36
|
raise Kibali::AccessDenied
|
38
37
|
end # if..then..else anonymous check
|
39
38
|
|
40
|
-
|
39
|
+
elsif !self.role_control_hash.member?( my_role = controller.current_user.get_role.name.to_sym )
|
40
|
+
|
41
|
+
if self.role_control_hash.member?( :all ) # if all is referenced, continue...
|
42
|
+
my_role = :all # ...then handle as all
|
43
|
+
else # unauthorized access of controller
|
44
|
+
raise Kibali::AccessDenied
|
45
|
+
end # if..then..else anonymous check
|
46
|
+
|
47
|
+
end # if..elsif check for anonymous or role not allowed
|
41
48
|
|
42
49
|
expected_action = controller.action_name.to_sym # action being attempted
|
43
50
|
|
44
|
-
|
51
|
+
permitted = true # presume authorized
|
45
52
|
|
46
53
|
# now check the action_hash for action access
|
47
54
|
# shown as a loop, but only the first entry is meaningful
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class AnonController < ApplicationController
|
2
|
+
before_filter :set_current_user
|
3
|
+
# before_filter :trace_setup
|
4
|
+
|
5
|
+
control_hash = {
|
6
|
+
:admin => { :allow => [] },
|
7
|
+
:anonymous => { :allow => [ :index ] },
|
8
|
+
:all => { :deny => [ :edit ] },
|
9
|
+
}
|
10
|
+
|
11
|
+
access_control control_hash
|
12
|
+
|
13
|
+
|
14
|
+
[:index, :show, :new, :edit, :update, :delete, :destroy].each do |act|
|
15
|
+
define_method(act) { render :text => 'OK' }
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def trace_setup
|
21
|
+
puts ">>>>>> trace/self: #{self.class.name} <<<<<<"
|
22
|
+
puts ">>>>>> trace/current_user: #{self.respond_to?(:current_user).to_s} <<<<<<"
|
23
|
+
puts ">>>>>> trace/method_defined: #{EmptyController.method_defined?(:current_user).to_s} <<<<<<"
|
24
|
+
puts ">>>>>> trace/user is: #{current_user.name.to_s} <<<<<<"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
data/test/test_access.rb
CHANGED
@@ -95,6 +95,15 @@ context "ctlr" do
|
|
95
95
|
|
96
96
|
|
97
97
|
|
98
|
+
should 'reject anonymous not referenced ' do
|
99
|
+
|
100
|
+
assert_raise( Kibali::AccessDenied ) do
|
101
|
+
get :index, :user => ""
|
102
|
+
end # block
|
103
|
+
|
104
|
+
end # should do
|
105
|
+
|
106
|
+
|
98
107
|
should 'deny others all access ' do
|
99
108
|
@deshaun.has_role!( :wildblue )
|
100
109
|
|
data/test/test_anon.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'ctlr_helper'
|
2
|
+
|
3
|
+
require 'anon_controller'
|
4
|
+
|
5
|
+
class AnonControllerTest < ActionController::TestCase
|
6
|
+
|
7
|
+
context "ctlr" do
|
8
|
+
|
9
|
+
setup do
|
10
|
+
@demarcus = FactoryGirl.create( :user )
|
11
|
+
@deshaun = FactoryGirl.create( :user )
|
12
|
+
end
|
13
|
+
|
14
|
+
teardown do
|
15
|
+
User.destroy_all
|
16
|
+
Role.destroy_all
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'permit admin access _ implicit all 2' do
|
20
|
+
@demarcus.has_role!( :admin )
|
21
|
+
|
22
|
+
get :index, :user => @demarcus.id.to_s
|
23
|
+
assert_response :success
|
24
|
+
|
25
|
+
get :show, :user => @demarcus.id.to_s
|
26
|
+
assert_response :success
|
27
|
+
|
28
|
+
end # should do
|
29
|
+
|
30
|
+
|
31
|
+
should 'permit anonymous only access to index not show' do
|
32
|
+
|
33
|
+
get :index, :user => ""
|
34
|
+
assert_response :success
|
35
|
+
|
36
|
+
assert_raise( Kibali::AccessDenied ) do
|
37
|
+
get :show, :user => ""
|
38
|
+
end # block
|
39
|
+
|
40
|
+
end # should do
|
41
|
+
|
42
|
+
|
43
|
+
should 'unspecified access to everything except edit' do
|
44
|
+
@deshaun.has_role!( :manager )
|
45
|
+
|
46
|
+
get :index, :user => @deshaun.id.to_s
|
47
|
+
assert_response :success
|
48
|
+
get :show, :user => @deshaun.id.to_s
|
49
|
+
assert_response :success
|
50
|
+
|
51
|
+
assert_raise( Kibali::AccessDenied ) do
|
52
|
+
get :edit, :user => @deshaun.id.to_s
|
53
|
+
end # block
|
54
|
+
|
55
|
+
|
56
|
+
end # should do
|
57
|
+
|
58
|
+
|
59
|
+
end # context
|
60
|
+
|
61
|
+
end # class test
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kibali
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- README.md
|
91
91
|
- Rakefile
|
92
92
|
- VERSION
|
93
|
+
- kibali.gemspec
|
93
94
|
- lib/kibali.rb
|
94
95
|
- lib/kibali/access_control.rb
|
95
96
|
- lib/kibali/base.rb
|
@@ -97,6 +98,7 @@ files:
|
|
97
98
|
- lib/kibali/railtie.rb
|
98
99
|
- lib/kibali/subject_extensions.rb
|
99
100
|
- markdown.rb
|
101
|
+
- test/app/controllers/anon_controller.rb
|
100
102
|
- test/app/controllers/application_controller.rb
|
101
103
|
- test/app/controllers/empty_controller.rb
|
102
104
|
- test/config.ru
|
@@ -108,6 +110,7 @@ files:
|
|
108
110
|
- test/support/models.rb
|
109
111
|
- test/support/schema.rb
|
110
112
|
- test/test_access.rb
|
113
|
+
- test/test_anon.rb
|
111
114
|
- test/test_kibali.rb
|
112
115
|
homepage: http://github.com/dsaronin@gmail.com/kibali
|
113
116
|
licenses:
|
@@ -124,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
127
|
version: '0'
|
125
128
|
segments:
|
126
129
|
- 0
|
127
|
-
hash: -
|
130
|
+
hash: -877913475
|
128
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
132
|
none: false
|
130
133
|
requirements:
|