2017-06-19 38 views
0

我有Deviseomniauth寶石。我或多或少地遵循了用於多重身份驗證的railscast,因此擁有用戶和身份驗證模型。設計管理員編輯用戶失敗的密碼「不能爲空」。代碼到DB的可能級別有哪些可以阻止這種情況?

我已經設法讓用戶在沒有密碼的情況下更新他們自己的配置文件。

class RegistrationsController < Devise::RegistrationsController 
    def update_resource(resource, params) 
    if current_user.authentications.empty? 
     resource.update_with_password(account_update_params) 
    else 
     params.except("current_password") 
     resource.update_without_password(account_update_params) 
    end 
    end 
end 

的routes.rb

devise_for :users, :controllers => {registrations: 'registrations'}, path_prefix: 'my' 
resources :users 

用戶/ edit.html.haml

<%= bootstrap_form_for @user, html: {multipart: true} do |f| %> 
    ... 
<%= f.submit "Update" %> 

users_controller.rb

def update 
    @user = User.find(params[:id]) 

    Rails.logger.info(params.inspect) 
    if @user.update_without_password(account_update_params) 
    flash[:success] = "User updated by admin." 
    redirect_to @user 
    else 
    Rails.logger.info(@user.errors.inspect) 
    flash[:alert] = "User update by admin failed to save" 
    render 'edit' 
    end 

    private 
    def account_update_params 
    params.require(:user).permit(:email, :first_name, :last_name, :username, :dob,:city, :state, :zip, :password, :password_confirmation, :current_password) 
    end 

end 

user.rb

def update_without_password(params, *options) 
    params.delete(:password) 
    params.delete(:password_confirmation) 
    result = update_attributes(params, *options) 
    clean_up_passwords 
    result 
end 

日誌文件

Started GET "https://stackoverflow.com/users/2/edit" for 127.0.0.1 at 2017-06-18 19:45:01 -0400 
Processing by UsersController#edit as HTML 
    Parameters: {"id"=>"2"} 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] 
    Rendering users/edit.html.erb within layouts/application 
    Rendered users/edit.html.erb within layouts/application (12.6ms) 
    Rendered layouts/_shim.html.erb (0.3ms) 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] 
    Rendered layouts/_sidenav.html.erb (1.0ms) 
    Rendered layouts/_nav_top.html.erb (0.4ms) 
    Rendered layouts/_notice.html.erb (0.3ms) 
    Rendered layouts/_footer.html.erb (0.2ms) 
Completed 200 OK in 193ms (Views: 190.3ms | ActiveRecord: 0.3ms) 


Started PATCH "https://stackoverflow.com/users/2" for 127.0.0.1 at 2017-06-18 19:45:04 -0400 
Processing by UsersController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"SwkF8C+P6iExhc1ju91C9xFgaR5GSKwy8KFJUaBtHCTKzEXmPIKhaAFHlfMO+6u4/UOM0y2IAAIkpfTsuBOX6g==", "user"=>{"first_name"=>"Bobby", "last_name"=>"", "username"=>"", "dob"=>"", "gender"=>"", "address1"=>"", "address2"=>"", "state"=>"", "zip"=>"", "email"=>"[email protected]"}, "commit"=>"Update", "id"=>"2"} 
    User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] 
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"SwkF8C+P6iExhc1ju91C9xFgaR5GSKwy8KFJUaBtHCTKzEXmPIKhaAFHlfMO+6u4/UOM0y2IAAIkpfTsuBOX6g==", "user"=>{"first_name"=>"Bobby", "last_name"=>"", "username"=>"", "dob"=>"", "gender"=>"", "address1"=>"", "address2"=>"", "state"=>"", "zip"=>"", "email"=>"[email protected]"}, "commit"=>"Update", "controller"=>"users", "action"=>"update", "id"=>"2"} permitted: false> 
    (0.1ms) begin transaction 
    Authentication Exists (0.1ms) SELECT 1 AS one FROM "authentications" WHERE "authentications"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]] 
    Authentication Exists (0.0ms) SELECT 1 AS one FROM "authentications" WHERE "authentications"."user_id" = ? LIMIT ? [["user_id", 2], ["LIMIT", 1]] 
    (0.0ms) rollback transaction 
#<ActiveModel::Errors:0x007f9cf49d1758 @base=#<User id: 2, email: "[email protected]", created_at: "2017-06-18 16:05:51", updated_at: "2017-06-18 16:05:51", username: "", first_name: "Bobby", last_name: "", dob: nil, gender: "", address1: "", address2: "", city: nil, state: "", zip: "", admin: false, phone: nil>, @messages={:password=>["can't be blank"]}, @details={:password=>[{:error=>:blank}]}> 
    Rendering users/edit.html.erb within layouts/application 
    Rendered users/edit.html.erb within layouts/application (5.1ms) 
    Rendered layouts/_shim.html.erb (0.3ms) 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]] 
    Rendered layouts/_sidenav.html.erb (0.9ms) 
    Rendered layouts/_nav_top.html.erb (0.5ms) 
    Rendered layouts/_notice.html.erb (0.3ms) 
    Rendered layouts/_footer.html.erb (0.2ms) 
Completed 200 OK in 199ms (Views: 188.4ms | ActiveRecord: 0.7ms) 

@messages={:password=>["can't be blank"]指向答案的消息,但一切我試過之後再移除這個要求。我認爲Devise的update_without_password方法可以開箱即用。

我甚至在user.rb的頂端嘗試過這個。

validates :password, presence: true, length: {minimum: 5, maximum: 120}, on: :create 
validates :password, length: {minimum: 5, maximum: 120}, on: :update, allow_blank: true 

感謝您的幫助!

+0

當您嘗試從activeAdmin更新用戶配置文件時是否收到此錯誤消息? –

+0

我沒有activeAdmin設置。我在用戶模型上有一個Admin布爾值。只有當我的Admin嘗試更新用戶(通過users_controller.rb)時,纔會發生此錯誤,而不是用戶嘗試更新自己時(通過registrations_controller.rb)。 – sthoward

回答

0

查看您的UsersController。您在params上使用except,然後在條件中使用account_update_paramsexcept並不完全刪除Hash中的keyvalue

這是一個有用的SO答案,應該可以解決您的情況here

如果不幫助我會按照制定的關於如何實現這個現有的指南:

請務必遵循Devise指南允許用戶編輯自己的帳戶without providing a password。我不確定您在User模型中想要做什麼,您是否嘗試覆蓋Devise方法?

如果你想覆蓋Devise方法,你應該看看該方法本身:

def update_without_password(params, *options) 
    params.delete(:email) 
    super(params) 
end 

如果使用這種方法,你應該重寫此方法來保護其他屬性,你不會喜歡在沒有密碼的情況下更新。

更改RegistrationsController到匹配的文檔:

def update_resource(resource, params) 
    resource.update_without_password(params) 
end 

然後按照剩餘的兩個步驟,並確認您編輯的觀點和路線。

如果您需要進行任何更改認證,請務必更改update_resource方法。

+0

感謝您的幫助。我確實檢查了答案指向Devise wiki「如何:允許用戶編輯他們的賬戶而不提供密碼」。來自registrations_controller.rb的我的update_resource適用於用戶自行更新。我的問題是管理員通過users_controller.rb更新用戶。你對params.except的評論 - 我嘗試了一些,並會更新OP。 – sthoward

+0

爲什麼不在'UsersController'中使用'current_user.authentications.present?'? – jdgray

+0

current_user是管理員。正在編輯的@user是一個不同的實例。所以current_user有或沒有身份驗證對正在編輯的實例無關緊要。 – sthoward

相關問題