diff --git a/clients/gitlabrepo/client.go b/clients/gitlabrepo/client.go index 1254118fffc..e0df99e5306 100644 --- a/clients/gitlabrepo/client.go +++ b/clients/gitlabrepo/client.go @@ -58,6 +58,20 @@ type Client struct { commitDepth int } +var errRepoAccess = errors.New("repo inaccessible") + +// Raise an error if repository access level is private or disabled. +func checkRepoInaccessible(repo *gitlab.Project) error { + if (repo.RepositoryAccessLevel == gitlab.PrivateAccessControl) || + (repo.RepositoryAccessLevel == gitlab.DisabledAccessControl) { + return fmt.Errorf("%w: %s access level %s", + errRepoAccess, repo.PathWithNamespace, string(repo.RepositoryAccessLevel), + ) + } + + return nil +} + // InitRepo sets up the GitLab project in local storage for improving performance and GitLab token usage efficiency. func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitDepth int) error { glRepo, ok := inputRepo.(*repoURL) @@ -71,6 +85,11 @@ func (client *Client) InitRepo(inputRepo clients.Repo, commitSHA string, commitD if err != nil { return sce.WithMessage(sce.ErrRepoUnreachable, proj+"\t"+err.Error()) } + + if err = checkRepoInaccessible(repo); err != nil { + return sce.WithMessage(sce.ErrRepoUnreachable, err.Error()) + } + if commitDepth <= 0 { client.commitDepth = 30 // default } else { diff --git a/clients/gitlabrepo/client_test.go b/clients/gitlabrepo/client_test.go index 8a92d634dbb..cfb6587bc13 100644 --- a/clients/gitlabrepo/client_test.go +++ b/clients/gitlabrepo/client_test.go @@ -16,9 +16,59 @@ package gitlabrepo import ( "context" + "fmt" "testing" + + "github.com/xanzy/go-gitlab" ) +func Test_checkRepoInaccessible(t *testing.T) { + tcs := []struct { + desc string + repourl string + }{ + { + desc: "private project", + repourl: "https://gitlab.com/ossf-test/private-project", + }, + } + + for _, tt := range tcs { + t.Run(tt.desc, func(t *testing.T) { + repo, err := MakeGitlabRepo(tt.repourl) + if err != nil { + t.Errorf(tt.repourl, err) + } + + client, err := CreateGitlabClient(context.Background(), repo.Host()) + if err != nil { + t.Errorf(tt.repourl, err) + } + + glRepo, ok := repo.(*repoURL) + if !ok { + t.Errorf(tt.repourl, errInputRepoType) + } + + // Sanity check. + glcl, ok := client.(*Client) + if !ok { + t.Error(tt.repourl, errInputRepoType) + } + + path := fmt.Sprintf("%s/%s", glRepo.owner, glRepo.project) + proj, _, err := glcl.glClient.Projects.GetProject(path, &gitlab.GetProjectOptions{}) + if err != nil { + t.Error(tt.repourl, err) + } + + if err = checkRepoInaccessible(proj); err == nil { + t.Errorf(fmt.Sprintf("repo %v was supposed to be unreachable but was reachable", repo)) + } + }) + } +} + func Test_InitRepo(t *testing.T) { t.Parallel() tcs := []struct {