Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: efc6936cd2
Fetching contributors…

Cannot retrieve contributors at this time

222 lines (198 sloc) 6.425 kB
module Ixtlan
module Guard
module ActionController
def self.included(base)
base.send(:include, InstanceMethods)
base.send(:include, GroupsMethod)
end
class Filter
attr_reader :block
def initialize(method, options, &block)
@only = options[:only]
@except = options[:except] || []
@reference = options[:reference]
@reference = @reference.to_sym if @reference
@block = block
@method = method.to_sym if method
raise "illegal arguments: either block or method name #{method}" if block && method
end
def proc(base, reference = nil)
if @block
if reference
Proc.new do |groups|
@block.call(groups, reference)
end
elsif @reference
Proc.new do |groups|
@block.call(groups, base.send(@reference))
end
else
@block
end
else
if base.respond_to?(@method) || base.private_methods.include?(@method.to_s)
if reference
Proc.new do |groups|
base.send(@method, groups, reference)
end
elsif @reference
Proc.new do |groups|
base.send(@method, groups, base.send(@reference))
end
else
base.method(@method)
end
else
if @reference
Proc.new do |groups|
base.class.send(@method, groups, base.send(@reference))
end
else
base.class.method(@method)
end
end
end
end
def allowed?(action)
action = action.to_sym
(@only && @only.member?(action)) ||
((@only.nil? || @only.empty?) && ! @except.member?(action))
end
end
module GroupsMethod
protected
def current_groups
@current_groups ||=
if respond_to?(:current_user) && current_user
current_user.groups
else
[]
end
end
end
module RootGroup
protected
def current_groups
['root']
end
end
module InstanceMethods #:nodoc:
def self.included(base)
base.class_eval do
def self.guard_filter(*args, &block)
method = nil#"_intern_#{guard_filters.size}"
options = {}
case args.size
when 1
if args[0].is_a? Symbol
method = args[0]
else
options = args[0]
end
when 2
method = args[0].to_sym
options = args[1]
else
raise "argument error, expected (Symbol, Hash) or (Symbol) or (Hash)"
end
guard_filters << Filter.new(method, options, &block)
end
def self.guard_filters
@_guard_filters ||= []
end
def self.guard
Rails.application.config.guard
end
def self.allowed?(action, current_groups, reference = nil)
filter = guard_filters.detect do |f|
f.allowed?(action)
end
if filter
guard.check(self.controller_name,
action,
current_groups || []) do |groups|
filter.proc(self, reference).call(groups)
end
else
# TODO maybe do something with the reference
guard.check(controller_name,
action,
current_groups || [])
end
end
end
end
protected
def guard
self.class.guard
end
def allowed?(action_or_actions,
controller = params[:controller],
reference = nil,
&block)
case action_or_actions
when Array
action_or_actions.detect do |action|
check(action, controller, reference, &block) != nil
end
else
check(action_or_actions, controller, reference, &block) != nil
end
end
def check(action = params[:action],
controller = params[:controller],
reference = nil,
&block)
unless block
filter = self.class.guard_filters.detect do |f|
f.allowed?(action)
end
end
if filter
guard.check(controller,
action,
current_groups || []) do |groups|
filter.proc(self).call(groups)
end
else
# TODO maybe do something with the reference
guard.check(controller,
action,
current_groups || [],
&block)
end
end
def authorize
unless check
raise ::Ixtlan::Guard::PermissionDenied.new("permission denied for '#{params[:controller]}##{params[:action]}'")
end
true
end
end
end
module Allowed
# Inclusion hook to make #allowed available as method
def self.included(base)
base.send(:include, InstanceMethods)
end
module InstanceMethods #:nodoc:
def allowed?(resource, action, reference = nil)
if resource.to_s != controller.class.controller_name || reference
other = "#{resource}Controller".classify.constantize
if other.respond_to?(:allowed?)
if reference
other.send(:allowed?, action, controller.current_groups, reference)
else
other.send(:allowed?, action, controller.current_groups)
end
else
raise "can not find 'allowed?' on #{other}"
end
else
controller.send(:allowed?, action, resource)
end
end
end
end
end
end
Jump to Line
Something went wrong with that request. Please try again.