class Aclize::Acl::ControllersRegistry

Attributes

denied[R]
permitted[R]

Public Class Methods

new() click to toggle source
# File lib/aclize/acl/controllers_registry.rb, line 13
def initialize
  @permitted = {"*" => []}.nested_under_indifferent_access
  @denied    = {"*" => []}.nested_under_indifferent_access
end

Public Instance Methods

permit(controller, only: nil, except: nil) click to toggle source

add a new permit rule to controllers registry

# File lib/aclize/acl/controllers_registry.rb, line 19
def permit(controller, only: nil, except: nil)
  @permitted[controller] ||= []
  @denied[controller]    ||= []

  raise ArgumentError.new("#permit cannot accept both :only and :except. At most one of them can be specified!") if only && except

  if except
    @permitted[controller] = ["*"]
    @denied[controller]    = normalize(except)
  elsif only
    @denied[controller]    = []
    @permitted[controller] = normalize(only)
  else
    @permitted[controller] = ["*"]
    @denied[controller]    = []
  end
end
permitted?(controller, *args) click to toggle source

check if each action in the list is allowed for the specified controller

# File lib/aclize/acl/controllers_registry.rb, line 38
def permitted?(controller, *args)
  @permitted[controller] ||= []
  @denied[controller]    ||= []
  actions = normalize(args)

  if actions.empty?
    return controller_permitted?(controller)
  elsif controller_permitted?(controller)
    # we know the there's at least one permitted action for this controller,
    # so return false if there's at least one denied action in the list of actions to check
    return false unless (actions & @denied[controller]).empty?

    # we know that the actions aren't denied at controller level, so we could
    # return true if all the actions are also permitted at controller level
    return true if @permitted[controller].include?("*") || (actions & @permitted[controller]) == actions

    # the actions aren't permitted at controller level, so if any of them is
    # denied at global level, we will return false
    return false unless (actions & @denied["*"]).empty?

    # the actions aren't denied at global level, so we have to check if them
    # are allowed at global level and return true if so
    return true if @permitted["*"].include?("*") || (actions & @permitted["*"]) == actions
  end

  return false
end

Protected Instance Methods

controller_permitted?(controller) click to toggle source

check if the controller is permitted (at least one action in the controller should be permitted)

# File lib/aclize/acl/controllers_registry.rb, line 69
def controller_permitted?(controller)
  # the simplies case is when there's a permission for at least one action for this controller
  if @permitted[controller].empty?
    # check if there're wildcard permissions
    if @permitted["*"].empty?
      # there isn't any global permission for the user
      return false
    else
      # we have global permissions (for all the controllers), so we
      # have to check if those actions weren't denied
      denied_actions = @denied[controller] + @denied["*"]
      return !(@permitted["*"] - denied_actions).empty?
    end
  else
    # we are sure there's at least one permission for this controller
    return true
  end
end
normalize(items) click to toggle source
# File lib/aclize/acl/controllers_registry.rb, line 88
def normalize(items)
  result = items.nil? ? [] : items.is_a?(Array) ? items.flatten : [items]
  return result.map { |x| x.to_s }
end