通过CanCan中的多个操作进行授权

时间:2012-11-14 11:48:16

标签: ruby-on-rails authorization cancan

我试图在授权方面更好地理解CanCan的功能。想象一下这个控制器动作:

def update
  if can? :action, Model or can? :resolve, Model or can? :authorize, AnotherModel
    # My Code here
    respond_with @model
  else
    raise CanCan::AccessDenied.new(nil, :update, Model)
  end
end

我在尝试使用authorize!找到上述解决方案时达到了这一点。据我所知(也看签名)authorize!只接受一个权限(动作)和一个主题,并带有可选消息,如下所示:

def authorize!(action, subject, *args)
  # code
end

有没有一种方法可以忽略指示授权检查多项操作?将两个一个接一个地授权将在权限之间充当AND条件,我希望它像OR条件一样工作,基本上类似于上面的自定义代码(具有以下问题)提高CanCan中的AuthorizationNotPerformed,可以使用skip_authorize_resource来避免,这不是我真正想做的事情。

2 个答案:

答案 0 :(得分:2)

您可以根据需要创建custom action并创建尽可能多的or条件。

can :my_update_action, Project do |project|
  can?(:read, ModelX) || can?(:read, ModelY) || ... 
end

答案 1 :(得分:1)

最后,我为能力类添加了这个相当不错的解决方案:

def multi_authorize!(*actions, message_hash)
    message = nil
    if message_hash.kind_of?(Hash) && message_hash.has_key?(:message)
      message = message_hash[:message]
    end
    auth = false
    actions.each do |act|
      auth = auth || can?(act[0], act[1])
    end
    if !auth
      message ||= unauthorized_message(actions[0][0], actions[0][1])
      raise CanCan::AccessDenied.new(message, actions[0][0], actions[0][1])
    end
end

包含控制器的帮助程序:

module CanCanAddition
  def multi_authorize!(*args)
    @_authorized = true
    current_ability.multi_authorize!(*args)
  end
end

if defined? ActionController::Base
  ActionController::Base.class_eval do
    include ApplicationHelper::CanCanAddition
  end
end

我称之为:

  def create
    multi_authorize! [:create, Model1], [:authorize, Model2], :message => "You are not authorized to perform this action!"
    # other code...
  end

警告:由于能力类中的代码,您必须提供消息,否则最后一对授权将不会在*args中传递。我需要一些时间来克服这个问题,但我认为解决方案的想法很合适。