Bug 2060541 - Recheck auth status on startup, weekly - #7564
Conversation
|
I have been thinking a fair amount about the part of this patch that I'm the least sure about: the part in |
|
I ended up not putting the logic to reset the auth timer in |
bendk
left a comment
There was a problem hiding this comment.
This is looking very good. Thanks for updating the example client.
I had a couple suggestions, but the only blocker is figuring out how we should store the refresh token when we're in the auth-issues state.
| last_seen_profile: None, | ||
| access_token_cache: HashMap::new(), | ||
| logged_out_from_auth_issues: false, | ||
| last_auth_recheck_time: None, |
There was a problem hiding this comment.
I see your point about resetting this timer and the Unititialized -> AuthIssues transition. My one idea here is to rename this to last_auth_check_time and set it in whenever check_authorization_status() is called (or maybe just whenever it fails?). I think that might give you the timer you need without the having to call reset_auth_recheck_timer in so many places. However, I'm not sure and I'm okay with the repetition if that's what we need to do. However you want to handle this is fine with me.
There was a problem hiding this comment.
My concern with this solution is that there are other ways that we can get into the AuthIssues state. Here, for example. With the proposed design, that line (and several others) would put us into the AuthIssues state and then we would re-check on the very next initialization. I assume that this isn't really the behavior that we want.
There was a problem hiding this comment.
I suspect that the those cases are buggy and we should fix those. For example, I think we should just get rid of the CallGetProfile event. Can you make a list of the other cases where you think there could be an issue? I'd love to go through them.
In the meantime, maybe we should just leave this code as-is. I don't want block this PR on figuring all that out.
There was a problem hiding this comment.
Aside from the one listed above, there is:
- This one where we initialize into the
Connectedstate, butaccount.finish_initializefails. - This one where we get the
WebChannelPasswordChangeevent from theConnectedstate andhandle_web_channel_password_changefails. - This one where we are in the
AuthIssuesstate, get theBeginOAuthFlowevent, andbegin_oauth_flowfails. - This one where we are in the
AuthIssuesstate, get theWebChannelPasswordChangeevent, andhandle_web_channel_password_changefails.
There was a problem hiding this comment.
Another possibility here is that we could just accept the behavior of doing one check on the very next initialization after the AuthIssues transition. That would simplify the code a bit since we would only reset the timer in one place. And if we did somehow end up in a situation where someone was frequently getting into that state, it would fix itself quickly instead of fixing itself once a week.
There was a problem hiding this comment.
I think an extra check wouldn't be the worst if we had to do it, but hopefully we can avoid it. I made https://bugzilla.mozilla.org/show_bug.cgi?id=2070265 and added some comments there.
The pull request has been modified, dismissing previous reviews.
| // This probably indicates that the user is not authorized but there are various | ||
| // corner cases where we might have gotten something wrong. For example, a bug in an | ||
| // older browser version that we've since fixed or an FxA server bug. | ||
| // Because of this, we will recheck the authorization status from time to time. |
There was a problem hiding this comment.
This patch looks nice to me!
But I think the comment about an fxa server bug is wishful thinking (eg, desktop has never done this and there's never been evidence it should), and even "old browser versions" is slightly wishful thinking - we fixed one such case just weeks ago :) I'm really more worried about remaining bugs!
ie, tbh I don't see this patch as an "improvement", but more as a "mitigation" - I fully expect this to never work once we've nailed the bugs. So I think it makes sense to have another issue be opened for recording telemetry here so we can witness it hit zero times it actually recovered and then remove this code? Happy to leave the formal review to Ben though.
There was a problem hiding this comment.
Good point. I think a lot of the bugs had to do with the way the old fxa code was structured, so there's good reason to believe that we'll actually fix the bugs for good at some point. That said, I don't see much downside to keeping it around either. I'm happy to go either way on this one.
There was a problem hiding this comment.
yeah, that's a future consideration, but I do like the idea of telemetry in the shorter term?
bendk
left a comment
There was a problem hiding this comment.
The changes look great. The last part is updating the methods I noted so that they continue to throw a NoRefreshToken error if logged_out_from_auth_issues=true.
| pub(crate) server_local_device_info: Option<LocalDevice>, | ||
| #[serde(default)] | ||
| pub(crate) logged_out_from_auth_issues: bool, | ||
| pub(crate) last_auth_recheck_time: Option<u64>, |
There was a problem hiding this comment.
Nano-nit: should this just be called last_auth_check_time? I think it's set on the initial auth check failure, not on the first recheck failure.
| if self.persisted_state.logged_out_from_auth_issues { | ||
| FxaRustAuthState::AuthIssues | ||
| } else if self.persisted_state.refresh_token.is_some() { | ||
| FxaRustAuthState::Connected |
There was a problem hiding this comment.
This change looks good, the other places that may need to be changed are functions that we expose to the consumer that read the refresh token. If the application calls those, we'll now use the old refresh token even though it may be bad, whereas before they would fail with a NoRefreshToken error. I noticed these methods:
- has_scope()
- update_device()
- fetch_and_parse_commands()
- invoke_command()
- get_command_for_index()
I'm not sure if we should change those methods or not. However, I think it's better to keep the behavior similar to how it was before. I guess NoRefreshToken is not the right error anymore, but it seems okay to continue to use it since it will end up as an Authentication error by the time it gets to the application which seems right. We can fix this in a follow-up.
Like I said, I'm not totally sure about this, what do you think @bytesized @mhammond ?
There was a problem hiding this comment.
nice catch - I think NoRefreshToken seems fine even if now it means NoValidRefreshToken :) I think the simplest would be to have pub fn refresh_token(&self) -> Option<&RefreshToken> check the auth status and return None if in that state?
There was a problem hiding this comment.
(hrm, which might mean we need a new method for check_authorization_status() to use, but given a suitable long name that seems ok)
Pull Request checklist
cargo testsucceeds locally.cargo fxa force-auth-issuescommand to the example CLI client in order to be able to test this manually.