ixtlan-guard 0.1.0 → 0.4.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/MIT-LICENSE +20 -0
- data/lib/generators/active_record/templates/flavor_migration.rb +13 -0
- data/lib/generators/active_record/templates/flavor_model.rb +8 -0
- data/lib/generators/active_record/templates/group_model.rb +43 -0
- data/lib/generators/active_record/templates/group_user_migration.rb +13 -0
- data/lib/generators/active_record/templates/user_model.rb +124 -0
- data/lib/generators/active_record/user_management_models_generator.rb +202 -0
- data/lib/generators/erb/user_management_controller_generator.rb +10 -0
- data/lib/generators/{ixtlan → guard}/controller/USAGE +0 -0
- data/lib/generators/{ixtlan → guard}/controller/controller_generator.rb +2 -2
- data/lib/generators/{ixtlan → guard}/scaffold/USAGE +0 -0
- data/lib/generators/{ixtlan → guard}/scaffold/scaffold_generator.rb +4 -6
- data/lib/generators/guard/scaffold/templates/guard.rb +20 -0
- data/lib/generators/guard/templates/guard.rb +20 -0
- data/lib/generators/ixtlan/maintenance_scaffold/USAGE +8 -0
- data/lib/generators/ixtlan/maintenance_scaffold/maintenance_scaffold_generator.rb +40 -0
- data/lib/generators/ixtlan/permissions_scaffold/USAGE +8 -0
- data/lib/generators/ixtlan/permissions_scaffold/permissions_scaffold_generator.rb +33 -0
- data/lib/generators/ixtlan/user_management_controller/USAGE +8 -0
- data/lib/generators/ixtlan/user_management_controller/user_management_controller_generator.rb +23 -0
- data/lib/generators/ixtlan/user_management_models/USAGE +8 -0
- data/lib/generators/ixtlan/user_management_models/user_management_models_generator.rb +19 -0
- data/lib/generators/ixtlan/user_management_scaffold/user_management_scaffold_generator.rb +13 -0
- data/lib/ixtlan-guard.rb +2 -2
- data/lib/ixtlan/guard.rb +1 -159
- data/lib/ixtlan/guard/controllers/maintenance_controller.rb +45 -0
- data/lib/ixtlan/guard/controllers/permissions_controller.rb +41 -0
- data/lib/ixtlan/guard/guard.rb +245 -0
- data/lib/ixtlan/guard/models/maintenance.rb +55 -0
- data/lib/ixtlan/guard/models/user_update_manager.rb +95 -0
- data/lib/ixtlan/guard/rails_integration.rb +88 -0
- data/lib/ixtlan/guard/railtie.rb +33 -0
- data/lib/ixtlan/guard/spec/user_management_models_spec.rb +193 -0
- data/spec/guard_spec.rb +48 -12
- data/spec/railtie_spec.rb +1 -1
- metadata +75 -52
- data/lib/generators/ixtlan/templates/edit.html.erb +0 -10
- data/lib/generators/ixtlan/templates/guard.rb +0 -13
- data/lib/generators/ixtlan/templates/index.html.erb +0 -35
- data/lib/generators/ixtlan/templates/new.html.erb +0 -7
- data/lib/generators/ixtlan/templates/show.html.erb +0 -16
- data/lib/generators/scaffold/scaffold/scaffold_generator.rb +0 -23
- data/lib/ixtlan/guard_railtie.rb +0 -43
- data/lib/ixtlan/rails_integration.rb +0 -55
@@ -0,0 +1,41 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Guard
|
3
|
+
module Controllers
|
4
|
+
module PermissionsController
|
5
|
+
|
6
|
+
# GET /permissions
|
7
|
+
# GET /permissions.xml
|
8
|
+
# GET /permissions.json
|
9
|
+
def index
|
10
|
+
respond_to do |format|
|
11
|
+
format.html
|
12
|
+
format.xml { render :xml => guard.permissions(self).to_xml }
|
13
|
+
format.json { render :json => guard.permissions(self).to_json }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# GET /permissions/1
|
18
|
+
# GET /permissions/1.xml
|
19
|
+
# GET /permissions/1.json
|
20
|
+
def show
|
21
|
+
controller = Object.new
|
22
|
+
def controller.current_user(u = nil)
|
23
|
+
@u = u if u
|
24
|
+
@u
|
25
|
+
end
|
26
|
+
if defined? ::DataMapper
|
27
|
+
controller.current_user(current_user.class.get(params[:id]))
|
28
|
+
else
|
29
|
+
controller.current_user(current_user.class.find(params[:id]))
|
30
|
+
end
|
31
|
+
|
32
|
+
respond_to do |format|
|
33
|
+
format.html
|
34
|
+
format.xml { render :xml => guard.permissions(controller).to_xml }
|
35
|
+
format.json { render :json => guard.permissions(controller).to_json }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Guard
|
3
|
+
class ControllerGuard
|
4
|
+
|
5
|
+
attr_accessor :name, :action_map, :aliases, :flavor
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name.sub(/_guard$/, '').to_sym
|
9
|
+
class_name = name.split(/\//).collect { |part| part.split("_").each { |pp| pp.capitalize! }.join }.join("::")
|
10
|
+
Object.const_get(class_name).new(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
def flavor=(flavor)
|
14
|
+
@flavor = flavor.to_sym
|
15
|
+
end
|
16
|
+
|
17
|
+
def name=(name)
|
18
|
+
@name = name.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def aliases=(map)
|
22
|
+
@aliases = symbolize(map)
|
23
|
+
end
|
24
|
+
|
25
|
+
def action_map=(map)
|
26
|
+
@action_map = symbolize(map)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def symbolize(h)
|
32
|
+
result = {}
|
33
|
+
|
34
|
+
h.each do |k, v|
|
35
|
+
if v.is_a?(Hash)
|
36
|
+
result[k.to_sym] = symbolize_keys(v) unless v.size == 0
|
37
|
+
elsif v.is_a?(Array)
|
38
|
+
val = []
|
39
|
+
v.each {|vv| val << vv.to_sym }
|
40
|
+
result[k.to_sym] = val
|
41
|
+
else
|
42
|
+
result[k.to_sym] = v.to_sym
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
class Guard
|
52
|
+
|
53
|
+
attr_accessor :logger, :guard_dir, :superuser, :groups_of_current_user
|
54
|
+
|
55
|
+
def initialize(options, &block)
|
56
|
+
@superuser = (options[:superuser] || :root).to_sym
|
57
|
+
@guard_dir = options[:guard_dir] || File.join("app", "guards")
|
58
|
+
@user_groups = (options[:user_groups] || :groups).to_sym
|
59
|
+
@user_groups_name = (options[:user_groups_name] || :name).to_sym
|
60
|
+
|
61
|
+
@map = {}
|
62
|
+
@aliases = {}
|
63
|
+
@flavor_map = {}
|
64
|
+
|
65
|
+
@groups_of_current_user =
|
66
|
+
if block
|
67
|
+
block
|
68
|
+
else
|
69
|
+
Proc.new do |controller|
|
70
|
+
# get the groups of the current_user
|
71
|
+
user = controller.send(:current_user) if controller.respond_to?(:current_user)
|
72
|
+
if user
|
73
|
+
(user.send(@user_groups) || []).collect do |group|
|
74
|
+
name = group.send(@user_groups_name)
|
75
|
+
name.to_sym if name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def logger
|
83
|
+
@logger ||= if defined?(Slf4r::LoggerFactory)
|
84
|
+
Slf4r::LoggerFactory.new(Ixtlan::Guard)
|
85
|
+
else
|
86
|
+
require 'logger'
|
87
|
+
Logger.new(STDOUT)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def setup
|
92
|
+
if File.exists?(@guard_dir)
|
93
|
+
Dir.new(guard_dir).to_a.each do |f|
|
94
|
+
if f.match(".rb$")
|
95
|
+
require(File.join(guard_dir, f))
|
96
|
+
controller_guard = ControllerGuard.new(f.sub(/.rb$/, ''))
|
97
|
+
register(controller_guard)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
logger.debug("initialized guard . . .")
|
101
|
+
else
|
102
|
+
raise GuardException.new("guard directory #{guard_dir} not found, skip loading")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def register(controller_guard)
|
109
|
+
msg = (controller_guard.aliases || {}).collect {|k,v| "\n\t#{k} == #{v}"} + controller_guard.action_map.collect{ |k,v| "\n\t#{k} => [#{v.join(',')}]"}
|
110
|
+
logger.debug("#{controller_guard.name} guard: #{msg}")
|
111
|
+
@map[controller_guard.name] = controller_guard.action_map
|
112
|
+
@aliases[controller_guard.name] = controller_guard.aliases || {}
|
113
|
+
@flavor_map[controller_guard.name] = controller_guard.flavor if controller_guard.flavor
|
114
|
+
end
|
115
|
+
|
116
|
+
public
|
117
|
+
|
118
|
+
def flavor(controller)
|
119
|
+
@flavor_map[controller.params[:controller].to_sym]
|
120
|
+
end
|
121
|
+
|
122
|
+
def block_groups(groups)
|
123
|
+
@blocked_groups = (groups || []).collect { |g| g.to_sym}
|
124
|
+
@blocked_groups.delete(@superuser)
|
125
|
+
@blocked_groups
|
126
|
+
end
|
127
|
+
|
128
|
+
def blocked_groups
|
129
|
+
@blocked_groups ||= []
|
130
|
+
end
|
131
|
+
|
132
|
+
def current_user_restricted?(controller)
|
133
|
+
groups = @groups_of_current_user.call(controller)
|
134
|
+
if groups
|
135
|
+
# groups.select { |g| !blocked_groups.member?(g.to_sym) }.size < groups.size
|
136
|
+
(groups - blocked_groups).size < groups.size
|
137
|
+
else
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def permissions(controller)
|
143
|
+
groups = (@groups_of_current_user.call(controller) || []).collect do
|
144
|
+
|g| g.to_sym
|
145
|
+
end
|
146
|
+
map = {}
|
147
|
+
@map.each do |resource, action_map|
|
148
|
+
action_map.each do |action, allowed|
|
149
|
+
if allowed.member? :*
|
150
|
+
allowed = groups.dup
|
151
|
+
end
|
152
|
+
allowed << @superuser unless allowed.member? @superuser
|
153
|
+
|
154
|
+
# intersection of allowed and groups empty ?
|
155
|
+
if (allowed - groups).size < allowed.size
|
156
|
+
permission = (map[resource] ||= {})
|
157
|
+
permission[:resource] = resource
|
158
|
+
actions = (permission[:actions] ||= [])
|
159
|
+
action_node = {:name => action}
|
160
|
+
flavors.each do |flavor, block|
|
161
|
+
flavor_list = []
|
162
|
+
(allowed - (allowed - groups)).each do |group|
|
163
|
+
list = block.call(controller, group)
|
164
|
+
# union - no duplicates
|
165
|
+
flavor_list = flavor_list - list + list
|
166
|
+
end
|
167
|
+
action_node[flavor.to_s.sub(/s$/, '') + "s"] = flavor_list if flavor_list.size > 0
|
168
|
+
end
|
169
|
+
actions << action_node
|
170
|
+
actions << @aliases[resource][action] if @aliases[resource][action]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
result = map.values
|
176
|
+
result.class_eval "alias :to_x :to_xml" unless map.respond_to? :to_x
|
177
|
+
def result.to_xml(options = {}, &block)
|
178
|
+
options[:root] = :permissions unless options[:root]
|
179
|
+
to_x(options, &block)
|
180
|
+
end
|
181
|
+
|
182
|
+
def result.to_json(options = {}, &block)
|
183
|
+
{:permissions => self}.to_json(options, &block)
|
184
|
+
end
|
185
|
+
result
|
186
|
+
end
|
187
|
+
|
188
|
+
def flavors
|
189
|
+
@flavors ||= {}
|
190
|
+
end
|
191
|
+
|
192
|
+
def register_flavor(flavor, &block)
|
193
|
+
flavors[flavor.to_sym] = block
|
194
|
+
end
|
195
|
+
|
196
|
+
def check(controller, resource, action, flavor_selector = nil, &block)
|
197
|
+
resource = resource.to_sym
|
198
|
+
action = action.to_sym
|
199
|
+
groups = @groups_of_current_user.call(controller)
|
200
|
+
if groups.nil?
|
201
|
+
logger.debug("check #{resource}##{action}: not authenticated")
|
202
|
+
return false
|
203
|
+
end
|
204
|
+
if (@map.key? resource)
|
205
|
+
action = @aliases[resource][action] || action
|
206
|
+
allowed = @map[resource][action]
|
207
|
+
if (allowed.nil?)
|
208
|
+
logger.warn("unknown action '#{action}' for controller '#{resource}'")
|
209
|
+
raise ::Ixtlan::Guard::GuardException.new("unknown action '#{action}' for controller '#{resource}'")
|
210
|
+
else
|
211
|
+
allowed << @superuser unless allowed.member? @superuser
|
212
|
+
allow_all_groups = allowed.member?(:*)
|
213
|
+
if(allow_all_groups && block.nil?)
|
214
|
+
logger.debug("check #{resource}##{action}: allowed for all")
|
215
|
+
return true
|
216
|
+
else
|
217
|
+
groups.each do |group|
|
218
|
+
if (allow_all_groups || allowed.member?(group.to_sym)) && !blocked_groups.member?(group.to_sym)
|
219
|
+
flavor_for_resource = flavors[@flavor_map[resource]]
|
220
|
+
if block.nil?
|
221
|
+
if(flavor_for_resource && flavor_for_resource.call(controller, group).member?(flavor_selector.to_s) || flavor_for_resource.nil?)
|
222
|
+
logger.debug("check #{resource}##{action}: true")
|
223
|
+
return true
|
224
|
+
end
|
225
|
+
elsif block.call(group)
|
226
|
+
logger.debug("check #{resource}##{action}: true")
|
227
|
+
return true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
logger.debug("check #{resource}##{action}: false")
|
233
|
+
return false
|
234
|
+
end
|
235
|
+
else
|
236
|
+
logger.warn("unknown controller for '#{resource}'")
|
237
|
+
raise ::Ixtlan::Guard::GuardException.new("unknown controller for '#{resource}'")
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
class GuardException < Exception; end
|
243
|
+
class PermissionDenied < GuardException; end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
unless String.respond_to? "plural"
|
2
|
+
class String
|
3
|
+
def plural
|
4
|
+
self + "s"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Ixtlan
|
10
|
+
module SerializableModel
|
11
|
+
def self.included(model)
|
12
|
+
model.send :include, ActiveModel::Serializers::JSON
|
13
|
+
model.send :include, ActiveModel::Serializers::Xml
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes=(attributes)
|
17
|
+
attributes.each do |k, v|
|
18
|
+
if k == k.plural
|
19
|
+
v = case v
|
20
|
+
when String
|
21
|
+
[v]
|
22
|
+
when Array
|
23
|
+
v
|
24
|
+
when Hash
|
25
|
+
v.values.flatten
|
26
|
+
end
|
27
|
+
end
|
28
|
+
send("#{k}=", v)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def attributes
|
33
|
+
map = instance_variables.collect do |name|
|
34
|
+
[name[1,1000], send(name[1,1000].to_sym)]
|
35
|
+
end.reject do |x|
|
36
|
+
x[1] == nil
|
37
|
+
end
|
38
|
+
Hash[map]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module Ixtlan
|
44
|
+
module Guard
|
45
|
+
module Models
|
46
|
+
class Maintenance
|
47
|
+
|
48
|
+
include Ixtlan::SerializableModel
|
49
|
+
|
50
|
+
attr_accessor :groups
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Guard
|
3
|
+
module Models
|
4
|
+
class UserUpdateManager
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@group_model = options[:group_model]
|
8
|
+
@user_id = options[:user_id].to_sym
|
9
|
+
@plural_group_name = options[:plural_group_name].to_sym
|
10
|
+
@group_id = options[:group_id].to_sym
|
11
|
+
@group_ids = "#{options[:group_id]}s"
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_groups(user, params = [])
|
15
|
+
allowed_ids = user.current_user.all_groups.collect { |g| g.id.to_s }
|
16
|
+
|
17
|
+
group_ids = params[@group_ids] || []
|
18
|
+
group_ids = intersect(group_ids, allowed_ids)
|
19
|
+
|
20
|
+
current_ids = user.send(@plural_group_name).collect { |g| g.id.to_s }
|
21
|
+
current_ids = intersect(current_ids, allowed_ids)
|
22
|
+
|
23
|
+
# add
|
24
|
+
(group_ids - current_ids).each do |gid|
|
25
|
+
user.send(@plural_group_name) << @group_model.find(gid)
|
26
|
+
end
|
27
|
+
|
28
|
+
#delete
|
29
|
+
(current_ids - group_ids).each do |gid|
|
30
|
+
user.groups.delete(@group_model.find(gid))
|
31
|
+
end
|
32
|
+
|
33
|
+
user.save
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(user, params = {}, options = {})
|
37
|
+
raise "no user" unless user
|
38
|
+
user.current_user = params.delete("current_user") || params.delete(:current_user) unless user.current_user
|
39
|
+
raise "'current_user' not set" unless user.current_user
|
40
|
+
|
41
|
+
flavor_id = options[:flavor_id].to_sym
|
42
|
+
flavor_ids = "#{options[:flavor_id]}s"
|
43
|
+
association_model = options[:association_model]
|
44
|
+
retrieve_flavors_method = options[:flavors_for_group].to_sym
|
45
|
+
|
46
|
+
allowed_ids = user.current_user.send(retrieve_flavors_method, @group_model.admin_group).collect {|i| i.id }
|
47
|
+
allowed_group_ids = user.current_user.all_groups.collect { |g| g.id.to_s }
|
48
|
+
|
49
|
+
group_ids = params[@group_ids] || []
|
50
|
+
group_ids = intersect(group_ids, allowed_group_ids)
|
51
|
+
group_ids.each do |gid|
|
52
|
+
g = @group_model.find(gid)
|
53
|
+
|
54
|
+
# calculate intersection of current and allowed
|
55
|
+
current_ids = user.send(retrieve_flavors_method, gid.to_i).collect { |d| d.id }
|
56
|
+
current_ids = intersect(current_ids, allowed_ids)
|
57
|
+
|
58
|
+
# calculate intersection of target and allowed
|
59
|
+
target_ids = ((params.delete(g.to_name) || {})[flavor_ids] || []).collect { |i| i.to_i }
|
60
|
+
target_ids = intersect(target_ids, allowed_ids)
|
61
|
+
|
62
|
+
# delete
|
63
|
+
(current_ids - target_ids).each do |id|
|
64
|
+
return false unless association_model.delete_all(["user_id=? and group_id=? and #{flavor_id}=?", user.id, gid, id])
|
65
|
+
end
|
66
|
+
|
67
|
+
# add
|
68
|
+
(target_ids - current_ids).each do |id|
|
69
|
+
return false unless association_model.create(@user_id => user.id, @group_id => gid, flavor_id => id)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def managed_flavors_for_group(user, group_or_id, options)
|
76
|
+
retrieve_flavors_method = options[:flavors_for_group].to_sym
|
77
|
+
group = @group_model.get(group_or_id)
|
78
|
+
if group.root?
|
79
|
+
[]
|
80
|
+
else
|
81
|
+
existing = user.send(retrieve_flavors_method, group)
|
82
|
+
managed = user.send(retrieve_flavors_method, @group_model.admin_group)
|
83
|
+
intersect(managed, existing)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def intersect(set1, set2)
|
90
|
+
set1 - (set1 - set2)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'ixtlan/guard'
|
2
|
+
module Ixtlan
|
3
|
+
module ActionController #:nodoc:
|
4
|
+
module Guard #:nodoc:
|
5
|
+
def self.included(base)
|
6
|
+
base.send(:include, InstanceMethods)
|
7
|
+
end
|
8
|
+
module InstanceMethods #:nodoc:
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
def guard
|
13
|
+
Rails.application.config.guard
|
14
|
+
end
|
15
|
+
|
16
|
+
def authorization(flavor = nil, &block)
|
17
|
+
if flavor.nil?
|
18
|
+
flavor = guard.flavor(self)
|
19
|
+
if flavor
|
20
|
+
method = "#{flavor}_authorization".to_sym
|
21
|
+
if self.respond_to?(method)
|
22
|
+
return send "#{flavor}_authorization".to_sym, &block
|
23
|
+
else
|
24
|
+
logger.warn "flavor #{flavor} configured in guard, but there is not method '#{method}'"
|
25
|
+
flavor = nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
resource_authorization(params[:controller], params[:action], flavor, &block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def resource_authorization(resource, action, flavor = nil, &block)
|
33
|
+
unless guard.check(self,
|
34
|
+
resource,
|
35
|
+
action,
|
36
|
+
&flavored_block(flavor, &block))
|
37
|
+
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{resource}##{action}'")
|
38
|
+
end
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def flavored_block(flavor = nil, &block)
|
43
|
+
if block
|
44
|
+
if flavor
|
45
|
+
Proc.new do |group|
|
46
|
+
allowed_flavors = guard.flavors[flavor.to_sym].call(self, group)
|
47
|
+
block.call(allowed_flavors)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
block
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
private :flavored_block
|
56
|
+
|
57
|
+
def allowed?(action, flavor = nil, &block)
|
58
|
+
guard.check(self,
|
59
|
+
params[:controller],
|
60
|
+
action,
|
61
|
+
&flavored_block(flavor, &block))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module Allowed #:nodoc:
|
68
|
+
# Inclusion hook to make #allowed available as method
|
69
|
+
def self.included(base)
|
70
|
+
base.send(:include, InstanceMethods)
|
71
|
+
end
|
72
|
+
|
73
|
+
module InstanceMethods #:nodoc:
|
74
|
+
def allowed?(resource, action, flavor_selector = nil, &block)
|
75
|
+
controller.send(:guard).check(controller, resource, action, flavor_selector, &block)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
ActionController::Base.send(:include, Ixtlan::ActionController::Guard)
|
82
|
+
ActionController::Base.send(:before_filter, :authorization)
|
83
|
+
ActionView::Base.send(:include, Ixtlan::Allowed)
|
84
|
+
module Erector
|
85
|
+
class Widget
|
86
|
+
include Ixtlan::Allowed
|
87
|
+
end
|
88
|
+
end
|