mirror of
https://github.com/safedep/vet.git
synced 2025-12-11 09:25:44 -06:00
103 lines
2.9 KiB
Go
103 lines
2.9 KiB
Go
package connect
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gofri/go-github-ratelimit/github_ratelimit"
|
|
"github.com/google/go-github/v54/github"
|
|
"github.com/safedep/dry/utils"
|
|
"github.com/safedep/vet/pkg/common/logger"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
const (
|
|
// We are storing the Github oauth2 client ID here. While this may not be
|
|
// the best way to store client id, this does not introduce any risk because
|
|
// it cannot be used for any authentication by itself
|
|
githubOAuth2ClientId = "9b535a30e967c5d4e2ca"
|
|
githubOAuth2ClientIdEnvKey = "VET_GITHUB_CLIENT_ID"
|
|
)
|
|
|
|
func PersistGithubAccessToken(token string) error {
|
|
return updateConfig(func(c *Config) {
|
|
c.GithubAccessToken = token
|
|
})
|
|
}
|
|
|
|
func GetGithubOAuth2ClientId() string {
|
|
clientID := strings.ToLower(os.Getenv(githubOAuth2ClientIdEnvKey))
|
|
if !utils.IsEmptyString(clientID) {
|
|
return clientID
|
|
}
|
|
|
|
return githubOAuth2ClientId
|
|
}
|
|
|
|
func GetGithubClient() (*github.Client, error) {
|
|
github_token := os.Getenv("GITHUB_TOKEN")
|
|
if !utils.IsEmptyString(github_token) {
|
|
logger.Debugf("Found GITHUB_TOKEN env variable, using it to access Github.")
|
|
} else {
|
|
github_token = globalConfig.GithubAccessToken
|
|
}
|
|
|
|
if utils.IsEmptyString(github_token) {
|
|
rateLimitedClient, err := githubRateLimitedClient(http.DefaultTransport)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger.Debugf("Creating a Github client without credential")
|
|
return github.NewClient(rateLimitedClient), nil
|
|
}
|
|
|
|
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{
|
|
AccessToken: github_token,
|
|
})
|
|
|
|
baseClient := oauth2.NewClient(context.Background(), tokenSource)
|
|
rateLimitedClient, err := githubRateLimitedClient(baseClient.Transport)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
logger.Debugf("Created a new Github client with credential")
|
|
return github.NewClient(rateLimitedClient), nil
|
|
}
|
|
|
|
// This is currently effective only for Github secondary rate limits
|
|
// https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api
|
|
func githubRateLimitedClient(transport http.RoundTripper) (*http.Client, error) {
|
|
var options []github_ratelimit.Option
|
|
|
|
if !githubClientRateLimitBlockDisabled() {
|
|
logger.Debugf("Adding Github rate limit callbacks to client")
|
|
|
|
options = append(options, github_ratelimit.WithLimitDetectedCallback(func(cc *github_ratelimit.CallbackContext) {
|
|
logger.Infof("Github rate limit detected, sleep until: %s", cc.SleepUntil)
|
|
}))
|
|
}
|
|
|
|
rateLimitedClient, err := github_ratelimit.NewRateLimitWaiterClient(transport, options...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return rateLimitedClient, err
|
|
}
|
|
|
|
// We implement this as an internal feature i.e. without a config or an UI option because
|
|
// we want this to be the default behaviour *always* unless user want to explicitly disable it
|
|
func githubClientRateLimitBlockDisabled() bool {
|
|
ret, err := strconv.ParseBool(os.Getenv("VET_GITHUB_DISABLE_RATE_LIMIT_BLOCKING"))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return ret
|
|
}
|