3

在授权方面,我试图更好地了解 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条件一样工作,基本上类似于上面的自定义代码(AuthorizationNotPerformed在CanCan中有提高的问题,可以避免skip_authorize_resource哪个不是我真的很想做的事情)。

4

2 回答 2

3

您可以创建自定义操作并创建任意数量的or-conditions。

can :my_update_action, Project do |project|
  can?(:read, ModelX) || can?(:read, ModelY) || ... 
end
于 2012-11-22T16:53:29.080 回答
3

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

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。我需要一些时间来克服这个问题,但我认为解决方案的想法很合适。

于 2012-11-23T11:49:52.510 回答