Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify some account reset classes #10740

Closed
wants to merge 4 commits into from

Conversation

zachmargolis
Copy link
Contributor

Removes:

  • AccountReset::FindPendingRequestForUser
  • AccountReset::CancelRequestForUser
  • AccountReset::NotifyUserOfRequestCancellation

There are still more single-method classes we could remove, but this seemed like a good start. After #10732 lands, that might make it easier to remove:

  • AccountReset::ValidateCancelToken
  • AccountReset::ValidateGrantedToken

And the others, maybe could reorganize those, but it would take a little more thinking

- Move logic to AccountResetRequest model
- Move logic into AccountResetRequest#cancel!
- Move logic into AccountResetRequest#cancel!
@zachmargolis zachmargolis requested a review from a team May 31, 2024 20:17
Comment on lines +44 to +59
def notify_user_via_email_of_account_reset_cancellation
user.confirmed_email_addresses.each do |email_address|
UserMailer.with(user: user, email_address: email_address).account_reset_cancel.
deliver_now_or_later
end
end

def notify_user_via_phone_of_account_reset_cancellation
MfaContext.new(user).phone_configurations.each do |phone_configuration|
phone = phone_configuration.phone
Telephony.send_account_reset_cancellation_notice(
to: phone,
country_code: Phonelib.parse(phone).country,
)
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love model classes that send emails and notify and stuff, but the Profile class already does that, so it's not new to our codebase

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there's a case there to at least keep the (a) service class for sending the notifications? I don't feel too strongly either way. Or to @monfresh's point, keeping one service class for canceling a pending request, but collapsing everything into it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping one service class is a good point

changelog: Internal, Source code, Unify related classes for account reset
).order(requested_at: :asc).first
end

def cancel!(now: Time.zone.now)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One potential issue with this being a public method on the model is that someone could cancel any Account Reset Request. Whereas before, it was clear that it only applies to the ones that were pending.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it could raise or short-circuit unless the request is pending?


def call(now: Time.zone.now)
account_reset_request.update!(cancelled_at: now)
NotifyUserOfRequestCancellation.new(user).call
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this was only used here, perhaps one way to reduce the amount of files you need to read to understand this is to pull in the notification into this class.

@aduth
Copy link
Member

aduth commented Jun 3, 2024

Looks like the build got caught up on an unnecessary allowed_extra_analytics. I think it's a valid failure, but not related to the changes here. Similar to #10617, I think there's some flakiness with how that new helper is identifying issues.

@@ -9,6 +11,24 @@ class AccountResetRequest < ApplicationRecord
primary_key: 'issuer'
# rubocop:enable Rails/InverseOf

# @return [AccountResetRequest, nil]
def self.pending_request_for(user)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious how we decide whether it makes sense for this method to live here or in the User model. I guess the upside of the latter is that it's a little more concise to do user.pending_account_reset_request vs. AccountResetRequest.pending_request_for(user), but perhaps at the risk of the User model becoming more bloated than it already is.

).order(requested_at: :asc).first
end

def cancel!(now: Time.zone.now)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it could raise or short-circuit unless the request is pending?

Comment on lines +44 to +59
def notify_user_via_email_of_account_reset_cancellation
user.confirmed_email_addresses.each do |email_address|
UserMailer.with(user: user, email_address: email_address).account_reset_cancel.
deliver_now_or_later
end
end

def notify_user_via_phone_of_account_reset_cancellation
MfaContext.new(user).phone_configurations.each do |phone_configuration|
phone = phone_configuration.phone
Telephony.send_account_reset_cancellation_notice(
to: phone,
country_code: Phonelib.parse(phone).country,
)
end
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there's a case there to at least keep the (a) service class for sending the notifications? I don't feel too strongly either way. Or to @monfresh's point, keeping one service class for canceling a pending request, but collapsing everything into it.

@zachmargolis
Copy link
Contributor Author

I think I'm going to need to come back to this with single account reset service, will close in the meantime

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants