-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Add client.WithClient method #3004
Comments
Thank you, @ashi009 . |
This is what we have today: // NewAppTokenHTTPClient creates a new http client that performs requests
// authenticated as a GitHub App.
func NewAppTokenHTTPClient(ctx context.Context, privateKeyPEM []byte, appID int64) (*http.Client, error) {
...
return oauth2.NewClient(ctx, oauth2.ReuseTokenSource(nil, ts)), nil
}
// NewAppInstallationTokenHTTPClient creates a new http client that performs requests
// authenticated as a GitHub App installation. gc must be a GitHub client authenticated
// as a GitHub App.
func NewAppInstallationTokenHTTPClient(ctx context.Context, gc *github.Client, installationID int64) (*http.Client, error) {
...
return oauth2.NewClient(ctx, oauth2.ReuseTokenSource(nil, ts)), nil
}
func main() {
ctx := context.Background()
ahc, _ := NewAppTokenHTTPClient(ctx, ...)
agc := github.NewClient(ahc).WithEnterpriseURLs(..., ...)
// the following might be in another file/struct, say, handling webhook requests, which sees nothing but the `agc`
aihc, _ := NewAppInstallationTokenHTTPClient(ctx, agc, ...)
aigc := github.NewClient(aihc).WithEnterpriseURLs(..., ...)
// If I need to use user credential, I'll need to do this all over again.
ugc := github.NewClient(uhc).WithEnterpriseURLs(..., ...)
} It will be much cleaner to do: func main() {
...
aigc := agc.WithClient(aihc)
ugc := agc.WithClient(uhc)
} I was also thinking about using ctx to carry the optional token source, which will make the code even cleaner. Then I realized that the current |
Thank you, @ashi009 for the extra details! This would be a great PR for any new contributor to this repo or a new Go developer. Feel free to volunteer for any issue and the issue can be assigned to you so that others don't attempt to duplicate the work. Please check out our CONTRIBUTING.md guide to get started. (In particular, please remember to Thank you! |
My understanding is that go-github is removing deps in recent releases. It would be super nice to include gh app cred support, instead of relying on ghinstallation (no offense). To be honest, ghinstallation builds on the go-github api, which means if not using the correct version, people will end up bundling 2 versions in the final binary... |
I considered adding This wouldn't be an issue for your use case because you wouldn't expect the auth header to be there after replacing the client with another one that handles auth. However, if Before adding |
For the record, I personally have no experience working with |
@gmlewis I'm not sure this will make a good first issue considering the compatibility issues I mentioned above. |
Sorry for the misunderstanding. I saw #2895 and #2914 in the recent changes. So I assume adding But it's definitely a good idea to create another issue to cover the gh app auth mania. A bunch of APIs requires that to work, e.g. checks API. So It's probably a good idea to have a full story supporting those use-cases. |
I think I have something that will work for this. We could add Here's a function that uses token auth as well as authenticating as both an app and an installation. func listAppRepos(ctx context.Context, gheURL, gheUploadURL, authToken, appSlug string, key []byte) ([]string, error) {
client, err := github.NewClient(nil).WithEnterpriseURLs(gheURL, gheUploadURL)
if err != nil {
return nil, err
}
client = client.WithAuthToken(authToken)
app, _, err := client.Apps.Get(ctx, appSlug)
if err != nil {
return nil, err
}
appsTransport, err := ghinstallation.NewAppsTransport(http.DefaultTransport, app.GetID(), key)
if err != nil {
return nil, err
}
client = client.WithRoundTripper(appsTransport)
installations, _, err := client.Apps.ListInstallations(ctx, nil)
if err != nil {
return nil, err
}
var result []string
var repos *github.ListRepositories
for _, inst := range installations {
client = client.WithRoundTripper(ghinstallation.NewFromAppsTransport(appsTransport, inst.GetID()))
repos, _, err = client.Apps.ListRepos(ctx, nil)
if err != nil {
return nil, err
}
for _, repo := range repos.Repositories {
result = append(result, repo.GetFullName())
}
}
return result, nil
} |
I would like to work on this PR |
Thank you, @WillAbides ! It's yours. |
When authenticating with github app creds, we need to attach a tokensource to the
http.Client
, and provide it to thegithub.NewClient
. However, a github app needs to switch between app cred, app install cred and perhaps user cred. Which means we need to callgithub.NewClient
repeatedly with differenthttp.Client
when switching between creds.This is very painful when using github enterprise, as we need a follow up call
c.WithEnterpriseURLs
at each callsite. It would be nice if we can add a method to do the necessary config copying when just changing the underlyinghttp.Client
.The text was updated successfully, but these errors were encountered: