module SimonSays::Authorizer

Public Instance Methods

authorize(required = nil, options) click to toggle source

Internal authorize instance method

@private @param [Symbol, String] one or more required roles @param [Hash] options authorizer options

# File lib/simon_says/authorizer.rb, line 147
def authorize(required = nil, options)
  if through = options[:through]
    name = through.to_s.singularize.to_sym
  else
    name = options[:resource]
  end

  record = instance_variable_get("@#{name}")

  if record.nil? # must be devise scope
    record = send("current_#{name}")
    send "authenticate_#{name}!"
  end

  role_attr = record.class.role_attribute_name
  actual = record.send(role_attr)

  required ||= options[role_attr]
  required = [required] unless Array === required

  # actual roles must have at least
  # one required role (array intersection)
  ((required & actual).size > 0).tap do |res|
    raise Denied.new(role_attr, required, actual) unless res
  end
end
find_resource(resource, options = {}) click to toggle source

Internal find_resource instance method

@private @param [Symbol, String] resource name of resource to find @param [Hash] options finder options

# File lib/simon_says/authorizer.rb, line 123
def find_resource(resource, options = {})
  resource = resource.to_s

  scope, query = resource_scope_and_query(resource, options)
  through = options[:through] ? options[:through].to_s : nil

  assoc = through || (options[:from] ? resource.pluralize : nil)
  scope = scope.send(assoc) if assoc && scope.respond_to?(assoc)

  record = scope.where(query).first!

  if through
    instance_variable_set "@#{through.singularize}", record
    record = record.send(resource)
  end

  instance_variable_set "@#{resource}", record
end

Private Instance Methods

resource_scope_and_query(resource, options) click to toggle source

@private

# File lib/simon_says/authorizer.rb, line 177
def resource_scope_and_query(resource, options)
  if options[:through]
    field = "#{resource}_id"

    query = { field => params[field] } if params[field]
    scope = send(self.class.default_authorization_scope)

  elsif options[:from]
    scope = instance_variable_get("@#{options[:from]}") || send(options[:from])

  else
    klass = (options[:class_name] || resource).to_s
    klass = "#{options[:namespace]}/#{klass}" if options[:namespace]

    scope = klass.classify.constantize
  end

  field ||= options.fetch(:find_attribute, :id)
  query ||= { field => params[options.fetch(:param_key, :id)] }

  return scope, query
end