renaming CanDefinition to Rule
This commit is contained in:
parent
a6959c0ab2
commit
37c149182c
|
@ -1,5 +1,5 @@
|
||||||
require 'cancan/ability'
|
require 'cancan/ability'
|
||||||
require 'cancan/can_definition'
|
require 'cancan/rule'
|
||||||
require 'cancan/controller_resource'
|
require 'cancan/controller_resource'
|
||||||
require 'cancan/controller_additions'
|
require 'cancan/controller_additions'
|
||||||
require 'cancan/active_record_additions'
|
require 'cancan/active_record_additions'
|
||||||
|
|
|
@ -54,8 +54,8 @@ module CanCan
|
||||||
#
|
#
|
||||||
# Also see the RSpec Matchers to aid in testing.
|
# Also see the RSpec Matchers to aid in testing.
|
||||||
def can?(action, subject, *extra_args)
|
def can?(action, subject, *extra_args)
|
||||||
match = relevant_can_definitions_for_match(action, subject).detect do |can_definition|
|
match = relevant_rules_for_match(action, subject).detect do |rule|
|
||||||
can_definition.matches_conditions?(action, subject, extra_args)
|
rule.matches_conditions?(action, subject, extra_args)
|
||||||
end
|
end
|
||||||
match ? match.base_behavior : false
|
match ? match.base_behavior : false
|
||||||
end
|
end
|
||||||
|
@ -122,7 +122,7 @@ module CanCan
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
def can(action = nil, subject = nil, conditions = nil, &block)
|
def can(action = nil, subject = nil, conditions = nil, &block)
|
||||||
can_definitions << CanDefinition.new(true, action, subject, conditions, block)
|
rules << Rule.new(true, action, subject, conditions, block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Defines an ability which cannot be done. Accepts the same arguments as "can".
|
# Defines an ability which cannot be done. Accepts the same arguments as "can".
|
||||||
|
@ -138,7 +138,7 @@ module CanCan
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
def cannot(action = nil, subject = nil, conditions = nil, &block)
|
def cannot(action = nil, subject = nil, conditions = nil, &block)
|
||||||
can_definitions << CanDefinition.new(false, action, subject, conditions, block)
|
rules << Rule.new(false, action, subject, conditions, block)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Alias one or more actions into another one.
|
# Alias one or more actions into another one.
|
||||||
|
@ -187,10 +187,10 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a CanCan::Query instance to help generate database queries based on the ability.
|
# Returns a CanCan::Query instance to help generate database queries based on the ability.
|
||||||
# If any relevant can definitions use a block then an exception will be raised because an
|
# If any relevant rules use a block then an exception will be raised because an
|
||||||
# SQL query cannot be generated from blocks of code.
|
# SQL query cannot be generated from blocks of code.
|
||||||
def query(action, subject)
|
def query(action, subject)
|
||||||
Query.new(subject, relevant_can_definitions_for_query(action, subject))
|
Query.new(subject, relevant_rules_for_query(action, subject))
|
||||||
end
|
end
|
||||||
|
|
||||||
# See ControllerAdditions#authorize! for documentation.
|
# See ControllerAdditions#authorize! for documentation.
|
||||||
|
@ -215,18 +215,18 @@ module CanCan
|
||||||
|
|
||||||
def attributes_for(action, subject)
|
def attributes_for(action, subject)
|
||||||
attributes = {}
|
attributes = {}
|
||||||
relevant_can_definitions(action, subject).map do |can_definition|
|
relevant_rules(action, subject).map do |rule|
|
||||||
attributes.merge!(can_definition.attributes_from_conditions) if can_definition.base_behavior
|
attributes.merge!(rule.attributes_from_conditions) if rule.base_behavior
|
||||||
end
|
end
|
||||||
attributes
|
attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_block?(action, subject)
|
def has_block?(action, subject)
|
||||||
relevant_can_definitions(action, subject).any?(&:only_block?)
|
relevant_rules(action, subject).any?(&:only_block?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_raw_sql?(action, subject)
|
def has_raw_sql?(action, subject)
|
||||||
relevant_can_definitions(action, subject).any?(&:only_raw_sql?)
|
relevant_rules(action, subject).any?(&:only_raw_sql?)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -259,30 +259,30 @@ module CanCan
|
||||||
results
|
results
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_definitions
|
def rules
|
||||||
@can_definitions ||= []
|
@rules ||= []
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns an array of CanDefinition instances which match the action and subject
|
# Returns an array of Rule instances which match the action and subject
|
||||||
# This does not take into consideration any hash conditions or block statements
|
# This does not take into consideration any hash conditions or block statements
|
||||||
def relevant_can_definitions(action, subject)
|
def relevant_rules(action, subject)
|
||||||
can_definitions.reverse.select do |can_definition|
|
rules.reverse.select do |rule|
|
||||||
can_definition.expanded_actions = expand_actions(can_definition.actions)
|
rule.expanded_actions = expand_actions(rule.actions)
|
||||||
can_definition.relevant? action, subject
|
rule.relevant? action, subject
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def relevant_can_definitions_for_match(action, subject)
|
def relevant_rules_for_match(action, subject)
|
||||||
relevant_can_definitions(action, subject).each do |can_definition|
|
relevant_rules(action, subject).each do |rule|
|
||||||
if can_definition.only_raw_sql?
|
if rule.only_raw_sql?
|
||||||
raise Error, "The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for #{action.inspect} #{subject.inspect}"
|
raise Error, "The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for #{action.inspect} #{subject.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def relevant_can_definitions_for_query(action, subject)
|
def relevant_rules_for_query(action, subject)
|
||||||
relevant_can_definitions(action, subject).each do |can_definition|
|
relevant_rules(action, subject).each do |rule|
|
||||||
if can_definition.only_block?
|
if rule.only_block?
|
||||||
raise Error, "The accessible_by call cannot be used with a block 'can' definition. The SQL cannot be determined for #{action.inspect} #{subject.inspect}"
|
raise Error, "The accessible_by call cannot be used with a block 'can' definition. The SQL cannot be determined for #{action.inspect} #{subject.inspect}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,21 +12,21 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def query_with_mongoid_support(action, subject)
|
def query_with_mongoid_support(action, subject)
|
||||||
MongoidQuery.new(subject, relevant_can_definitions_for_query(action, subject))
|
MongoidQuery.new(subject, relevant_rules_for_query(action, subject))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class MongoidQuery
|
class MongoidQuery
|
||||||
def initialize(sanitizer, can_definitions)
|
def initialize(sanitizer, rules)
|
||||||
@sanitizer = sanitizer
|
@sanitizer = sanitizer
|
||||||
@can_definitions = can_definitions
|
@rules = rules
|
||||||
end
|
end
|
||||||
|
|
||||||
def conditions
|
def conditions
|
||||||
if @can_definitions.size == 0
|
if @rules.size == 0
|
||||||
false_query
|
false_query
|
||||||
else
|
else
|
||||||
@can_definitions.first.instance_variable_get(:@conditions)
|
@rules.first.instance_variable_get(:@conditions)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ module CanCan
|
||||||
# => true
|
# => true
|
||||||
# {}.all?{|a| a != 5}
|
# {}.all?{|a| a != 5}
|
||||||
# => true
|
# => true
|
||||||
class CanDefinition
|
class Rule
|
||||||
def matches_conditions_hash_with_mongoid_subject?(subject, conditions = @conditions)
|
def matches_conditions_hash_with_mongoid_subject?(subject, conditions = @conditions)
|
||||||
if subject.class.include?(Mongoid::Document) && conditions.any?{|k,v| !k.kind_of?(Symbol)}
|
if subject.class.include?(Mongoid::Document) && conditions.any?{|k,v| !k.kind_of?(Symbol)}
|
||||||
if conditions.empty?
|
if conditions.empty?
|
||||||
|
|
|
@ -3,9 +3,9 @@ module CanCan
|
||||||
# Generates the sql conditions and association joins for use in ActiveRecord queries.
|
# Generates the sql conditions and association joins for use in ActiveRecord queries.
|
||||||
# Normally you will not use this class directly, but instead through ActiveRecordAdditions#accessible_by.
|
# Normally you will not use this class directly, but instead through ActiveRecordAdditions#accessible_by.
|
||||||
class Query
|
class Query
|
||||||
def initialize(sanitizer, can_definitions)
|
def initialize(sanitizer, rules)
|
||||||
@sanitizer = sanitizer
|
@sanitizer = sanitizer
|
||||||
@can_definitions = can_definitions
|
@rules = rules
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns conditions intended to be used inside a database query. Normally you will not call this
|
# Returns conditions intended to be used inside a database query. Normally you will not call this
|
||||||
|
@ -24,12 +24,12 @@ module CanCan
|
||||||
# query(:manage, User).conditions # => "not (self_managed = 't') AND ((manager_id = 1) OR (id = 1))"
|
# query(:manage, User).conditions # => "not (self_managed = 't') AND ((manager_id = 1) OR (id = 1))"
|
||||||
#
|
#
|
||||||
def conditions
|
def conditions
|
||||||
if @can_definitions.size == 1 && @can_definitions.first.base_behavior
|
if @rules.size == 1 && @rules.first.base_behavior
|
||||||
# Return the conditions directly if there's just one definition
|
# Return the conditions directly if there's just one definition
|
||||||
@can_definitions.first.tableized_conditions
|
@rules.first.tableized_conditions
|
||||||
else
|
else
|
||||||
@can_definitions.reverse.inject(false_sql) do |sql, can_definition|
|
@rules.reverse.inject(false_sql) do |sql, rule|
|
||||||
merge_conditions(sql, can_definition.tableized_conditions, can_definition.base_behavior)
|
merge_conditions(sql, rule.tableized_conditions, rule.base_behavior)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -38,8 +38,8 @@ module CanCan
|
||||||
# See ActiveRecordAdditions#accessible_by for use in Active Record.
|
# See ActiveRecordAdditions#accessible_by for use in Active Record.
|
||||||
def joins
|
def joins
|
||||||
joins_hash = {}
|
joins_hash = {}
|
||||||
@can_definitions.each do |can_definition|
|
@rules.each do |rule|
|
||||||
merge_joins(joins_hash, can_definition.associations_hash)
|
merge_joins(joins_hash, rule.associations_hash)
|
||||||
end
|
end
|
||||||
clean_joins(joins_hash) unless joins_hash.empty?
|
clean_joins(joins_hash) unless joins_hash.empty?
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module CanCan
|
||||||
# This class is used internally and should only be called through Ability.
|
# This class is used internally and should only be called through Ability.
|
||||||
# it holds the information about a "can" call made on Ability and provides
|
# it holds the information about a "can" call made on Ability and provides
|
||||||
# helpful methods to determine permission checking and conditions hash generation.
|
# helpful methods to determine permission checking and conditions hash generation.
|
||||||
class CanDefinition # :nodoc:
|
class Rule # :nodoc:
|
||||||
attr_reader :base_behavior, :actions
|
attr_reader :base_behavior, :actions
|
||||||
attr_writer :expanded_actions
|
attr_writer :expanded_actions
|
||||||
|
|
|
@ -32,7 +32,7 @@ describe CanCan::Ability do
|
||||||
@ability.can?(:read, Symbol).should be_true
|
@ability.can?(:read, Symbol).should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should pass to previous can definition, if block returns false or nil" do
|
it "should pass to previous rule, if block returns false or nil" do
|
||||||
@ability.can :read, Symbol
|
@ability.can :read, Symbol
|
||||||
@ability.can :read, Integer do |i|
|
@ability.can :read, Integer do |i|
|
||||||
i < 5
|
i < 5
|
||||||
|
@ -144,7 +144,7 @@ describe CanCan::Ability do
|
||||||
@ability.can?(:update, 123).should be_false
|
@ability.can?(:update, 123).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should support custom objects in the can definition" do
|
it "should support custom objects in the rule" do
|
||||||
@ability.can :read, :stats
|
@ability.can :read, :stats
|
||||||
@ability.can?(:read, :stats).should be_true
|
@ability.can?(:read, :stats).should be_true
|
||||||
@ability.can?(:update, :stats).should be_false
|
@ability.can?(:update, :stats).should be_false
|
||||||
|
@ -165,7 +165,7 @@ describe CanCan::Ability do
|
||||||
@ability.can?(:read, 123).should be_false
|
@ability.can?(:read, 123).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should pass to previous can definition, if block returns false or nil" do
|
it "should pass to previous rule, if block returns false or nil" do
|
||||||
@ability.can :read, :all
|
@ability.can :read, :all
|
||||||
@ability.cannot :read, Integer do |int|
|
@ability.cannot :read, Integer do |int|
|
||||||
int > 10 ? nil : ( int > 5 )
|
int > 10 ? nil : ( int > 5 )
|
||||||
|
|
|
@ -15,19 +15,19 @@ describe CanCan::Query do
|
||||||
@ability.query(:read, Project).conditions.should == { :blocked => false, :user_id => 1 }
|
@ability.query(:read, Project).conditions.should == { :blocked => false, :user_id => 1 }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should merge multiple can definitions into single SQL string joining with OR" do
|
it "should merge multiple rules into single SQL string joining with OR" do
|
||||||
@ability.can :read, Project, :blocked => false
|
@ability.can :read, Project, :blocked => false
|
||||||
@ability.can :read, Project, :admin => true
|
@ability.can :read, Project, :admin => true
|
||||||
@ability.query(:read, Project).conditions.should == "(admin=true) OR (blocked=false)"
|
@ability.query(:read, Project).conditions.should == "(admin=true) OR (blocked=false)"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should merge multiple can definitions into single SQL string joining with OR and AND" do
|
it "should merge multiple rules into single SQL string joining with OR and AND" do
|
||||||
@ability.can :read, Project, :blocked => false, :active => true
|
@ability.can :read, Project, :blocked => false, :active => true
|
||||||
@ability.can :read, Project, :admin => true
|
@ability.can :read, Project, :admin => true
|
||||||
@ability.query(:read, Project).conditions.should orderlessly_match("(blocked=false AND active=true) OR (admin=true)")
|
@ability.query(:read, Project).conditions.should orderlessly_match("(blocked=false AND active=true) OR (admin=true)")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should merge multiple can definitions into single SQL string joining with OR and AND" do
|
it "should merge multiple rules into single SQL string joining with OR and AND" do
|
||||||
@ability.can :read, Project, :blocked => false, :active => true
|
@ability.can :read, Project, :blocked => false, :active => true
|
||||||
@ability.can :read, Project, :admin => true
|
@ability.can :read, Project, :admin => true
|
||||||
@ability.query(:read, Project).conditions.should orderlessly_match("(blocked=false AND active=true) OR (admin=true)")
|
@ability.query(:read, Project).conditions.should orderlessly_match("(blocked=false AND active=true) OR (admin=true)")
|
||||||
|
@ -77,7 +77,7 @@ describe CanCan::Query do
|
||||||
@ability.query(:read, Project).conditions.should == 'true=true'
|
@ability.query(:read, Project).conditions.should == 'true=true'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should have nil joins if no can definitions" do
|
it "should have nil joins if no rules" do
|
||||||
@ability.query(:read, Project).joins.should be_nil
|
@ability.query(:read, Project).joins.should be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,57 @@
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
# Most of CanDefinition functionality is tested in Ability specs
|
# Most of Rule functionality is tested in Ability specs
|
||||||
describe CanCan::CanDefinition do
|
describe CanCan::Rule do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@conditions = {}
|
@conditions = {}
|
||||||
@can = CanCan::CanDefinition.new(true, :read, Integer, @conditions, nil)
|
@rule = CanCan::Rule.new(true, :read, Integer, @conditions, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return no association joins if none exist" do
|
it "should return no association joins if none exist" do
|
||||||
@can.associations_hash.should == {}
|
@rule.associations_hash.should == {}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return no association for joins if just attributes" do
|
it "should return no association for joins if just attributes" do
|
||||||
@conditions[:foo] = :bar
|
@conditions[:foo] = :bar
|
||||||
@can.associations_hash.should == {}
|
@rule.associations_hash.should == {}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return single association for joins" do
|
it "should return single association for joins" do
|
||||||
@conditions[:foo] = {:bar => 1}
|
@conditions[:foo] = {:bar => 1}
|
||||||
@can.associations_hash.should == {:foo => {}}
|
@rule.associations_hash.should == {:foo => {}}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return multiple associations for joins" do
|
it "should return multiple associations for joins" do
|
||||||
@conditions[:foo] = {:bar => 1}
|
@conditions[:foo] = {:bar => 1}
|
||||||
@conditions[:test] = {1 => 2}
|
@conditions[:test] = {1 => 2}
|
||||||
@can.associations_hash.should == {:foo => {}, :test => {}}
|
@rule.associations_hash.should == {:foo => {}, :test => {}}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return nested associations for joins" do
|
it "should return nested associations for joins" do
|
||||||
@conditions[:foo] = {:bar => {1 => 2}}
|
@conditions[:foo] = {:bar => {1 => 2}}
|
||||||
@can.associations_hash.should == {:foo => {:bar => {}}}
|
@rule.associations_hash.should == {:foo => {:bar => {}}}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should tableize correctly for absurdly complex permissions" do
|
it "should tableize correctly for absurdly complex permissions" do
|
||||||
@conditions[:unit] = {:property=>{:landlord=>{:weasle_id=>560}}}
|
@conditions[:unit] = {:property=>{:landlord=>{:weasle_id=>560}}}
|
||||||
@conditions[:test] = 1
|
@conditions[:test] = 1
|
||||||
@can.tableized_conditions.should == {:units => {:properties => {:landlords=>{:weasle_id=>560}}}, :test => 1}
|
@rule.tableized_conditions.should == {:units => {:properties => {:landlords=>{:weasle_id=>560}}}, :test => 1}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should tableize correctly for complex permissions" do
|
it "should tableize correctly for complex permissions" do
|
||||||
@conditions[:unit] = {:property=>{:landlord_id=>560}}
|
@conditions[:unit] = {:property=>{:landlord_id=>560}}
|
||||||
@conditions[:test] = 1
|
@conditions[:test] = 1
|
||||||
@can.tableized_conditions.should == {:units => {:properties => {:landlord_id=>560}}, :test => 1}
|
@rule.tableized_conditions.should == {:units => {:properties => {:landlord_id=>560}}, :test => 1}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return table names in conditions for association joins" do
|
it "should return table names in conditions for association joins" do
|
||||||
@conditions[:foo] = {:bar => 1}
|
@conditions[:foo] = {:bar => 1}
|
||||||
@conditions[:test] = 1
|
@conditions[:test] = 1
|
||||||
@can.tableized_conditions.should == {:foos => {:bar => 1}, :test => 1}
|
@rule.tableized_conditions.should == {:foos => {:bar => 1}, :test => 1}
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return no association joins if conditions is nil" do
|
it "should return no association joins if conditions is nil" do
|
||||||
can = CanCan::CanDefinition.new(true, :read, Integer, nil, nil)
|
rule = CanCan::Rule.new(true, :read, Integer, nil, nil)
|
||||||
can.associations_hash.should == {}
|
rule.associations_hash.should == {}
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in New Issue
Block a user