Обновление пользователя без хеширования дважды пароля

Моя модель:

class User < Sequel::Model
self.raise_on_save_failure = false
plugin :validation_helpers
def validate
    super
    validates_format /@/, :email
    validates_presence [:email, :password]
    validates_unique :email
end

def before_save
    super
    self[:password] = BCrypt::Password.create(self[:password])
end

конец

Но когда я обновляю пользователя, мой пароль хэшируется дважды. Я знаю, что это из-за before_save крюк, но я хочу сохранить sequel проверка действительного пароля(validates_presence), а не результата хеширования bcrypt (причина BCrypt::Password.create('') не пусто)

Так что мне нужно как-то сделать следующее:

  1. проверьте, изменился ли пароль
  2. подтвердить реальный пароль sequel
  3. сохранить bcrypt хэш моего пароля

2 ответа

Решение

Я думаю, что вы должны пересмотреть свой рабочий процесс. Если вы хотите, чтобы неверный ввод обнаруживался только при попытке обновить БД, почему бы не пойти примерно так:

post '/update' do
  ...

  if params[:password] == nil || params[:password].empty?
    password = nil
  else
    password = BCrypt::Password.create(params[:password])
  end

  # I have no idea how this line should really look like in your code
  User.find(param[:id]).set(:password, password)

  ...
end

Таким образом, в основном, дайте ему ноль, если поле пароля не было отправлено или пусто.

РЕДАКТИРОВАТЬ

Как ясно сказано в комментариях Иаина:

[...] вы должны использовать Sequel только для проверки данных, которые хранятся или будут храниться в базе данных. Настоящий пароль должен быть проверен уровнем бизнес-логики, что и происходит в этом ответе.

Вы можете проверить это в методе класса следующим образом:

  if user.password_digest != expected_password
    user = nil
  end
Другие вопросы по тегам