rbacanable 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +4 -1
- data/examples/callbacks.rb +84 -0
- data/lib/canable.rb +8 -203
- data/lib/canable/actor.rb +76 -0
- data/lib/canable/canable.rb +82 -0
- data/lib/canable/cans.rb +38 -0
- data/lib/canable/enforcers.rb +14 -0
- data/lib/canable/role.rb +45 -0
- data/rbacanable.gemspec +83 -0
- data/test/helper.rb +13 -0
- data/test/test_ables.rb +81 -37
- metadata +23 -3
data/Rakefile
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
3
|
|
4
|
-
|
4
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
|
5
|
+
require 'canable'
|
5
6
|
|
6
7
|
begin
|
7
8
|
require 'jeweler'
|
@@ -16,6 +17,8 @@ begin
|
|
16
17
|
gem.add_development_dependency "shoulda", "2.10.3"
|
17
18
|
gem.add_development_dependency "mocha", "0.9.8"
|
18
19
|
gem.add_development_dependency "yard", ">= 0"
|
20
|
+
gem.add_development_dependency "activesupport", ">= 0"
|
21
|
+
|
19
22
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
23
|
end
|
21
24
|
Jeweler::GemcutterTasks.new
|
@@ -0,0 +1,84 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rubygems'
|
4
|
+
require 'activesupport'
|
5
|
+
require 'canable'
|
6
|
+
require 'terminal-table/import'
|
7
|
+
|
8
|
+
module Canable::Roles
|
9
|
+
module BasicRole
|
10
|
+
include Canable::Role
|
11
|
+
default_response false
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
module EmployeeRole
|
16
|
+
include Canable::Role
|
17
|
+
default_response false
|
18
|
+
|
19
|
+
def can_destroy_article?(article)
|
20
|
+
article.creator == @name
|
21
|
+
end
|
22
|
+
|
23
|
+
def can_update_article?(article)
|
24
|
+
article.creator == @name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class User
|
30
|
+
include Canable::Actor
|
31
|
+
attr_accessor :name
|
32
|
+
attr_accessor :role
|
33
|
+
|
34
|
+
default_role Canable::Roles::BasicRole
|
35
|
+
after_permissions_query :after_query
|
36
|
+
|
37
|
+
def after_query(options = {})
|
38
|
+
puts "After Query from Basic Role"
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(attributes = {})
|
42
|
+
@name = attributes[:name]
|
43
|
+
@role = attributes[:role]
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
"#{@role.to_s}: #{@name}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Article
|
52
|
+
include Canable::Ables
|
53
|
+
attr_accessor :creator
|
54
|
+
|
55
|
+
def initialize(attributes = {})
|
56
|
+
@creator = attributes[:creator]
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
"#{@creator}'s article"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
users = [
|
65
|
+
User.new(:name => "John", :role => :employee),
|
66
|
+
User.new(:name => "Jim")
|
67
|
+
]
|
68
|
+
|
69
|
+
posts = [
|
70
|
+
Article.new(:creator => "John"),
|
71
|
+
Article.new(:creator => "Jim"),
|
72
|
+
Article.new(:creator => "Harry")
|
73
|
+
]
|
74
|
+
|
75
|
+
|
76
|
+
user_table = table do |t|
|
77
|
+
t.headings = "User", "Resource", "Can View?", "Can Create?", "Can Update?", "Can Destroy?", "@role", "Included Role"
|
78
|
+
users.each do |user|
|
79
|
+
posts.each do |post|
|
80
|
+
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]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
puts user_table
|
data/lib/canable.rb
CHANGED
@@ -1,207 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# Module that holds all the [method]able_by? methods.
|
8
|
-
module Ables; end
|
9
|
-
|
10
|
-
# Module that is included by a role implementation
|
11
|
-
module Role
|
12
|
-
|
13
|
-
def self.included(base)
|
14
|
-
base.extend(ClassMethods)
|
15
|
-
end
|
16
|
-
|
17
|
-
# These are applied to the actual Role module 'instance' that includes this (Canable::Role) module
|
18
|
-
module ClassMethods
|
19
|
-
# Each role has a default query response, found in this variable
|
20
|
-
attr_accessor :_default_response
|
21
|
-
|
22
|
-
|
23
|
-
# Called when another Role imeplementation module tries to inherit an existing Role implementation
|
24
|
-
# Notice this method isn't self.included, this method becomes self.included on the module including this (Canable::Role) module
|
25
|
-
# This is nesscary to emulate inhertance of the default response and any other variables in the future
|
26
|
-
def included(base)
|
27
|
-
base._default_response = self._default_response
|
28
|
-
end
|
29
|
-
|
30
|
-
# Called when an Actor decides its role and extends itself (an instance) with a Role implementation
|
31
|
-
# Creates the default instance methods for an Actor and persists the can_action? response default down
|
32
|
-
def extended(base)
|
33
|
-
base.extend(RoleEnabledCanInstanceMethods)
|
34
|
-
this_role = self # can't use self inside the instance eval
|
35
|
-
base.instance_eval { @_canable_role = this_role }
|
36
|
-
end
|
37
|
-
|
38
|
-
# Methods given to an instance of an Actor
|
39
|
-
module RoleEnabledCanInstanceMethods
|
40
|
-
def _canable_default # the role default response
|
41
|
-
@_canable_role._default_response
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# ----------------------
|
46
|
-
# Role building DSL
|
47
|
-
# ----------------------
|
48
|
-
def default_response(val)
|
49
|
-
self._default_response = val
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
module Actor
|
55
|
-
include Cans # each role has a distinct set of responses to all the can_action? methods
|
56
|
-
attr_accessor :canable_included_role
|
57
|
-
|
58
|
-
def self.included(base)
|
59
|
-
base.extend(ClassMethods)
|
60
|
-
end
|
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
|
65
|
-
self.__initialize_canable_role
|
66
|
-
@canable_included_role
|
67
|
-
end
|
68
|
-
|
69
|
-
# Called every time a role is needed to make sure the lazy load has been completed
|
70
|
-
def __initialize_canable_role
|
71
|
-
return if @_canable_initialized == true
|
72
|
-
@_canable_intialize == true
|
73
|
-
role_constant = self.__get_role_constant
|
74
|
-
if role_constant == nil
|
75
|
-
default_role = self.class.canable_default_role
|
76
|
-
self.act(default_role) unless default_role == nil
|
77
|
-
else
|
78
|
-
self.act(role_constant)
|
79
|
-
end
|
80
|
-
end
|
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
|
-
|
91
|
-
# Sets the role of this actor by including a role module
|
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
|
97
|
-
self.canable_included_role = role
|
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
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# Holds all the different roles that an actor may assume
|
127
|
-
module Roles
|
128
|
-
# Make one default role that is false for everything
|
129
|
-
module Role
|
130
|
-
include Canable::Role
|
131
|
-
default_response false
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
# Module that holds all the enforce_[action]_permission methods for use in controllers.
|
136
|
-
module Enforcers
|
137
|
-
def self.included(controller)
|
138
|
-
controller.class_eval do
|
139
|
-
Canable.actions.each do |can, able|
|
140
|
-
delegate "can_#{can}?", :to => :current_user
|
141
|
-
helper_method "can_#{can}?" if controller.respond_to?(:helper_method)
|
142
|
-
hide_action "can_#{can}?" if controller.respond_to?(:hide_action)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# Exception that gets raised when permissions are broken for whatever reason.
|
149
|
-
class Transgression < StandardError; end
|
1
|
+
require 'active_support'
|
2
|
+
require 'canable/role'
|
3
|
+
require 'canable/canable'
|
4
|
+
require 'canable/cans'
|
5
|
+
require 'canable/actor'
|
6
|
+
require 'canable/enforcers'
|
150
7
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
# Returns hash of actions that have been added.
|
155
|
-
# {:view => :viewable, ...}
|
156
|
-
def self.actions
|
157
|
-
@actions
|
158
|
-
end
|
159
|
-
|
160
|
-
# Adds an action to actions and the correct methods to can and able modules.
|
161
|
-
#
|
162
|
-
# @param [Symbol] can_method The name of the can_[action]? method.
|
163
|
-
# @param [Symbol] resource_method The name of the [resource_method]_by? method.
|
164
|
-
def self.add(can, able)
|
165
|
-
@actions[can] = able
|
166
|
-
add_can_method(can)
|
167
|
-
add_able_method(can, able)
|
168
|
-
add_enforcer_method(can)
|
169
|
-
end
|
170
|
-
|
171
|
-
private
|
172
|
-
def self.add_can_method(can)
|
173
|
-
Cans.module_eval <<-EOM
|
174
|
-
def can_#{can}?(resource)
|
175
|
-
self.__initialize_canable_role if self.class.include?(Canable::Actor)
|
176
|
-
method = ("can_#{can}_"+resource.class.name.gsub(/::/,"_").downcase+"?").intern
|
177
|
-
if self.respond_to?(method, true)
|
178
|
-
self.send method, resource
|
179
|
-
elsif self.respond_to?(:_canable_default)
|
180
|
-
self._canable_default
|
181
|
-
else
|
182
|
-
false
|
183
|
-
end
|
184
|
-
end
|
185
|
-
EOM
|
186
|
-
end
|
187
|
-
|
188
|
-
def self.add_able_method(can, able)
|
189
|
-
Ables.module_eval <<-EOM
|
190
|
-
def #{able}_by?(actor)
|
191
|
-
return false if actor.blank?
|
192
|
-
actor.can_#{can}?(self)
|
193
|
-
end
|
194
|
-
EOM
|
195
|
-
end
|
196
|
-
|
197
|
-
def self.add_enforcer_method(can)
|
198
|
-
Enforcers.module_eval <<-EOM
|
199
|
-
def enforce_#{can}_permission(resource)
|
200
|
-
raise Canable::Transgression unless can_#{can}?(resource)
|
201
|
-
end
|
202
|
-
private :enforce_#{can}_permission
|
203
|
-
EOM
|
204
|
-
end
|
8
|
+
module Canable
|
9
|
+
Version = '0.2.2'
|
205
10
|
end
|
206
11
|
|
207
12
|
Canable.add(:view, :viewable)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Canable
|
2
|
+
module Actor
|
3
|
+
attr_accessor :canable_included_role
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.instance_eval do
|
7
|
+
include Canable::Cans
|
8
|
+
end
|
9
|
+
class << base
|
10
|
+
include ClassMethods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Override attr_accessor to make sure the role has been included so that we can return an accurate value
|
15
|
+
# "lazy" role including
|
16
|
+
def canable_included_role
|
17
|
+
self.__initialize_canable_role
|
18
|
+
@canable_included_role
|
19
|
+
end
|
20
|
+
|
21
|
+
# Called every time a role is needed to make sure the lazy load has been completed
|
22
|
+
def __initialize_canable_role
|
23
|
+
return if @_canable_initialized == true
|
24
|
+
@_canable_intialize == true
|
25
|
+
role_constant = self.__get_role_constant
|
26
|
+
if role_constant == nil
|
27
|
+
default_role = self.class.canable_default_role
|
28
|
+
self.act(default_role) unless default_role == nil
|
29
|
+
else
|
30
|
+
self.act(role_constant)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def __get_role_constant
|
35
|
+
if self.class.canable_role_proc.respond_to?(:call)
|
36
|
+
attribute = self.class.canable_role_proc.call(self)
|
37
|
+
elsif self.instance_variable_get(:@role)
|
38
|
+
attribute = @role
|
39
|
+
end
|
40
|
+
attribute || nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Sets the role of this actor by including a role module
|
44
|
+
def act(role)
|
45
|
+
unless(role.respond_to?(:included))
|
46
|
+
role = Canable::Roles.const_get((role.to_s.capitalize+"Role").intern)
|
47
|
+
end
|
48
|
+
self.extend role
|
49
|
+
self.canable_included_role = role
|
50
|
+
end
|
51
|
+
|
52
|
+
# ---------------
|
53
|
+
# RBAC Actor building DSL
|
54
|
+
# ---------------
|
55
|
+
|
56
|
+
module ClassMethods
|
57
|
+
attr_accessor :canable_default_role
|
58
|
+
attr_accessor :canable_role_proc
|
59
|
+
|
60
|
+
def default_role(role)
|
61
|
+
self.canable_default_role = role
|
62
|
+
end
|
63
|
+
|
64
|
+
def role_attribute(attribute)
|
65
|
+
self.canable_role_proc = Proc.new {|actor|
|
66
|
+
role = actor.instance_variable_get(attribute)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def role_proc(proc)
|
71
|
+
self.canable_role_proc = proc
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Canable
|
2
|
+
|
3
|
+
# Module that holds all the can_action? methods.
|
4
|
+
module Cans; end
|
5
|
+
|
6
|
+
# Module that holds all the [method]able_by? methods.
|
7
|
+
module Ables; end
|
8
|
+
|
9
|
+
# Holds all the different roles that an actor may assume
|
10
|
+
module Roles
|
11
|
+
# Make one default role that is false for everything
|
12
|
+
module Role
|
13
|
+
include Canable::Role
|
14
|
+
default_response false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Exception that gets raised when permissions are broken for whatever reason.
|
19
|
+
class Transgression < StandardError; end
|
20
|
+
|
21
|
+
# Default actions to an empty hash.
|
22
|
+
@actions = {}
|
23
|
+
|
24
|
+
# Returns hash of actions that have been added.
|
25
|
+
# {:view => :viewable, ...}
|
26
|
+
def self.actions
|
27
|
+
@actions
|
28
|
+
end
|
29
|
+
|
30
|
+
# Adds an action to actions and the correct methods to can and able modules.
|
31
|
+
#
|
32
|
+
# @param [Symbol] can_method The name of the can_[action]? method.
|
33
|
+
# @param [Symbol] resource_method The name of the [resource_method]_by? method.
|
34
|
+
def self.add(can, able)
|
35
|
+
@actions[can] = able
|
36
|
+
add_can_method(can)
|
37
|
+
add_able_method(can, able)
|
38
|
+
add_enforcer_method(can)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.run_callbacks(callback, options)
|
42
|
+
@callbacks.run_callbacks(callback, options) { |result, object| result == false }
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def self.add_can_method(can)
|
47
|
+
Cans.module_eval <<-EOM
|
48
|
+
def can_#{can}?(resource)
|
49
|
+
self.__initialize_canable_role if self.class.include?(Canable::Actor)
|
50
|
+
self.run_callback(:before_query, {:can => self, :able => resource, :permission => :#{can}})
|
51
|
+
method = ("can_#{can}_"+resource.class.name.gsub(/::/,"_").downcase+"?").intern
|
52
|
+
if self.respond_to?(method, true)
|
53
|
+
result = self.send method, resource
|
54
|
+
elsif self.respond_to?(:_canable_default)
|
55
|
+
result = self._canable_default
|
56
|
+
else
|
57
|
+
result = false
|
58
|
+
end
|
59
|
+
self.run_callback(:after_query, {:can => self, :able => resource, :permission => :#{can}, :result => result})
|
60
|
+
result
|
61
|
+
end
|
62
|
+
EOM
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.add_able_method(can, able)
|
66
|
+
Ables.module_eval <<-EOM
|
67
|
+
def #{able}_by?(actor)
|
68
|
+
return false if actor.blank?
|
69
|
+
actor.can_#{can}?(self)
|
70
|
+
end
|
71
|
+
EOM
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.add_enforcer_method(can)
|
75
|
+
Enforcers.module_eval <<-EOM
|
76
|
+
def enforce_#{can}_permission(resource)
|
77
|
+
raise Canable::Transgression unless can_#{can}?(resource)
|
78
|
+
end
|
79
|
+
private :enforce_#{can}_permission
|
80
|
+
EOM
|
81
|
+
end
|
82
|
+
end
|
data/lib/canable/cans.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Canable
|
2
|
+
module Cans
|
3
|
+
def self.included(base)
|
4
|
+
class << base
|
5
|
+
include ClassMethods
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def run_callback(name, options)
|
10
|
+
cs = self.class.canable_callbacks
|
11
|
+
self.send(cs[name], options) if cs[name]
|
12
|
+
end
|
13
|
+
|
14
|
+
# ---------------
|
15
|
+
# RBAC Can/Actor building DSL
|
16
|
+
# ---------------
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
attr_accessor :canable_callbacks
|
20
|
+
|
21
|
+
def canable_callbacks
|
22
|
+
@canable_callbacks ||= {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_permissions_query(symbol)
|
26
|
+
c = self.canable_callbacks
|
27
|
+
c[:after_query] = symbol
|
28
|
+
self.canable_callbacks = c
|
29
|
+
end
|
30
|
+
|
31
|
+
def before_permissions_query(symbol)
|
32
|
+
c = self.canable_callbacks
|
33
|
+
c[:before_query] = symbol
|
34
|
+
self.canable_callbacks = c
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Canable
|
2
|
+
# Module that holds all the enforce_[action]_permission methods for use in controllers.
|
3
|
+
module Enforcers
|
4
|
+
def self.included(controller)
|
5
|
+
controller.class_eval do
|
6
|
+
Canable.actions.each do |can, able|
|
7
|
+
delegate "can_#{can}?", :to => :current_user
|
8
|
+
helper_method "can_#{can}?" if controller.respond_to?(:helper_method)
|
9
|
+
hide_action "can_#{can}?" if controller.respond_to?(:hide_action)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/canable/role.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Canable
|
2
|
+
# Module that is included by a role implementation
|
3
|
+
module Role
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
# These are applied to the actual Role module 'instance' that includes this (Canable::Role) module
|
10
|
+
module ClassMethods
|
11
|
+
# Each role has a default query response, found in this variable
|
12
|
+
attr_accessor :_default_response
|
13
|
+
|
14
|
+
|
15
|
+
# Called when another Role imeplementation module tries to inherit an existing Role implementation
|
16
|
+
# Notice this method isn't self.included, this method becomes self.included on the module including this (Canable::Role) module
|
17
|
+
# This is nesscary to emulate inhertance of the default response and any other variables in the future
|
18
|
+
def included(base)
|
19
|
+
base._default_response = self._default_response
|
20
|
+
end
|
21
|
+
|
22
|
+
# Called when an Actor decides its role and extends itself (an instance) with a Role implementation
|
23
|
+
# Creates the default instance methods for an Actor and persists the can_action? response default down
|
24
|
+
def extended(base)
|
25
|
+
base.extend(RoleEnabledCanInstanceMethods)
|
26
|
+
this_role = self # can't use self inside the instance eval
|
27
|
+
base.instance_eval { @_canable_role = this_role }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Methods given to an instance of an Actor
|
31
|
+
module RoleEnabledCanInstanceMethods
|
32
|
+
def _canable_default # the role default response
|
33
|
+
@_canable_role._default_response
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# ----------------------
|
38
|
+
# Role building DSL
|
39
|
+
# ----------------------
|
40
|
+
def default_response(val)
|
41
|
+
self._default_response = val
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/rbacanable.gemspec
ADDED
@@ -0,0 +1,83 @@
|
|
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{rbacanable}
|
8
|
+
s.version = "0.2.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["John Nunemaker", "Harry Brundage"]
|
12
|
+
s.date = %q{2010-04-07}
|
13
|
+
s.description = %q{Simple role based permissions system}
|
14
|
+
s.email = %q{harry.brundage@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"Changes.rdoc",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"examples/basic.rb",
|
27
|
+
"examples/callbacks.rb",
|
28
|
+
"examples/roles.rb",
|
29
|
+
"lib/canable.rb",
|
30
|
+
"lib/canable/actor.rb",
|
31
|
+
"lib/canable/canable.rb",
|
32
|
+
"lib/canable/cans.rb",
|
33
|
+
"lib/canable/enforcers.rb",
|
34
|
+
"lib/canable/role.rb",
|
35
|
+
"rbacanable.gemspec",
|
36
|
+
"specs.watchr",
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_ables.rb",
|
39
|
+
"test/test_canable.rb",
|
40
|
+
"test/test_cans.rb",
|
41
|
+
"test/test_enforcers.rb",
|
42
|
+
"test/test_roles.rb"
|
43
|
+
]
|
44
|
+
s.homepage = %q{http://github.com/hornairs/rbacanable}
|
45
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
46
|
+
s.require_paths = ["lib"]
|
47
|
+
s.rubygems_version = %q{1.3.6}
|
48
|
+
s.summary = %q{Simple role based permissions system}
|
49
|
+
s.test_files = [
|
50
|
+
"test/helper.rb",
|
51
|
+
"test/test_ables.rb",
|
52
|
+
"test/test_canable.rb",
|
53
|
+
"test/test_cans.rb",
|
54
|
+
"test/test_enforcers.rb",
|
55
|
+
"test/test_roles.rb",
|
56
|
+
"examples/basic.rb",
|
57
|
+
"examples/callbacks.rb",
|
58
|
+
"examples/roles.rb"
|
59
|
+
]
|
60
|
+
|
61
|
+
if s.respond_to? :specification_version then
|
62
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
63
|
+
s.specification_version = 3
|
64
|
+
|
65
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
66
|
+
s.add_development_dependency(%q<shoulda>, ["= 2.10.3"])
|
67
|
+
s.add_development_dependency(%q<mocha>, ["= 0.9.8"])
|
68
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<activesupport>, [">= 0"])
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
72
|
+
s.add_dependency(%q<mocha>, ["= 0.9.8"])
|
73
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
74
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
75
|
+
end
|
76
|
+
else
|
77
|
+
s.add_dependency(%q<shoulda>, ["= 2.10.3"])
|
78
|
+
s.add_dependency(%q<mocha>, ["= 0.9.8"])
|
79
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
80
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
data/test/helper.rb
CHANGED
@@ -14,6 +14,19 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
14
14
|
require 'canable'
|
15
15
|
|
16
16
|
class Test::Unit::TestCase
|
17
|
+
|
18
|
+
def self.should_set_callback_attributes(test_value)
|
19
|
+
should "be called" do
|
20
|
+
assert ! subject.blank?
|
21
|
+
end
|
22
|
+
should "return proper options" do
|
23
|
+
assert_equal @user, subject[:can]
|
24
|
+
assert_equal @resource, subject[:able]
|
25
|
+
assert_equal :update, subject[:permission]
|
26
|
+
assert_equal test_value, subject[:test]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
17
30
|
end
|
18
31
|
|
19
32
|
def Doc(name=nil, &block)
|
data/test/test_ables.rb
CHANGED
@@ -27,57 +27,101 @@ class AblesTest < Test::Unit::TestCase
|
|
27
27
|
assert ! @resource.viewable_by?('')
|
28
28
|
end
|
29
29
|
end
|
30
|
+
|
31
|
+
context "creatable_by?" do
|
32
|
+
should "be false if user cannot create" do
|
33
|
+
user = mock('user', :can_create? => false)
|
34
|
+
assert ! @resource.creatable_by?(user)
|
35
|
+
end
|
36
|
+
|
37
|
+
should "be true if user can create" do
|
38
|
+
user = mock('user', :can_create? => true)
|
39
|
+
assert @resource.creatable_by?(user)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "be false if resource is blank" do
|
43
|
+
assert ! @resource.creatable_by?(nil)
|
44
|
+
assert ! @resource.creatable_by?('')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "updatable_by?" do
|
49
|
+
should "be false if user cannot update" do
|
50
|
+
user = mock('user', :can_update? => false)
|
51
|
+
assert ! @resource.updatable_by?(user)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "be true if user can update" do
|
55
|
+
user = mock('user', :can_update? => true)
|
56
|
+
assert @resource.updatable_by?(user)
|
57
|
+
end
|
58
|
+
|
59
|
+
should "be false if resource is blank" do
|
60
|
+
assert ! @resource.updatable_by?(nil)
|
61
|
+
assert ! @resource.updatable_by?('')
|
62
|
+
end
|
63
|
+
end
|
30
64
|
|
31
|
-
context "
|
32
|
-
should "be false if user cannot
|
33
|
-
user = mock('user', :
|
34
|
-
assert ! @resource.
|
65
|
+
context "destroyable_by?" do
|
66
|
+
should "be false if user cannot destroy" do
|
67
|
+
user = mock('user', :can_destroy? => false)
|
68
|
+
assert ! @resource.destroyable_by?(user)
|
35
69
|
end
|
36
70
|
|
37
|
-
should "be true if user can
|
38
|
-
user = mock('user', :
|
39
|
-
assert @resource.
|
71
|
+
should "be true if user can destroy" do
|
72
|
+
user = mock('user', :can_destroy? => true)
|
73
|
+
assert @resource.destroyable_by?(user)
|
40
74
|
end
|
41
75
|
|
42
76
|
should "be false if resource is blank" do
|
43
|
-
assert ! @resource.
|
44
|
-
assert ! @resource.
|
77
|
+
assert ! @resource.destroyable_by?(nil)
|
78
|
+
assert ! @resource.destroyable_by?('')
|
45
79
|
end
|
46
80
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
assert ! @resource.updatable_by?(user)
|
52
|
-
end
|
81
|
+
end
|
82
|
+
context "Canable Ables with callbacks defined" do
|
83
|
+
setup do
|
84
|
+
@resource = mock('resource')
|
53
85
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
86
|
+
userklass = Class.new do
|
87
|
+
attr_accessor :before_options
|
88
|
+
attr_accessor :after_options
|
89
|
+
include Canable::Actor
|
90
|
+
before_permissions_query :before
|
91
|
+
after_permissions_query :after
|
58
92
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "destroyable_by?" do
|
66
|
-
should "be false if user cannot destroy" do
|
67
|
-
user = mock('user', :can_destroy? => false)
|
68
|
-
assert ! @resource.destroyable_by?(user)
|
93
|
+
def before(options = {})
|
94
|
+
options[:test] = 2+2
|
95
|
+
@before_options = options
|
69
96
|
end
|
70
97
|
|
71
|
-
|
72
|
-
|
73
|
-
|
98
|
+
def after(options = {})
|
99
|
+
options[:test] = 2-3
|
100
|
+
@after_options = options
|
74
101
|
end
|
102
|
+
end
|
75
103
|
|
76
|
-
|
77
|
-
|
78
|
-
|
104
|
+
@user = userklass.new
|
105
|
+
end
|
106
|
+
|
107
|
+
context "and a permission query is preformed, " do
|
108
|
+
setup do
|
109
|
+
@result = @user.can_update?(@resource)
|
110
|
+
end
|
111
|
+
|
112
|
+
context "before callbacks" do
|
113
|
+
subject {@user.before_options}
|
114
|
+
should_set_callback_attributes(4)
|
115
|
+
end
|
116
|
+
|
117
|
+
context "after callbacks" do
|
118
|
+
subject{@user.after_options}
|
119
|
+
should_set_callback_attributes(-1)
|
120
|
+
|
121
|
+
should "have the result in an option" do
|
122
|
+
assert_equal @user.after_options[:result], false
|
79
123
|
end
|
80
124
|
end
|
81
|
-
|
82
|
-
|
125
|
+
end
|
126
|
+
end
|
83
127
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 2
|
9
|
+
version: 0.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- John Nunemaker
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-04-
|
18
|
+
date: 2010-04-07 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -58,6 +58,18 @@ dependencies:
|
|
58
58
|
version: "0"
|
59
59
|
type: :development
|
60
60
|
version_requirements: *id003
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: activesupport
|
63
|
+
prerelease: false
|
64
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
version: "0"
|
71
|
+
type: :development
|
72
|
+
version_requirements: *id004
|
61
73
|
description: Simple role based permissions system
|
62
74
|
email: harry.brundage@gmail.com
|
63
75
|
executables: []
|
@@ -75,8 +87,15 @@ files:
|
|
75
87
|
- README.rdoc
|
76
88
|
- Rakefile
|
77
89
|
- examples/basic.rb
|
90
|
+
- examples/callbacks.rb
|
78
91
|
- examples/roles.rb
|
79
92
|
- lib/canable.rb
|
93
|
+
- lib/canable/actor.rb
|
94
|
+
- lib/canable/canable.rb
|
95
|
+
- lib/canable/cans.rb
|
96
|
+
- lib/canable/enforcers.rb
|
97
|
+
- lib/canable/role.rb
|
98
|
+
- rbacanable.gemspec
|
80
99
|
- specs.watchr
|
81
100
|
- test/helper.rb
|
82
101
|
- test/test_ables.rb
|
@@ -122,4 +141,5 @@ test_files:
|
|
122
141
|
- test/test_enforcers.rb
|
123
142
|
- test/test_roles.rb
|
124
143
|
- examples/basic.rb
|
144
|
+
- examples/callbacks.rb
|
125
145
|
- examples/roles.rb
|