Files
trufflehog/pkg/sources/github/connector_app.go
Kashif Khan 92e9157267 Github and Gitlab Authentication via http.extraHeader for cloning Repositories (#4139)
* initial code changes

* move args before clone command

* add comments

* added flag for github source to support backward compatibility

* added flag for gitlab source to support backward compatibility

* inverse the logic for enterprise

* remove print statement

* remove flag defaults

* updated comments and removed CloneRepoUsingTokenInHeader function

* false->true
2025-05-27 11:24:43 +05:00

97 lines
2.9 KiB
Go

package github
import (
"fmt"
"strconv"
"github.com/bradleyfalzon/ghinstallation/v2"
gogit "github.com/go-git/go-git/v5"
"github.com/google/go-github/v67/github"
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/credentialspb"
"github.com/trufflesecurity/trufflehog/v3/pkg/sources/git"
)
type appConnector struct {
apiClient *github.Client
installationClient *github.Client
installationID int64
}
var _ Connector = (*appConnector)(nil)
func NewAppConnector(apiEndpoint string, app *credentialspb.GitHubApp) (Connector, error) {
installationID, err := strconv.ParseInt(app.InstallationId, 10, 64)
if err != nil {
return nil, fmt.Errorf("could not parse app installation ID %q: %w", app.InstallationId, err)
}
appID, err := strconv.ParseInt(app.AppId, 10, 64)
if err != nil {
return nil, fmt.Errorf("could not parse app ID %q: %w", appID, err)
}
const httpTimeoutSeconds = 60
httpClient := common.RetryableHTTPClientTimeout(int64(httpTimeoutSeconds))
installationTransport, err := ghinstallation.NewAppsTransport(
httpClient.Transport,
appID,
[]byte(app.PrivateKey))
if err != nil {
return nil, fmt.Errorf("could not create installation client transport: %w", err)
}
installationTransport.BaseURL = apiEndpoint
installationHttpClient := common.RetryableHTTPClientTimeout(60)
installationHttpClient.Transport = installationTransport
installationClient, err := github.NewClient(installationHttpClient).WithEnterpriseURLs(apiEndpoint, apiEndpoint)
if err != nil {
return nil, fmt.Errorf("could not create installation client: %w", err)
}
apiTransport, err := ghinstallation.New(
httpClient.Transport,
appID,
installationID,
[]byte(app.PrivateKey))
if err != nil {
return nil, fmt.Errorf("could not create API client transport: %w", err)
}
apiTransport.BaseURL = apiEndpoint
httpClient.Transport = apiTransport
apiClient, err := github.NewClient(httpClient).WithEnterpriseURLs(apiEndpoint, apiEndpoint)
if err != nil {
return nil, fmt.Errorf("could not create API client: %w", err)
}
return &appConnector{
apiClient: apiClient,
installationClient: installationClient,
installationID: installationID,
}, nil
}
func (c *appConnector) APIClient() *github.Client {
return c.apiClient
}
func (c *appConnector) Clone(ctx context.Context, repoURL string, args ...string) (string, *gogit.Repository, error) {
// TODO: Check rate limit for this call.
token, _, err := c.installationClient.Apps.CreateInstallationToken(
ctx,
c.installationID,
&github.InstallationTokenOptions{})
if err != nil {
return "", nil, fmt.Errorf("could not create installation token: %w", err)
}
return git.CloneRepoUsingToken(ctx, token.GetToken(), repoURL, "x-access-token", true, args...)
}
func (c *appConnector) InstallationClient() *github.Client {
return c.installationClient
}