Merge branch 'master' into meta_where

This commit is contained in:
Ryan Bates
2011-03-08 22:05:40 -08:00
13 changed files with 125 additions and 53 deletions

View File

@@ -206,7 +206,7 @@ module CanCan
def unauthorized_message(action, subject)
keys = unauthorized_message_keys(action, subject)
variables = {:action => action.to_s}
variables[:subject] = (subject.class == Class ? subject : subject.class).to_s.downcase
variables[:subject] = (subject.class == Class ? subject : subject.class).to_s.underscore.humanize.downcase
message = I18n.translate(nil, variables.merge(:scope => :unauthorized, :default => keys + [""]))
message.blank? ? nil : message
end

View File

@@ -109,6 +109,9 @@ module CanCan
#
# load_resource :new => :build
#
# [:+prepend+]
# Passing +true+ will use prepend_before_filter instead of a normal before_filter.
#
def load_resource(*args)
cancan_resource_class.add_before_filter(self, :load_resource, *args)
end
@@ -162,6 +165,9 @@ module CanCan
# [:+through+]
# Authorize conditions on this parent resource when instance isn't available.
#
# [:+prepend+]
# Passing +true+ will use prepend_before_filter instead of a normal before_filter.
#
def authorize_resource(*args)
cancan_resource_class.add_before_filter(self, :authorize_resource, *args)
end
@@ -220,14 +226,31 @@ module CanCan
# check_authorization
# end
#
# Any arguments are passed to the +after_filter+ it triggers.
#
# See skip_authorization_check to bypass this check on specific controller actions.
def check_authorization(*args)
self.after_filter(*args) do |controller|
unless controller.instance_variable_defined?(:@_authorized)
raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check."
end
#
# Options:
# [:+only+]
# Only applies to given actions.
#
# [:+except+]
# Does not apply to given actions.
#
# [:+if+]
# Supply the name of a controller method to be called. The authorization check only takes place if this returns true.
#
# check_authorization :if => :admin_controller?
#
# [:+unless+]
# Supply the name of a controller method to be called. The authorization check only takes place if this returns false.
#
# check_authorization :unless => :devise_controller?
#
def check_authorization(options = {})
self.after_filter(options.slice(:only, :except)) do |controller|
return if controller.instance_variable_defined?(:@_authorized)
return if options[:if] && !controller.send(options[:if])
return if options[:unless] && controller.send(options[:unless])
raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check."
end
end

View File

@@ -5,7 +5,8 @@ module CanCan
def self.add_before_filter(controller_class, method, *args)
options = args.extract_options!
resource_name = args.first
controller_class.before_filter(options.slice(:only, :except)) do |controller|
before_filter_method = options.delete(:prepend) ? :prepend_before_filter : :before_filter
controller_class.send(before_filter_method, options.slice(:only, :except)) do |controller|
controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except)).send(method)
end
end
@@ -112,7 +113,7 @@ module CanCan
end
def member_action?
!collection_actions.include? @params[:action].to_sym
new_actions.include?(@params[:action].to_sym) || (@params[:id] && !collection_actions.include?(@params[:action].to_sym))
end
# Returns the class used for this resource. This can be overriden by the :class option.

View File

@@ -3,7 +3,8 @@ module CanCan
class InheritedResource < ControllerResource # :nodoc:
def load_resource_instance
if parent?
@controller.send :parent
@controller.send :association_chain
@controller.instance_variable_get("@#{instance_name}")
elsif new_actions.include? @params[:action].to_sym
@controller.send :build_resource
else
@@ -12,7 +13,7 @@ module CanCan
end
def resource_base
@controller.send :end_of_association_chain
@controller.send :collection
end
end
end

View File

@@ -68,7 +68,9 @@ module CanCan
end
def database_records
if @model_class.respond_to?(:where) && @model_class.respond_to?(:joins)
if override_scope
override_scope
elsif @model_class.respond_to?(:where) && @model_class.respond_to?(:joins)
@model_class.where(conditions).joins(joins)
else
@model_class.scoped(:conditions => conditions, :joins => joins)
@@ -77,6 +79,18 @@ module CanCan
private
def override_scope
conditions = @rules.map(&:conditions).compact
if conditions.any? { |c| c.kind_of?(ActiveRecord::Relation) }
if conditions.size == 1
conditions.first
else
rule = @rules.detect { |rule| rule.conditions.kind_of?(ActiveRecord::Relation) }
raise Error, "Unable to merge an Active Record scope with other conditions. Instead use a hash or SQL for #{rule.actions.first} #{rule.subjects.first} ability."
end
end
end
def merge_conditions(sql, conditions_hash, behavior)
if conditions_hash.blank?
behavior ? true_sql : false_sql

View File

@@ -3,7 +3,7 @@ module CanCan
# it holds the information about a "can" call made on Ability and provides
# helpful methods to determine permission checking and conditions hash generation.
class Rule # :nodoc:
attr_reader :base_behavior, :actions, :conditions
attr_reader :base_behavior, :subjects, :actions, :conditions
attr_writer :expanded_actions
# The first argument when initializing is the base_behavior which is a true/false
@@ -11,6 +11,7 @@ module CanCan
# and subject respectively (such as :read, @project). The third argument is a hash
# of conditions and the last one is the block passed to the "can" call.
def initialize(base_behavior, action, subject, conditions, block)
raise Error, "You are not able to supply a block with a hash of conditions in #{action} #{subject} ability. Use either one." if conditions.kind_of?(Hash) && !block.nil?
@match_all = action.nil? && subject.nil?
@base_behavior = base_behavior
@actions = [action].flatten