2012-06-18 23 views
0

愚蠢的問題時間:在下面的請求規範中,我嘗試確保我的分區中的第一個用戶不能被編輯(除了第一個用戶以外的任何人)。本規範中put和update_attributes之間的區別

# user is not logged in during these tests 

# variant 1 - this passes 
describe "first user" do 
    let(:first_user){ FactoryGirl.create(:admin) } 

    # use put to modify the user 
    before { put user_path(first_user, email: '[email protected]') } 

    # this passes, the response is a redirect 
    specify { response.should redirect_to(root_path) } 
end 

# variant 2 - this test fails 
describe "first user" do 
    let(:first_user){ FactoryGirl.create(:admin) } 

    # this fails, email is updated 
    it "can't be updated or edited" do 
    expect do 
     first_user.update_attributes(email: '[email protected]') 
    end.not_to change(first_user.reload, :email) 
    end 
end 

這兩個測試似乎做同樣的事情,但一個失敗,一個通過。我想我的理解很糟糕。應該update_attributes方法,如稱爲失敗的測試,調用我的控制器的過濾器之前:

# users_controller.rb 
before_filter correct_user, only: [:edit, :update] 

private 

# pretty messy, but ensures that ordinary users can only 
# edit their own accounts, that admin users can 
# edit all accounts, except for the first one. 
# I believe it also ensures that the first_user 
# can only be edited by the owner of the first account, i.e. me 
# due to the fact that the first condition of the `unless` clause will pass 
# if the current_user is the first_user. The complexity is necessary to prevent 
# other admins, from being able to edit the first_user. 
def correct_user 
    @user=User.find(params[:id]) 
    redirect_to(root_path, only_path: true) unless current_user?(@user) || (current_user.admin? && !first_user?(@user)) 
end 

def first_user?(user) 
    user==User.first 
end 

是否忽略的update_attributes我的before_filter?爲什麼不放?

回答

1

update_attributes不是一個請求,它是一個模型方法 - 過濾器在請求上下文之外沒有意義。

「put」是一個請求,所以過濾器運行。

+0

謝謝,我現在看到。我想我擔心攻擊者進入我的應用程序並運行update_attributes。那麼我必須在模型中找到防止這種情況的方法。稍後當我回到PC時,會接受這一點。再次感謝。 – stephenmurdoch

+0

@stephenmurdoch「Inside」你的應用程序? –

+0

@Dave_Newton我在這裏複雜的東西。我擔心有人可以通過命令行訪問我的應用程序(比如在我運行heroku控制檯時黑客入侵了我的電腦),可以修改第一個用戶(我的帳戶),並且可以通過禁用'update_attributes在那個記錄上。試圖做到這一點有什麼意義嗎?可以這樣做嗎?或者是否會讓具有這種訪問權限的攻擊者無法阻止? – stephenmurdoch