2011-05-03 29 views
2

我正在使用聲明性授權gem來獲取rails項目中的權限,我試圖根據用戶權限限制模型的輸出。使用declarative_authorization來限制模型中的結果

我的縮寫授權文件看起來是這樣的:

roles do 
    role :supervisor 
    has_permission_on :people, :to => :manage_all 
    end 

    role :basic_user 
    has_permission_on :people, :to => :manage_subordinates 
    end 
end 

privileges do 
    privilege :manage_subordinates do 
    includes :subordinate_records 
    end 

    privilege :manage_all do 
    includes :all_records 
    end 
end 

在我的人的模型,我有我想這個樣子

def self.supervised_by(user) 
    if user.permitted_to? :all_records 
    #return all of the records 
    elsif user.permitted_to? :subordinate_records 
    #return some of the records 
    else 
    #return none of the records 
    end 
end 

它看起來像有支持靜態方法這在使用with_permissions_to或allowed_to的文檔中使用AuthorizationInModel對象。我一直無法知道如何根據文檔使用這些函數,或者如何在當前模型中返回當前用戶的權限列表。

任何想法?

回答

1

我發現了一個替代解決方案,使用內置的if屬性方法。我原來是離開它,因爲我使用了非命名空間模型和命名空間控制器和視圖。這個結構是我正在處理的項目的原始版本的工件。我的大部分工作都得到了聲明授權來處理這種結構。

我不清楚的主要信息是如何在部分命名空間環境中命名權限。模型期望模型名稱(:people),控制器預期命名空間和模型(:staff_people),並且只要您選擇一個,視圖就不會在意。我選擇的解決方案是使用模型名稱並在每個控制器中明確設置上下文。如果未在控制器中設置上下文,則使用filter_access_to不起作用,因爲它將查找staff_people權限而不是正確的權限人員。

在聲明性授權配置文件中,我授予管理員和部分權限給主管的完全權限。 person.supervised返回一個自己和所有其他受監督人員的數組。

roles do 
    role :administrator 
    has_permission_on :people, :to => [:create, :read, :update, :delete] 
    end 

    role :supervisor 
    has_permission_on :people do 
     to => [:create, :read, :update, :delete] 
     if_attribute :id => is_in { Person.find_by_user_id(user.id).supervised } 
    end 
    end 
end 

要在Namespaced控制器中訪問此信息,我正在使用filer_resource_access。

module Staff 
    class PeopleController < ApplicationController 
    filter_resource_access :context => :people 

    def index 
     @people = People.with_permissions_to(:read) 
    end 

我發現,使用

filter_access_to :all, :with_attribute => true 

對於那些需要使用with_permissions_to和if_attribute許可方法沒有奏效。我不知道爲什麼,這是一個問題

仍然有必要使用filter_access_to對於不包括id獲取單個記錄作爲參數部分非標準控制器動作。例如,如果叫part_timers一個動作返回的人的名單,這個解決方法看起來像它應該工作:

filter_resource_access :context => :people, :additional_member => { :part_timers => :read } 

正確的解決辦法是保持filter_resource_access原樣,並添加一個filter_access_to該動作

filter_resource_access :context => :people 
fitler_access_to :part_timers, :required => :read, :context => people 
0

可能有更好的方法來做到這一點,但如果一切設置正確,這應該適用於您的supervised_by方法。

def self.supervised_by(user) 
    if Person.new.permitted_to? :all_records, :user=>user 
    #return all of the records 
    elsif Person.new.permitted_to? :subordinate_records, :user=>user 
    #return some of the records 
    else 
    #return none of the records 
    end 
end