[NPQ-3490] - store long lived auth token#3317
Conversation
|
Review app deployed to https://npq-registration-review-3317-web.test.teacherservices.cloud/ |
fd8ba6c to
01efa4e
Compare
895d923 to
0ef27e0
Compare
0ef27e0 to
345820b
Compare
03ae5b4 to
ed6c714
Compare
82ceb3c to
65339ad
Compare
2c04143 to
8050cbe
Compare
8050cbe to
c4768b8
Compare
c4768b8 to
a94bdb2
Compare
|
Review app for PR 3317 was deleted |
a94bdb2 to
187968b
Compare
jebw
left a comment
There was a problem hiding this comment.
Looks good - I've a few comments on changes - can you review them then ping me when you're ready for a catch up, thanks
| let(:older_statement_output_fee_true) { create(:statement, cohort: older_cohort, lead_provider:, output_fee: true, for_date: 3.months.ago) } | ||
| let(:older_statement_output_fee_false) { create(:statement, cohort: older_cohort, lead_provider:, output_fee: false, for_date: 2.months.ago) } | ||
| let(:latest_statement_output_fee_true) { create(:statement, cohort: older_cohort, lead_provider:, output_fee: true, for_date: 1.month.ago) } | ||
| let(:latest_statement_output_fee_false) { create(:statement, cohort: older_cohort, lead_provider:, output_fee: false, for_date: 0.months.ago) } | ||
| let(:future_statement_output_fee_true) { create(:statement, cohort: older_cohort, lead_provider:, output_fee: true, for_date: 1.month.from_now) } |
There was a problem hiding this comment.
This shouldn't be here - this reverts Alkesh' recent fix for a flaky spec
| it "does not enqueue a RefreshUserTokenJob" do | ||
| expect { subject }.not_to have_enqueued_job(RefreshUserTokenJob) | ||
| end | ||
| end |
There was a problem hiding this comment.
Can you add a spec here to check sentry was alerted that we didn't get a refresh token back for some reason
There was a problem hiding this comment.
Think you'll also need to change it to alert sentry
|
|
||
| new_refresh_token_assigned = false | ||
| user = nil | ||
| Rails.logger.info("[HELLO4] Create user with provider data") |
There was a problem hiding this comment.
Removed leftover logging
| headers: { "Content-Type" => "application/x-www-form-urlencoded" }, | ||
| ) | ||
|
|
||
| response.parsed_response["refresh_token"] || @refresh_token |
There was a problem hiding this comment.
This makes no sense - if the API returned a success resposnse, then @refresh_token is now used up and cannot be resused again so returning it will lead to the application incorrectly updating with an expired token
| application.update!(lead_provider_approval_status: "rejected", reason_for_rejection:) | ||
| ApplicationRecord.transaction do | ||
| application.update!(lead_provider_approval_status: "rejected", reason_for_rejection:) | ||
| clear_refresh_token_if_orphaned |
There was a problem hiding this comment.
Orphaned isn't a term we're using so may lead to confusion for other developers - how about clear_refresh_token_if_no_remaining_applications!
| class RefreshAccessToken | ||
| include HTTParty | ||
|
|
||
| default_timeout 5.seconds |
There was a problem hiding this comment.
Given this will be getting called from a Job I think we can give this longer to respond - say 15.seconds
| new_refresh_token_assigned = persist_refresh_token(user_matched_using_trn, provider_data) | ||
| end | ||
|
|
||
| schedule_refresh(user_matched_using_trn) if new_refresh_token_assigned |
There was a problem hiding this comment.
This shouldn't be needed if we're using an hourly job
| def schedule_refresh(user) | ||
| RefreshUserTokenJob.set(wait: 7.days).perform_later(user.id) | ||
| end |
| @@ -3,6 +3,7 @@ | |||
| module Users | |||
| class FindOrCreateFromTeacherAuth | |||
There was a problem hiding this comment.
The call method in this class are getting very complicated and its because there are multiple places all trying to do the same 'after sorting user out' action of persisting the token.
I can see 2 approaches
- Move the
persist the tokenout to the omniauth controller (with some helper code on the token class) - this logic is orthogonal to signing the user in.
@user = Users::FindOrCreateFromTeacherAuth
if @user
@user.set_refresh_token(provider_data.credentials&.fetch(:token)) if @user.trn.blank?
# ....
end- Or alternatively, add a level of indirection within this class - move the existing
#callmethod to be a differently named private method, egsign_in_useror similar since that always returns a user class. Then add a new#callmethod with something like the following
def call
sign_in_user(...).tap do |user|
set_refresh_token_on_user(user) if user && user.trn.blank?
end
end| create_table :user_refresh_tokens do |t| | ||
| t.references :user, null: false, foreign_key: true, index: { unique: true } | ||
| t.text :refresh_token, null: false | ||
| t.datetime :refresh_token_updated_at, null: false | ||
| t.timestamps | ||
| end |
There was a problem hiding this comment.
Could do with a chat around the schema on this
jebw
left a comment
There was a problem hiding this comment.
See responses in earlier approval (I'd meant to just comment rather than approve so I've dismissed that one)
| token_record.update!(refresh_token: new_refresh_token, refresh_token_updated_at: Time.current) | ||
| rescue StandardError => e | ||
| Sentry.capture_exception(e, extra: { user_id: }) | ||
| raise |
There was a problem hiding this comment.
This shouldn't re-raise otherwise you'll end up with a thundering herd problem when you chain jobs
- 9am - Enqueue job kicks of 1000 api jobs
- they fail because endpoint is unavailable
- those 1000 jobs reschedule themselves
- and keep rescheduling them selves with increasing backoff
- meanwhile at 10am - Enqueue job kicks off the same 1000 api jobs for a second time
- and so the loop continues
187968b to
900ec36
Compare
900ec36 to
618c5a0
Compare
|



Context
Ticket: https://dfedigital.atlassian.net/browse/NPQ-3490
Changes proposed in this pull request