2012-11-14 49 views
1

我試圖更好地理解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,可以避免與這不是我真正想做的事情)。

回答

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中傳遞。我需要一些時間來克服這個問題,但是我認爲這個解決方案適合我。

+0

好的,但是你可以用循環和能力文件中的一些條件(使用自定義動作)構建相同的東西。而且你可以重複使用這些自定義操作,從而產生更簡潔的代碼庫。那麼無論你爲什麼工作;) – spas

2

您可以創建一個custom action並根據需要創建儘可能多的or條件。

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

+1。很好的解決方案,但我覺得需要更通用的東西,而不是創建很多自定義的「可以」操作。我已經添加了自己的解決方案。 – Tallmaris