@@ -4,17 +4,8 @@ import (
44"context"
55"crypto/rand"
66base64Utils"encoding/base64"
7- "encoding/json"
87"errors"
98"fmt"
10- "github.com/google/go-github/v56/github"
11- "github.com/grokify/mogo/encoding/base64"
12- "github.com/jfrog/froggit-go/vcsutils"
13- "github.com/jfrog/gofrog/datastructures"
14- "github.com/mitchellh/mapstructure"
15- "golang.org/x/crypto/nacl/box"
16- "golang.org/x/exp/slices"
17- "golang.org/x/oauth2"
189"io"
1910"net/http"
2011"net/url"
@@ -23,6 +14,15 @@ import (
2314"strconv"
2415"strings"
2516"time"
17+
18+ "github.com/google/go-github/v62/github"
19+ "github.com/grokify/mogo/encoding/base64"
20+ "github.com/jfrog/froggit-go/vcsutils"
21+ "github.com/jfrog/gofrog/datastructures"
22+ "github.com/mitchellh/mapstructure"
23+ "golang.org/x/crypto/nacl/box"
24+ "golang.org/x/exp/slices"
25+ "golang.org/x/oauth2"
2626)
2727
2828const (
@@ -156,8 +156,8 @@ func (client *GitHubClient) ListRepositories(ctx context.Context) (results map[s
156156}
157157
158158func (client * GitHubClient )executeListRepositoriesInPage (ctx context.Context ,page int ) ([]* github.Repository ,* github.Response ,error ) {
159- options := & github.RepositoryListOptions {ListOptions : github.ListOptions {Page :page }}
160- return client .ghClient .Repositories .List (ctx , "" ,options )
159+ options := & github.RepositoryListByAuthenticatedUserOptions {ListOptions : github.ListOptions {Page :page }}
160+ return client .ghClient .Repositories .ListByAuthenticatedUser (ctx ,options )
161161}
162162
163163// ListBranches on GitHub
@@ -1001,24 +1001,15 @@ func (client *GitHubClient) executeUploadCodeScanning(ctx context.Context, owner
10011001return
10021002}
10031003
1004- id , err = handleGitHubUploadSarifID (sarifID , err )
1004+ id = extractIdFronSarifIDIfExists (sarifID )
10051005return
10061006}
10071007
1008- func handleGitHubUploadSarifID (sarifID * github.SarifID , uploadSarifErr error ) ( id string , err error ) {
1008+ func extractIdFronSarifIDIfExists (sarifID * github.SarifID ) string {
10091009if sarifID != nil && * sarifID .ID != "" {
1010- id = * sarifID .ID
1011- return
1012- }
1013- var result map [string ]string
1014- var ghAcceptedError * github.AcceptedError
1015- if errors .As (uploadSarifErr ,& ghAcceptedError ) {
1016- if err = json .Unmarshal (ghAcceptedError .Raw ,& result );err != nil {
1017- return
1018- }
1019- id = result ["id" ]
1010+ return * sarifID .ID
10201011}
1021- return
1012+ return ""
10221013}
10231014
10241015// DownloadFileFromRepo on GitHub
@@ -1448,12 +1439,13 @@ func extractGitHubEnvironmentReviewers(environment *github.Environment) ([]strin
14481439}
14491440
14501441func createGitHubHook (token ,payloadURL string ,webhookEvents ... vcsutils.WebhookEvent )* github.Hook {
1442+ contentType := "json"
14511443return & github.Hook {
14521444Events :getGitHubWebhookEvents (webhookEvents ... ),
1453- Config :map [ string ] interface {} {
1454- "url" : payloadURL ,
1455- "content_type" : "json" ,
1456- "secret" :token ,
1445+ Config :& github. HookConfig {
1446+ ContentType : & contentType ,
1447+ URL : & payloadURL ,
1448+ Secret :& token ,
14571449},
14581450}
14591451}
@@ -1639,3 +1631,76 @@ func (client *GitHubClient) ListAppRepositories(ctx context.Context) ([]AppRepos
16391631
16401632return results ,nil
16411633}
1634+ func (client * GitHubClient )UploadSnapshotToDependencyGraph (ctx context.Context ,owner ,repo string ,snapshot * SbomSnapshot )error {
1635+ if snapshot == nil {
1636+ return fmt .Errorf ("provided snapshot is nil" )
1637+ }
1638+ ghSnapshot ,err := convertToGitHubSnapshot (snapshot )
1639+ if err != nil {
1640+ return fmt .Errorf ("failed to convert snapshot to GitHub format: %w" ,err )
1641+ }
1642+
1643+ _ ,ghResponse ,err := client .ghClient .DependencyGraph .CreateSnapshot (ctx ,owner ,repo ,ghSnapshot )
1644+ if err != nil {
1645+ return fmt .Errorf ("failed to upload snapshot to dependency graph: %w" ,err )
1646+ }
1647+
1648+ client .logger .Info (vcsutils .SuccessfulSnapshotUpload ,ghResponse .StatusCode )
1649+ return nil
1650+ }
1651+
1652+ func convertToGitHubSnapshot (snapshot * SbomSnapshot ) (* github.DependencyGraphSnapshot ,error ) {
1653+ ghSnapshot := & github.DependencyGraphSnapshot {
1654+ Version :snapshot .Version ,
1655+ Sha :& snapshot .Sha ,
1656+ Ref :& snapshot .Ref ,
1657+ Scanned :& github.Timestamp {Time :snapshot .Scanned },// Use current time if not provided
1658+ }
1659+
1660+ if snapshot .Job == nil {
1661+ return nil ,fmt .Errorf ("job information is required in the snapshot" )
1662+ }
1663+ ghSnapshot .Job = & github.DependencyGraphSnapshotJob {
1664+ Correlator :& snapshot .Job .Correlator ,
1665+ ID :& snapshot .Job .ID ,
1666+ }
1667+
1668+ if snapshot .Detector == nil {
1669+ return nil ,fmt .Errorf ("detector information is required in the snapshot" )
1670+ }
1671+ ghSnapshot .Detector = & github.DependencyGraphSnapshotDetector {
1672+ Name :& snapshot .Detector .Name ,
1673+ Version :& snapshot .Detector .Version ,
1674+ URL :& snapshot .Detector .Url ,
1675+ }
1676+
1677+ if len (snapshot .Manifests )== 0 {
1678+ return nil ,fmt .Errorf ("at least one manifest is required in the snapshot" )
1679+ }
1680+ ghSnapshot .Manifests = make (map [string ]* github.DependencyGraphSnapshotManifest )
1681+ for manifestName ,manifest := range snapshot .Manifests {
1682+ ghManifest := & github.DependencyGraphSnapshotManifest {
1683+ Name :& manifest .Name ,
1684+ }
1685+
1686+ if manifest .File == nil {
1687+ return nil ,fmt .Errorf ("manifest '%s' is missing file information" ,manifestName )
1688+ }
1689+ ghManifest .File = & github.DependencyGraphSnapshotManifestFile {SourceLocation :& manifest .File .SourceLocation }
1690+
1691+ if len (manifest .Resolved )== 0 {
1692+ return nil ,fmt .Errorf ("manifest '%s' must have at least one resolved dependency" ,manifestName )
1693+ }
1694+ ghManifest .Resolved = make (map [string ]* github.DependencyGraphSnapshotResolvedDependency )
1695+ for depName ,dep := range manifest .Resolved {
1696+ ghDep := & github.DependencyGraphSnapshotResolvedDependency {
1697+ PackageURL :& dep .PackageURL ,
1698+ Dependencies :dep .Dependencies ,
1699+ }
1700+ ghManifest .Resolved [depName ]= ghDep
1701+ }
1702+
1703+ ghSnapshot .Manifests [manifestName ]= ghManifest
1704+ }
1705+ return ghSnapshot ,nil
1706+ }