rbacanable 0.2.1 → 0.2.2
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/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
|