ixtlan-guard 0.1.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|