2010-04-16 36 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