class Acl9::Dsl::Base

Attributes

allows[R]
denys[R]

Public Class Methods

new(*args) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 10
def initialize(*args)
  @default_action = nil
  @allows = []
  @denys  = []
  @original_args = args
  @action_clause = nil
end

Public Instance Methods

acl_block!(&acl_block) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 18
def acl_block!(&acl_block)
  instance_eval(&acl_block)
end
allowance_expression() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 26
def allowance_expression
  allowed_expr    = @allows.any?  ? @allows.map { |clause| "(#{clause})" }.join(' || ') : 'false'
  not_denied_expr = @denys.any?   ? @denys.map { |clause| "!(#{clause})" }.join(' && ') : 'true'

  [allowed_expr, not_denied_expr].
    map { |expr| "(#{expr})" }.
    join(default_action == :deny ? ' && ' : ' || ')
end
Also aliased as: to_s
default_action() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 22
def default_action
  @default_action.nil? ? :deny : @default_action
end
to_s()

Protected Instance Methods

_action_check_expression(action_list) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 168
def _action_check_expression(action_list)
  unless action_list.is_a?(Array)
    action_list = [ action_list.to_s ]
  end

  case action_list.size
  when 0 then "true"
  when 1 then "(#{_action_ref} == '#{action_list.first}')"
  else
    set_of_actions = "Set.new([" + action_list.map { |act| "'#{act}'"}.join(',')  + "])"

    "#{set_of_actions}.include?(#{_action_ref})"
  end
end
_action_ref() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 203
def _action_ref
  raise
end
_add_rule(what, condition) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 150
def _add_rule(what, condition)
  anded = [what] + [@action_clause, condition].compact
  anded[0] = "(#{anded[0]})" if anded.size > 1

  (@current_rule == :allow ? @allows : @denys) << anded.join(' && ')
end
_either_of(exprs) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 145
def _either_of(exprs)
  clause = exprs.map { |expr| "(#{expr})" }.join(' || ')
  return "(#{clause})"
end
_method_ref(method) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 207
def _method_ref(method)
  raise
end
_object_ref(object) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 199
def _object_ref(object)
  raise
end
_parse_and_add_rule(*args) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 106
def _parse_and_add_rule(*args)
  options = args.extract_options!
  options.keys.each { |key| _permitted_allow_deny_option!(key) }

  _set_action_clause( _retrieve_only(options), options.delete(:except))

  object_s = _role_object_s(options)

  role_checks = args.map do |who|
    case who
    when anonymous then "#{_subject_ref}.nil?"
    when logged_in then "!#{_subject_ref}.nil?"
    when all       then "true"
    else
      "!#{_subject_ref}.nil? && #{_subject_ref}.has_role?('#{who}'#{object_s})"
    end
  end

  [:if, :unless].each do |cond|
    val = options[cond]
    raise ArgumentError, "#{cond} option must be a Symbol" if val && !val.is_a?(Symbol)
  end

  condition = [
    (_method_ref(options[:if]) if options[:if]),
    ("!#{_method_ref(options[:unless])}" if options[:unless])
  ].compact.join(' && ')

  condition = nil if condition.blank?

  _add_rule(case role_checks.size
            when 0
              raise ArgumentError, "allow/deny should have at least 1 argument"
            when 1 then role_checks.first
            else
              _either_of(role_checks)
            end, condition)
end
_permitted_allow_deny_option!(key) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 96
def _permitted_allow_deny_option!(key)
  raise ArgumentError, "#{key} is not a valid option" unless [:to, :only, :except, :if, :unless, *VALID_PREPOSITIONS].include?(key.to_sym)
end
_retrieve_only(options) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 100
def _retrieve_only options
  only = [ options.delete(:only) ].flatten.compact
  only |= [ options.delete(:to) ].flatten.compact
  only if only.present?
end
_role_object_s(options) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 183
def _role_object_s(options)
  object = _by_preposition options

  case object
  when Class  then ", #{object}"
  when Symbol then ", #{_object_ref object}"
  when nil    then ""
  else
    raise ArgumentError, "object specified by preposition can only be a Class or a Symbol"
  end
end
_set_action_clause(only, except) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 157
def _set_action_clause(only, except)
  raise ArgumentError, "both :only (:to) and :except cannot be specified in the rule" if only && except

  @action_clause  = nil
  action_list     = only || except
  return unless action_list

  expr = _action_check_expression(action_list)
  @action_clause = only ? "#{expr}" : "!#{expr}"
end
_subject_ref() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 195
def _subject_ref
  raise
end
action(*args, &block)
Alias for: actions
actions(*args, &block) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 59
def actions(*args, &block)
  raise ArgumentError, "actions should receive at least 1 action as argument" if args.size < 1

  subsidiary = self.class.new(*@original_args)

  class <<subsidiary
    def actions(*args)
      raise ArgumentError, "You cannot use actions inside another actions block"
    end

    def default(*args)
      raise ArgumentError, "You cannot use default inside an actions block"
    end

    def _set_action_clause(only, except)
      raise ArgumentError, "You cannot use :only (:to) or :except inside actions block" if only || except
    end
  end

  subsidiary.acl_block!(&block)
  action_check = _action_check_expression(args)
  squash = lambda { |rules| action_check + ' && ' + _either_of(rules) }

  @allows << squash.call(subsidiary.allows) if subsidiary.allows.size > 0
  @denys  << squash.call(subsidiary.denys)  if subsidiary.denys.size > 0
end
Also aliased as: action
all() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 90
def all;       true  end
Also aliased as: everyone, everybody, anyone
allow(*args) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 49
def allow(*args)
  @current_rule = :allow
  _parse_and_add_rule(*args)
end
anonymous() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 89
def anonymous; nil   end
anyone()
Alias for: all
default(default_action) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 39
def default(default_action)
  raise ArgumentError, "default can only be called once in access_control block" if @default_action

  unless [:allow, :deny].include? default_action
    raise ArgumentError, "invalid value for default (can be :allow or :deny)"
  end

  @default_action = default_action
end
deny(*args) click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 54
def deny(*args)
  @current_rule = :deny
  _parse_and_add_rule(*args)
end
everybody()
Alias for: all
everyone()
Alias for: all
logged_in() click to toggle source
# File lib/acl9/controller_extensions/dsl_base.rb, line 88
def logged_in; false end