rbacanable 0.2 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/basic.rb +2 -2
- data/examples/roles.rb +5 -6
- data/lib/canable.rb +50 -31
- data/test/test_roles.rb +31 -3
- metadata +3 -2
data/examples/basic.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
4
|
+
require 'activesupport'
|
5
5
|
require 'canable'
|
6
6
|
|
7
7
|
class User
|
@@ -12,7 +12,7 @@ class User
|
|
12
12
|
@name = attributes[:name]
|
13
13
|
end
|
14
14
|
|
15
|
-
def can_update_article(article)
|
15
|
+
def can_update_article?(article)
|
16
16
|
article.creator == @name
|
17
17
|
end
|
18
18
|
end
|
data/examples/roles.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
3
|
require 'rubygems'
|
4
|
-
require '
|
4
|
+
require 'activesupport'
|
5
5
|
require 'canable'
|
6
6
|
require 'terminal-table/import'
|
7
7
|
|
@@ -47,14 +47,13 @@ end
|
|
47
47
|
class User
|
48
48
|
include Canable::Actor
|
49
49
|
attr_accessor :name
|
50
|
-
|
50
|
+
attr_accessor :role
|
51
51
|
default_role Canable::Roles::BasicRole
|
52
|
-
#
|
52
|
+
#role_attribute :@role #-- RBACanable by default looks in @role for a Module constant or string to use as a role
|
53
53
|
|
54
54
|
def initialize(attributes = {})
|
55
55
|
@name = attributes[:name]
|
56
56
|
@role = attributes[:role]
|
57
|
-
self.__initialize_canable_role # nessecary since initialize is overridden
|
58
57
|
end
|
59
58
|
|
60
59
|
def to_s
|
@@ -90,10 +89,10 @@ posts = [
|
|
90
89
|
|
91
90
|
|
92
91
|
user_table = table do |t|
|
93
|
-
t.headings = "User", "Resource", "Can View?", "Can Create?", "Can Update?", "Can Destroy?", "Role"
|
92
|
+
t.headings = "User", "Resource", "Can View?", "Can Create?", "Can Update?", "Can Destroy?", "@role", "Included Role"
|
94
93
|
users.each do |user|
|
95
94
|
posts.each do |post|
|
96
|
-
t << [user.to_s, post.to_s, user.can_view?(post), user.can_create?(post), user.can_update?(post), user.can_destroy?(post), user.canable_included_role]
|
95
|
+
t << [user.to_s, post.to_s, user.can_view?(post), user.can_create?(post), user.can_update?(post), user.can_destroy?(post), user.role, user.canable_included_role]
|
97
96
|
end
|
98
97
|
end
|
99
98
|
end
|
data/lib/canable.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Canable
|
2
|
-
Version = '0.2'
|
2
|
+
Version = '0.2.1'
|
3
3
|
|
4
4
|
# Module that holds all the can_action? methods.
|
5
5
|
module Cans; end
|
@@ -9,7 +9,6 @@ module Canable
|
|
9
9
|
|
10
10
|
# Module that is included by a role implementation
|
11
11
|
module Role
|
12
|
-
include Cans # each role has a distinct set of responses to all the can_action? methods
|
13
12
|
|
14
13
|
def self.included(base)
|
15
14
|
base.extend(ClassMethods)
|
@@ -53,39 +52,25 @@ module Canable
|
|
53
52
|
end
|
54
53
|
|
55
54
|
module Actor
|
55
|
+
include Cans # each role has a distinct set of responses to all the can_action? methods
|
56
56
|
attr_accessor :canable_included_role
|
57
|
-
|
57
|
+
|
58
58
|
def self.included(base)
|
59
59
|
base.extend(ClassMethods)
|
60
60
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
# ---------------
|
66
|
-
# RBAC Actor building DSL
|
67
|
-
# ---------------
|
68
|
-
|
69
|
-
def default_role(role)
|
70
|
-
self.canable_default_role = role
|
71
|
-
end
|
72
|
-
|
73
|
-
def role_attribute(attribute)
|
74
|
-
self.canable_role_attribute = attribute
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
def initialize(*args)
|
80
|
-
super(*args)
|
61
|
+
|
62
|
+
# Override attr_accessor to make sure the role has been included so that we can return an accurate value
|
63
|
+
# "lazy" role including
|
64
|
+
def canable_included_role
|
81
65
|
self.__initialize_canable_role
|
82
|
-
|
66
|
+
@canable_included_role
|
83
67
|
end
|
84
68
|
|
69
|
+
# Called every time a role is needed to make sure the lazy load has been completed
|
85
70
|
def __initialize_canable_role
|
86
|
-
|
87
|
-
|
88
|
-
role_constant = self.
|
71
|
+
return if @_canable_initialized == true
|
72
|
+
@_canable_intialize == true
|
73
|
+
role_constant = self.__get_role_constant
|
89
74
|
if role_constant == nil
|
90
75
|
default_role = self.class.canable_default_role
|
91
76
|
self.act(default_role) unless default_role == nil
|
@@ -94,13 +79,46 @@ module Canable
|
|
94
79
|
end
|
95
80
|
end
|
96
81
|
|
82
|
+
def __get_role_constant
|
83
|
+
if self.class.canable_role_proc.respond_to?(:call)
|
84
|
+
attribute = self.class.canable_role_proc.call(self)
|
85
|
+
elsif self.instance_variable_get(:@role)
|
86
|
+
attribute = @role
|
87
|
+
end
|
88
|
+
attribute || nil
|
89
|
+
end
|
90
|
+
|
97
91
|
# Sets the role of this actor by including a role module
|
98
92
|
def act(role)
|
93
|
+
unless(role.respond_to?(:included))
|
94
|
+
role = Canable::Roles.const_get((role.to_s.capitalize+"Role").intern)
|
95
|
+
end
|
96
|
+
self.extend role
|
99
97
|
self.canable_included_role = role
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
# ---------------
|
102
|
+
# RBAC Actor building DSL
|
103
|
+
# ---------------
|
104
|
+
|
105
|
+
module ClassMethods
|
106
|
+
attr_accessor :canable_default_role
|
107
|
+
attr_accessor :canable_role_proc
|
108
|
+
|
109
|
+
|
110
|
+
def default_role(role)
|
111
|
+
self.canable_default_role = role
|
112
|
+
end
|
113
|
+
|
114
|
+
def role_attribute(attribute)
|
115
|
+
self.canable_role_proc = Proc.new {|actor|
|
116
|
+
role = actor.instance_variable_get(attribute)
|
117
|
+
}
|
118
|
+
end
|
119
|
+
|
120
|
+
def role_proc(proc)
|
121
|
+
self.canable_role_proc = proc
|
104
122
|
end
|
105
123
|
end
|
106
124
|
end
|
@@ -154,6 +172,7 @@ module Canable
|
|
154
172
|
def self.add_can_method(can)
|
155
173
|
Cans.module_eval <<-EOM
|
156
174
|
def can_#{can}?(resource)
|
175
|
+
self.__initialize_canable_role if self.class.include?(Canable::Actor)
|
157
176
|
method = ("can_#{can}_"+resource.class.name.gsub(/::/,"_").downcase+"?").intern
|
158
177
|
if self.respond_to?(method, true)
|
159
178
|
self.send method, resource
|
data/test/test_roles.rb
CHANGED
@@ -134,7 +134,6 @@ class RolesTest < Test::Unit::TestCase
|
|
134
134
|
|
135
135
|
def initialize(role=nil)
|
136
136
|
@role = role
|
137
|
-
self.__initialize_canable_role # nessecary since initialize is overridden
|
138
137
|
end
|
139
138
|
end
|
140
139
|
|
@@ -164,7 +163,37 @@ class RolesTest < Test::Unit::TestCase
|
|
164
163
|
|
165
164
|
def initialize(role=nil)
|
166
165
|
@nonstandard = role
|
167
|
-
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
@default_user = userklass.new
|
170
|
+
@nondefault_user = userklass.new(@role2klass)
|
171
|
+
end
|
172
|
+
|
173
|
+
should "have included the correct roles" do
|
174
|
+
assert_equal @role1klass, @default_user.canable_included_role
|
175
|
+
assert_equal @role2klass, @nondefault_user.canable_included_role
|
176
|
+
end
|
177
|
+
|
178
|
+
should "be governed by the rules in their roles" do
|
179
|
+
assert @default_user.can_view?(@resource)
|
180
|
+
assert ! @nondefault_user.can_view?(@resource)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "and actors with a default role and a role proc" do
|
185
|
+
setup do
|
186
|
+
role1klass = @role1klass
|
187
|
+
userklass = Class.new do
|
188
|
+
include Canable::Actor
|
189
|
+
attr_accessor :attributes
|
190
|
+
|
191
|
+
default_role role1klass
|
192
|
+
role_proc Proc.new {|actor| actor.attributes[:role]}
|
193
|
+
|
194
|
+
def initialize(role=nil)
|
195
|
+
@attributes = {}
|
196
|
+
@attributes[:role] = role
|
168
197
|
end
|
169
198
|
end
|
170
199
|
|
@@ -245,7 +274,6 @@ class RolesTest < Test::Unit::TestCase
|
|
245
274
|
def initialize(_name, _role)
|
246
275
|
@name = _name
|
247
276
|
@role = _role
|
248
|
-
self.__initialize_canable_role # nessecary since initialize is overridden
|
249
277
|
end
|
250
278
|
end
|
251
279
|
|
metadata
CHANGED
@@ -5,7 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
|
8
|
+
- 1
|
9
|
+
version: 0.2.1
|
9
10
|
platform: ruby
|
10
11
|
authors:
|
11
12
|
- John Nunemaker
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-04-01 00:00:00 -04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|