Skip to content

fix: always attempt external auth refresh when fetching #11762

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

Merged
merged 9 commits into from
Jan 25, 2024

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Jan 22, 2024

What this does

Refactors the external auth code to:

  • Always attempt to refresh when workspace agent fetches auth links. The agent uses this endpoint.
  • ValidateToken takes into account Expirary information.

Comment on lines +186 to +188
if !link.Expiry.IsZero() && link.Expiry.Before(dbtime.Now()) {
return false, nil, nil
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Expired tokens should return invalid

@@ -2030,78 +2030,25 @@ func (api *API) workspaceAgentsExternalAuth(rw http.ResponseWriter, r *http.Requ
return
}

if listen {
Copy link
Member Author

Choose a reason for hiding this comment

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

I hope my new flow is a bit easier to understand.

Basically there is 2 flows, listen and not listen. If listen is set to true, then the http handler will block until a valid auth token is found (this should probably be a websocket or something else idk).

Before listen and not listen did not share any code, which is dumb because on a success, their code paths should be identical. So this refactor makes the two cases share the same code execution path when a valid auth token is found.

@Emyrk Emyrk requested a review from johnstcn January 23, 2024 17:56
Copy link
Member

@johnstcn johnstcn left a comment

Choose a reason for hiding this comment

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

The change makes sense to me overall. Just need to make the tests pass.

@Emyrk Emyrk force-pushed the stevenmasley/external_auth_refresh branch from e998ccb to 189c8ae Compare January 24, 2024 20:17
@Emyrk Emyrk requested a review from johnstcn January 24, 2024 22:55
Comment on lines +2087 to 2094
if !valid {
// Set the previous token so the retry logic will skip validating the
// same token again. This should only be set if the token is invalid and there
// was no error. If it is invalid because of an error, then we should recheck.
previousToken = &externalAuthLink
handleRetrying(http.StatusOK, agentsdk.ExternalAuthResponse{
URL: redirectURL.String(),
})
Copy link
Member Author

Choose a reason for hiding this comment

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

Had to do this to prevent re-validating the same token after the refresh attempt

Comment on lines +406 to +410
// If expiresIn is 0, then the token never expires.
expires := dbtime.Now().Add(time.Duration(body.ExpiresIn) * time.Second)
if body.ExpiresIn == 0 {
expires = time.Time{}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This was another bug I found. If zero time was passed in, the token was considered immediately expired on our end.

Copy link
Member

Choose a reason for hiding this comment

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

That's probably a big one. IIRC GitHub often just gives you tokens with no expiry.

@Emyrk
Copy link
Member Author

Emyrk commented Jan 24, 2024

@johnstcn got it all passing

Copy link
Member

@johnstcn johnstcn left a comment

Choose a reason for hiding this comment

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

LGTM, some comments

Comment on lines 1626 to 1630
// We expect only 2. One from the initial "Refresh" attempt, and
// another from the first tick. Ideally this would be just one.
// In a failed test, you will likely see 9, as the last one
// gets canceled.
require.Equal(t, 1, validateCalls, "validate calls duplicated on same token")
Copy link
Member

Choose a reason for hiding this comment

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

Comment does not agree with below require.Equal -- do we only expect 1 or 2?

Copy link
Member Author

Choose a reason for hiding this comment

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

I forgot to commit my comment diff 🤦.

It was two, then I decided to fix it and make it 1, since lower == better.

Screenshot from 2024-01-25 10-15-15

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed the typo...

Comment on lines +406 to +410
// If expiresIn is 0, then the token never expires.
expires := dbtime.Now().Add(time.Duration(body.ExpiresIn) * time.Second)
if body.ExpiresIn == 0 {
expires = time.Time{}
}
Copy link
Member

Choose a reason for hiding this comment

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

That's probably a big one. IIRC GitHub often just gives you tokens with no expiry.

@Emyrk
Copy link
Member Author

Emyrk commented Jan 25, 2024

That's probably a big one. IIRC GitHub often just gives you tokens with no expiry.

They do in the regular oauth flow for sure. I would guess this would be a big issue, but if it was, then wouldn't it break spectacularly?? So maybe in the device flow method there is an expiry 🤔

@Emyrk Emyrk merged commit 0befc08 into main Jan 25, 2024
@Emyrk Emyrk deleted the stevenmasley/external_auth_refresh branch January 25, 2024 16:54
@github-actions github-actions bot locked and limited conversation to collaborators Jan 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants