class RequirementAuthorization::Requirement

Constants

CONTROLLER_OPTIONS

Public Class Methods

new(opts={}) { |self| ... } click to toggle source
# File lib/requirement_authorization.rb, line 13
def initialize(opts={},&block)
  yield self if block_given?
end

Public Instance Methods

filter(controller, *args) click to toggle source

Sets up the filter for the controller by wrapping this requirement up in a proc.

# File lib/requirement_authorization.rb, line 35
def filter(controller, *args)
  args, controller_options = extract_filter_args!(args)
  # Capture the Method object here in case the scope of the block changes
  resolve_method = method(:resolve)
  controller.before_filter(controller_options){ |c| resolve_method.call(c, *args) }
end
guard(proc=nil, &block) click to toggle source

A proc or method that must return a true for the requirement to be satisified

# File lib/requirement_authorization.rb, line 18
def guard(proc=nil, &block)
  @guard = controller_filter_proc(proc, &block)
end
Also aliased as: guard_if
guard_if(proc=nil, &block)
Alias for: guard
guard_unless(proc=nil, &block) click to toggle source
# File lib/requirement_authorization.rb, line 23
def guard_unless(proc=nil, &block)
  # Lazily invert the return of the controller proc.
  @guard = Proc.new{|c, args| not controller_filter_proc(proc, &block).call(c, *args)}
end
resolution(proc=nil, &block) click to toggle source

This is the method that we’ll call if the guard fails. The resolution should take the user through a flow where they can satisify the requirements for the requirement and pass on through.

# File lib/requirement_authorization.rb, line 30
def resolution(proc=nil, &block)
  @resolution = controller_filter_proc(proc, &block)
end
resolve(controller_instance, *args) click to toggle source

The gaurd, resolution process. This is where the magic happens.

# File lib/requirement_authorization.rb, line 43
def resolve(controller_instance, *args)
  @resolution.call(controller_instance, *args) if @guard.call(controller_instance, *args)
end

Protected Instance Methods

controller_filter_proc(proc=nil, &block) click to toggle source

Packages up a proc or a block into something that a controller can deal with

# File lib/requirement_authorization.rb, line 49
def controller_filter_proc(proc=nil, &block)
  if block_given? # Instance eval the block in the context of the controller
    Proc.new{|c, args| c.instance_eval(&block)}
  elsif proc.respond_to?(:call) # Just run the proc, easy!
    Proc.new{|c, args| proc.call(*args)}
  else # This could be a symbol or string, which we'll send to the controller to see if it exists
    # TODO make this arity dyanmic...
    # The arity check lets us call a method in a controller with or without arguments
    Proc.new{|c, args| c.method(proc).arity == 0 ? c.send(proc) : c.send(proc, *args)}
  end
end
extract_filter_args!(args) click to toggle source
# File lib/requirement_authorization.rb, line 61
def extract_filter_args!(args)
  # Gives us the last hash in an array of args (e.g. before_filter :act1, :act2, :only => [:fun])
  # would return {:only => [:fun]}
  options = args.last.is_a?(Hash) ? args.pop : {}
  # Collect all of the controller options and delete them out of the options hash
  controller_options = options.inject({}) do |memo, (option, value)|
    memo[option] = options.delete(option) if CONTROLLER_OPTIONS.include?(option)
    memo
  end
  # The remaining pairs in the options hash should be put back into the args array
  # unless the hash is empty. If we pushed an empty hash theres a chance we'd screw
  # up the arity of calling functions within the controllers.
  args.push options unless options.empty?
  [ args, controller_options ]
end