FIX: When admin changes an email for the user the user must confirm the change (#10830)

See https://meta.discourse.org/t/changing-a-users-email/164512 for additional context.

Previously when an admin user changed a user's email we assumed that they would need a password reset too because they likely did not have access to their account. This proved to be incorrect, as there are other reasons a user needs admin to change their email. This PR:

* Changes the admin change email for user flow so the user is sent an email to confirm the change
* We now record who the email change request was requested by
* If the requested by user is admin and not the user we note this in the email sent to the user
* We also make the confirm change email route open to anonymous users, so it can be clicked by the user even if they do not have access to their account. If there is a logged in user we make sure the confirmation matches the current user.
This commit is contained in:
Martin Brennan
2020-10-07 13:02:24 +10:00
committed by GitHub
parent 3303b7f9d0
commit 6e2be3e60b
14 changed files with 155 additions and 62 deletions

View File

@ -4,6 +4,7 @@ class EmailChangeRequest < ActiveRecord::Base
belongs_to :old_email_token, class_name: 'EmailToken'
belongs_to :new_email_token, class_name: 'EmailToken'
belongs_to :user
belongs_to :requested_by, class_name: "User", foreign_key: :requested_by_user_id
validates :new_email, presence: true, format: { with: EmailValidator.email_regex }
@ -11,23 +12,38 @@ class EmailChangeRequest < ActiveRecord::Base
@states ||= Enum.new(authorizing_old: 1, authorizing_new: 2, complete: 3)
end
def requested_by_admin?
self.requested_by.admin? && !self.requested_by_self?
end
def requested_by_self?
self.requested_by_user_id == self.user_id
end
def self.find_by_new_token(token)
joins(
"INNER JOIN email_tokens ON email_tokens.id = email_change_requests.new_email_token_id"
).where("email_tokens.token = ?", token).last
end
end
# == Schema Information
#
# Table name: email_change_requests
#
# id :integer not null, primary key
# user_id :integer not null
# old_email :string
# new_email :string not null
# old_email_token_id :integer
# new_email_token_id :integer
# change_state :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# id :integer not null, primary key
# user_id :integer not null
# old_email :string
# new_email :string not null
# old_email_token_id :integer
# new_email_token_id :integer
# change_state :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# requested_by_user_id :integer
#
# Indexes
#
# index_email_change_requests_on_user_id (user_id)
# idx_email_change_requests_on_requested_by (requested_by_user_id)
# index_email_change_requests_on_user_id (user_id)
#