Skip to content

#valid_password? returns false when updating resource with empty password fields #5038

@codeminator

Description

@codeminator

Environment

  • Ruby 2.4.4
  • Rails 5.2.2
  • Devise 4.6.1

Description

In prior versions of devise (I tested with v.4.4.2 since, it's the earliest version compatible with Rails ~> 5.2), it was possible to call update statement on a resource with some fields, while submitting password and password_confirmation fields as empty strings, and still old password is valid:

> pw = 'thisIsPassword'
> user.update(password: pw, password_confirmation: pw)
User Update (7.5ms)  UPDATE `users` SET `updated_at` = '2019-03-07 10:18:45', `encrypted_password` = '$2a$10$mh8fvYDEujHZrDIAPao8k.rj.EweEwT/uf4i/Ax71d0oSMYYtvUHe' WHERE `users`.`id` = 5
   (1.4ms)  COMMIT
=> true
> user.valid_password?(pw)
=> true
user.update(email: "another_email@mail.com", password: "", password_confirmation: "")
   (0.4ms)  BEGIN
  User Update (0.7ms)  UPDATE `users` SET `email` = 'another_email@mail.com', `updated_at` = '2019-03-07 10:19:40' WHERE `users`.`id` = 5
   (3.9ms)  COMMIT
=> true
> user.valid_password?(pw)
=> true

While in v.4.6.1 (the latest), #valid_password? returns false when doing the same steps (Basically, it sets encrypted-password column with NULL):

> pw = 'thisIsPasswordTest'
=> "thisIsPasswordTest"
> user.update(password: pw, password_confirmation: pw)
   (0.2ms)  BEGIN
  User Update (0.5ms)  UPDATE `users` SET `updated_at` = '2019-03-07 10:21:57', `encrypted_password` = '$2a$10$uRBpZWVLF2epl3J.apIiZ.KdQ9hFM0Qmn53hMpmNNgvUccCyjmPnq' WHERE `users`.`id` = 5
   (2.0ms)  COMMIT
=> true
> user.valid_password?(pw)
=> true
> user.update(email: "another_email_updated@test.com", password: "", password_confirmation: "")
   (0.2ms)  BEGIN
  User Update (0.4ms)  UPDATE `users` SET `email` = 'another_email_updated@test.com', `updated_at` = '2019-03-07 10:23:13', `encrypted_password` = NULL WHERE `users`.`id` = 5
   (0.5ms)  COMMIT
=> true
[6] pry(main)> user.valid_password?(pw)
=> false

Current behavior

valid_password? with old password returns false when password/password_confirmation fields have been submitted as empty strings within #update call.

Expected behavior

valid_password? with old password returns true password/password_confirmation fields have been submitted as empty strings within #update call (older versions are working that way).

I know that we have already methods such as update_without_password and update_with_password. The question is what if you have a large app, that is updating user information from a form or something that contains password fields, then you have to either edit the code to check the presence of password/password_confirmation params, or change the user experience.

If it's intended behaviour, kindly clarify.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions