Rails - поиск метода сухой авторизации, совместимого с различными вложенными ресурсами - PullRequest
0 голосов
/ 16 апреля 2010

Консенсус в том, что вы не должны вкладывать ресурсы глубже, чем на 1 уровень. Так что, если у меня есть 3 модели, как это (ниже только гипотетическая ситуация)

Пользователь has_many Houses has_many Арендаторы

и соблюдать вышеизложенное, я делаю

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

Теперь я хочу, чтобы пользователь мог редактировать как свои дома, так и информацию об арендаторах, но я хочу, чтобы они не пытались редактировать дома и арендаторы других пользователей, подделывая часть user_id URL. Поэтому я создаю before_filter, как этот

 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

для домов это просто, потому что user_id передается через

edit_user_house_path(@user, @house)

но в случае арендаторов

tenant house_tenent_path(@house)

идентификатор пользователя не передается. Но я могу получить идентификатор пользователя, выполнив @ house.user.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 Ответ

1 голос
/ 16 апреля 2010

Выполните следующие действия:

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 !@current_user.houses.exists?(params[:house_id])
    kill_session("You don't have access to this page")
  elsif params[:tenant_id] and !@current_user.tenants.exists?(params[:tanant_id])
    kill_session("You don't have access to this page")
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...