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

feat: Auto-refresh github token #3185

Merged
merged 11 commits into from
Apr 17, 2024
Merged

feat: Auto-refresh github token #3185

merged 11 commits into from
Apr 17, 2024

Conversation

bryanhuhta
Copy link
Contributor

@bryanhuhta bryanhuhta commented Apr 9, 2024

related: https://github.com/grafana/pyroscope-squad/issues/129
related: https://github.com/grafana/pyroscope-app-plugin/pull/392

When we go through the OAuth login flow with GitHub, GitHub sends us a use token and a refresh token. The user token expires in 8 hours and the refresh token expires in 6 months. Both tokens are encrypted into cookie the GitHubLogin endpoint send back to the UI.

This PR introduces mechanisms for the UI to request a new user token. To do so, I created a new endpoint /vcs.v1.VCSService/GithubRefresh which will use the refresh token to get a new user token.

@bryanhuhta bryanhuhta self-assigned this Apr 9, 2024
Comment on lines -19 to -43
var (
GithubAppClientID = os.Getenv("GITHUB_CLIENT_ID")
githubAppClientSecret = os.Getenv("GITHUB_CLIENT_SECRET")
githubSessionSecret = []byte(os.Getenv("GITHUB_SESSION_SECRET"))
)

const (
gitHubCookieName = "GitSession"
)

// githubOAuth returns a github oauth2 config.
// Returns an error if the environment variables are not set.
func githubOAuth() (*oauth2.Config, error) {
if GithubAppClientID == "" {
return nil, errors.New("missing GITHUB_CLIENT_ID environment variable")
}
if githubAppClientSecret == "" {
return nil, errors.New("missing GITHUB_CLIENT_SECRET environment variable")
}
return &oauth2.Config{
ClientID: GithubAppClientID,
ClientSecret: githubAppClientSecret,
Endpoint: o2endpoints.GitHub,
}, nil
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of this OAuth stuff got abstracted to token.go

Comment on lines +43 to +44
q.logger.Log("err", err, "msg", "failed to get GitHub OAuth config")
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to authorize with GitHub"))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This pattern of "log the real error, return a generic message" is so we don't accidentally leak anything sensitive to the UI. While errors won't include tokens or any really sensitive info, better to be on the safe side with what we send back to the client.

Comment on lines +97 to +100
err = rejectExpiredToken(token)
if err != nil {
return nil, err
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can check if the token is expired without having to talk to GitHub.

@bryanhuhta bryanhuhta marked this pull request as ready for review April 16, 2024 23:16
@bryanhuhta bryanhuhta requested review from a team as code owners April 16, 2024 23:16
Copy link
Contributor

@cyriltovena cyriltovena left a comment

Choose a reason for hiding this comment

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

LGTM

@bryanhuhta bryanhuhta merged commit 677729d into main Apr 17, 2024
16 checks passed
@bryanhuhta bryanhuhta deleted the gh-token-refresh branch April 17, 2024 20:04
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

2 participants