Принудительная проверка пустых паролей в Authlogic - PullRequest
5 голосов
/ 01 февраля 2010

Я добавляю функцию сброса пароля в мое приложение Rails, которое использует Authlogic. Я следовал этому руководству: http://www.binarylogic.com/2008/11/16/tutorial-reset-passwords-with-authlogic/ и все работает, как хотелось бы, за исключением одного: форма сброса пароля принимает пустые пароли и просто не меняет их.

Я искал вокруг и узнал, что это предполагаемое поведение по умолчанию, потому что оно позволяет вам создавать пользовательские формы редактирования, которые изменяют пароль пользователя, только если он вводит новый, и игнорируют его в противном случае. Но в этом случае я специально хочу обеспечить проверку пароля, как при первоначальной регистрации пользователя. Я нашел два возможных решения этой проблемы, но не смог выяснить, как реализовать любой из них.

1) Кто-то задавал этот же вопрос в группах Google:

Модель пользователя сохраняется с пустым паролем

Ответом Бена было использование @user.validate_password = true для принудительной проверки пароля. Я пробовал это, но я получаю неопределенную ошибку метода: undefined method 'validate_password_field=' for #<User>.

2) Кажется, есть опция конфигурации Authlogic под названием ignore_blank_passwords. Это задокументировано здесь:

Модуль: Authlogic :: ActsAsAuthentic :: Password :: Config # ignore_blank_passwords

Похоже, что это сработает, но, насколько я понимаю, это глобальная опция конфигурации, которую вы используете при первоначальном вызове acts_as_authentic в модели User, и я не хочу менять его во всем приложении, так как У меня есть обычная форма редактирования для пользователей, где я хочу, чтобы пустые пароли по умолчанию игнорировались.

Кто-нибудь нашел решение этой проблемы? Я вижу validate_password= в журнале изменений для Authlogic 1.4.1, и с тех пор ничего не было удалено. Я просто использую это неправильно? Есть ли способ использовать ignore_blank_passwords для каждого запроса?

Ответы [ 5 ]

8 голосов
/ 26 апреля 2010

Это старая ветка, но так как она не получила ответа, я выложу это.

Мне удалось сделать это немного более аккуратно, чем другие решения, «помогая» аутентификации с помощью моей собственной аутентификации.

Я добавил это пользователю:

class User < ActiveRecord::Base

  ...

  attr_writer :password_required

  validates_presence_of :password, :if => :password_required?

  def password_required?
    @password_required
  end

  ...
end

Вы можете уменьшить его до двух строк, сделав attr_accessor и используя :if => :password_required (без запроса), но я предпочитаю этот другой синтаксис со знаком запроса.

Тогда действие вашего контроллера может быть выполнено так:

def update
  @user.password = params[:user][:password]
  @user.password_confirmation = params[:user][: password_confirmation]
  @user.password_required = true

  if @user.save
    flash[:notice] = "Password successfully updated"
    redirect_to account_url
  else
    render :action => :edit
  end
end

Это будет иметь локальный эффект; на остальную часть приложения это не повлияет (если в других местах password_required не установлено значение true).

Надеюсь, это поможет.

5 голосов
/ 13 сентября 2010

Это то, что я сделал.

class User < ActiveRecord::Base
  attr_accessor :ignore_blank_passwords

  # object level attribute overrides the config level
  # attribute
  def ignore_blank_passwords?
    ignore_blank_passwords.nil? ? super : (ignore_blank_passwords == true)
  end
end

Теперь в вашем контроллере установите атрибут ignore_blank_passwords в значение false.

user.ignore_blank_passwords = false

Здесь вы работаете в рамках AuthLogic. Вам не нужно менять логику проверки.

2 голосов
/ 02 июля 2010
User.ignore_blank_passwords = false

Используйте модель, а не объект для установки этого свойства.

def update_passwords
  User.ignore_blank_passwords = false
  if @user.update_attributes(params[:user])
    ...
  end
  User.ignore_blank_passwords = true
end
1 голос
/ 04 марта 2010

Помимо решения Zetetic вы можете сделать это следующим образом:

def update
  @user.password = params[:user][:password]
  @user.password_confirmation = params[:user][: password_confirmation]

  if @user.changed? && @user.save
    flash[:notice] = "Password successfully updated"
    redirect_to account_url
  else
    render :action => :edit
  end
end

Вы в основном проверяете, изменил ли authlogic запись пользователя (чего не происходит, если пароль пуст). В блоке else вы можете проверить, был ли пароль пустым, и добавить соответствующее сообщение об ошибке в запись пользователя или отобразить флэш-сообщение.

1 голос
/ 01 февраля 2010

Может быть, проверить значение параметра в контроллере? (воздушный код):

def update
  @user.password = params[:user][:password]
  @user.password_confirmation = params[:user][: password_confirmation]
  if @user.password.blank?
    flash[:error] = "Password cannot be blank"
    render :action => :edit
    return
  end
  if @user.save
    flash[:notice] = "Password successfully updated"
    redirect_to account_url
  else
    render :action => :edit
  end
end
...