@@ -2,43 +2,88 @@ package github
2
2
3
3
import (
4
4
"fmt"
5
+ "net/http"
6
+ "net/url"
7
+ "strings"
5
8
6
9
gogit "github.com/go-git/go-git/v5"
7
10
"github.com/google/go-github/v67/github"
8
- "github.com/trufflesecurity/trufflehog/v3/pkg/log "
11
+ "github.com/shurcooL/githubv4 "
9
12
10
13
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
14
+ "github.com/trufflesecurity/trufflehog/v3/pkg/log"
11
15
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb"
12
16
)
13
17
14
- const cloudEndpoint = "https://api.github.com"
18
+ const (
19
+ cloudV3Endpoint = "https://api.github.com"
20
+ cloudGraphqlEndpoint = "https://api.github.com/graphql" // https://docs.github.com/en/graphql/guides/forming-calls-with-graphql#the-graphql-endpoint
21
+ )
15
22
16
23
type connector interface {
17
24
// APIClient returns a configured GitHub client that can be used for GitHub API operations.
18
25
APIClient () * github.Client
26
+ // GraphQLClient returns a client that can be used for GraphQL operations.
27
+ GraphQLClient () * githubv4.Client
19
28
// Clone clones a repository using the configured authentication information.
20
29
Clone (ctx context.Context , repoURL string ) (string , * gogit.Repository , error )
21
30
}
22
31
23
- func newConnector (source * Source ) (connector , error ) {
32
+ func newConnector (ctx context.Context , source * Source ) (connector , error ) {
33
+ // Construct the URLs.
24
34
apiEndpoint := source .conn .Endpoint
25
35
if apiEndpoint == "" || endsWithGithub .MatchString (apiEndpoint ) {
26
- apiEndpoint = cloudEndpoint
36
+ apiEndpoint = cloudV3Endpoint
27
37
}
28
38
29
39
switch cred := source .conn .GetCredential ().(type ) {
30
40
case * sourcespb.GitHub_GithubApp :
31
41
log .RedactGlobally (cred .GithubApp .GetPrivateKey ())
32
- return newAppConnector (apiEndpoint , cred .GithubApp )
42
+ return newAppConnector (ctx , apiEndpoint , cred .GithubApp )
33
43
case * sourcespb.GitHub_BasicAuth :
34
44
log .RedactGlobally (cred .BasicAuth .GetPassword ())
35
- return newBasicAuthConnector (apiEndpoint , cred .BasicAuth )
45
+ return newBasicAuthConnector (ctx , apiEndpoint , cred .BasicAuth )
36
46
case * sourcespb.GitHub_Token :
37
47
log .RedactGlobally (cred .Token )
38
- return newTokenConnector (apiEndpoint , cred .Token , source .handleRateLimit )
48
+ return newTokenConnector (ctx , apiEndpoint , cred .Token , source .handleRateLimit )
39
49
case * sourcespb.GitHub_Unauthenticated :
40
- return newUnauthenticatedConnector (apiEndpoint )
50
+ return newUnauthenticatedConnector (ctx , apiEndpoint )
41
51
default :
42
52
return nil , fmt .Errorf ("unknown connection type" )
43
53
}
44
54
}
55
+
56
+ func createAPIClient (ctx context.Context , httpClient * http.Client , apiEndpoint string ) (* github.Client , error ) {
57
+ getLogger (ctx ).V (2 ).Info ("Creating API client" , "url" , apiEndpoint )
58
+
59
+ // If we're using public GitHub, make a regular client.
60
+ // Otherwise, make an enterprise client.
61
+ if strings .EqualFold (apiEndpoint , cloudV3Endpoint ) {
62
+ return github .NewClient (httpClient ), nil
63
+ }
64
+
65
+ return github .NewClient (httpClient ).WithEnterpriseURLs (apiEndpoint , apiEndpoint )
66
+ }
67
+
68
+ func createGraphqlClient (ctx context.Context , client * http.Client , apiEndpoint string ) (* githubv4.Client , error ) {
69
+ var graphqlEndpoint string
70
+ if apiEndpoint == cloudV3Endpoint {
71
+ graphqlEndpoint = cloudGraphqlEndpoint
72
+ } else {
73
+ // Use the root endpoint for the host.
74
+ // https://docs.github.com/en/[email protected] /graphql/guides/introduction-to-graphql
75
+ parsedURL , err := url .Parse (apiEndpoint )
76
+ if err != nil {
77
+ return nil , fmt .Errorf ("could not create GraphQL client: %w" , err )
78
+ }
79
+
80
+ // GitHub Enterprise uses `/api/v3` for the base. (https://github.com/google/go-github/issues/958)
81
+ // Swap it, and anything before `/api`, with GraphQL.
82
+ before , _ := strings .CutSuffix (parsedURL .Path , "/api/v3" )
83
+ parsedURL .Path = before + "/api/graphql"
84
+ graphqlEndpoint = parsedURL .String ()
85
+ }
86
+ getLogger (ctx ).V (2 ).Info ("Creating GraphQL client" , "url" , graphqlEndpoint )
87
+
88
+ return githubv4 .NewEnterpriseClient (graphqlEndpoint , client ), nil
89
+ }
0 commit comments