2010-04-16 66 views
0

共識是你不應該嵌套比1級更深的資源。所以,如果我有3款這樣 (以下僅僅是一個假設的情況)Rails - 尋求與各種嵌套資源兼容的乾式授權方法

用戶的has_many房屋的has_many租戶

,並共同遵守上述我做

map.resources :users, :has_many => :houses 
map.resorces :houses, :has_many => :tenants 

現在,我希望用戶能夠編輯他們的房屋和租戶的詳細信息,但我想阻止他們通過僞造url的user_id部分來編輯另一個用戶房屋和租戶。所以,我創建了這樣的房子

def prevent_user_acting_as_other_user 
     if User.find_by_id(params[:user_id]) != current_user() 
      @current_user_session.destroy 
      flash[:error] = "Stop screwing around wiseguy" 
      redirect_to login_url() 
      return 
     end 
    end 

一個的before_filter,因爲USER_ID通過

edit_user_house_path(@user, @house) 

但在tenents情況下

tenant house_tenent_path(@house) 

沒有用戶ID傳遞通過這很容易。但是我可以通過@ house.user.id來獲取用戶ID,但是這樣id必須將上面的代碼更改爲此。

def prevent_user_acting_as_other_user 
    if params[:user_id] 
     @user = User.find(params[:user_id] 
    elsif params[:house_id] 
     @user = House.find(params[:house_id]).user 
    end 
    if @user != current_user() 
     #kick em out 
    end 
end 

它做的工作,但我想知道如果有一個更優雅的方式。每次我添加一個需要保護用戶僞造的新資源時,我必須不斷添加條件。我不認爲會有很多情況,但如果存在的話,想知道更好的方法。

回答

1

執行以下操作:

class User < ActiveRecord::Base 
    has_many :houses 
    has_many :tenants 
end 

class House < ActiveRecord::Base 
    belongs_to :user 
    has_many :tenants 
end 

class Tenant < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :house 
end 

在你的過濾器執行以下操作:

def kill_session(message) 
    @current_user_session.destroy 
    flash[:error] = message 
    redirect_to login_url() 
end 

def prevent_user_acting_as_other_user 
    if params[:user_id] and params[:user_id] != @current_user.id 
    kill_session("You don't have access to this page") 
    elsif params[:house_id] and [email protected]_user.houses.exists?(params[:house_id]) 
    kill_session("You don't have access to this page") 
    elsif params[:tenant_id] and [email protected]_user.tenants.exists?(params[:tanant_id]) 
    kill_session("You don't have access to this page") 
    end 
end 
+0

更新了答案,解決關聯。 – 2010-04-16 04:57:09

+0

非常感謝您對此和您最近問題的其他答案。 – robodisco 2010-04-19 05:50:38