diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 1585ef24..baff4ed9 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -58,8 +58,6 @@ jobs: - name: Run GitLab E2E #using retry because the GitHub token is being throttled. uses: nick-invision/retry@943e742917ac94714d2f408a0e8320f2d1fcafcd - env: - GITLAB_AUTH_TOKEN: ${{ secrets.GITLAB_TOKEN }} with: max_attempts: 3 retry_on: error diff --git a/clients/gitlabrepo/issues.go b/clients/gitlabrepo/issues.go index 1902bcd0..36151ed4 100644 --- a/clients/gitlabrepo/issues.go +++ b/clients/gitlabrepo/issues.go @@ -48,8 +48,8 @@ func (handler *issuesHandler) setup() error { // There doesn't seem to be a good way to get user access_levels in gitlab so the following way may seem incredibly // barberic, however I couldn't find a better way in the docs. - projectAccessTokens, resp, err := handler.glClient.ProjectAccessTokens.ListProjectAccessTokens( - handler.repourl.project, &gitlab.ListProjectAccessTokensOptions{}) + projMemberships, resp, err := handler.glClient.ProjectMembers.ListAllProjectMembers( + handler.repourl.project, &gitlab.ListProjectMembersOptions{}) if err != nil && resp.StatusCode != 401 { handler.errSetup = fmt.Errorf("unable to find access tokens associated with the project id: %w", err) return @@ -58,26 +58,25 @@ func (handler *issuesHandler) setup() error { return } - if len(issues) > 0 { - for _, issue := range issues { - authorAssociation := clients.RepoAssociationMember - if resp.StatusCode != 401 { - authorAssociation = findAuthorAssociationFromUserID(projectAccessTokens, issue.Author.ID) + var authorAssociation clients.RepoAssociation + for _, issue := range issues { + for _, m := range projMemberships { + if issue.Author.ID == m.ID { + authorAssociation = accessLevelToRepoAssociation(m.AccessLevel) } - issueIDString := fmt.Sprint(issue.ID) - handler.issues = append(handler.issues, - clients.Issue{ - URI: &issueIDString, - CreatedAt: issue.CreatedAt, - Author: &clients.User{ - ID: int64(issue.Author.ID), - }, - AuthorAssociation: &authorAssociation, - Comments: nil, - }) } - } else { - handler.issues = nil + + issueIDString := fmt.Sprint(issue.ID) + handler.issues = append(handler.issues, + clients.Issue{ + URI: &issueIDString, + CreatedAt: issue.CreatedAt, + Author: &clients.User{ + ID: int64(issue.Author.ID), + }, + AuthorAssociation: &authorAssociation, + Comments: nil, + }) } }) return handler.errSetup @@ -91,28 +90,23 @@ func (handler *issuesHandler) listIssues() ([]clients.Issue, error) { return handler.issues, nil } -func findAuthorAssociationFromUserID(accessTokens []*gitlab.ProjectAccessToken, targetID int) clients.RepoAssociation { - for _, accessToken := range accessTokens { - if accessToken.UserID == targetID { - switch accessToken.AccessLevel { - case 0: - return clients.RepoAssociationNone - case 5: - return clients.RepoAssociationFirstTimeContributor - case 10: - return clients.RepoAssociationCollaborator - case 20: - return clients.RepoAssociationCollaborator - case 30: - return clients.RepoAssociationMember - case 40: - return clients.RepoAssociationMaintainer - case 50: - return clients.RepoAssociationOwner - default: - return clients.RepoAssociationNone - } - } +func accessLevelToRepoAssociation(l gitlab.AccessLevelValue) clients.RepoAssociation { + switch l { + case 0: + return clients.RepoAssociationNone + case 5: + return clients.RepoAssociationFirstTimeContributor + case 10: + return clients.RepoAssociationCollaborator + case 20: + return clients.RepoAssociationCollaborator + case 30: + return clients.RepoAssociationMember + case 40: + return clients.RepoAssociationMaintainer + case 50: + return clients.RepoAssociationOwner + default: + return clients.RepoAssociationNone } - return clients.RepoAssociationNone } diff --git a/e2e/maintained_test.go b/e2e/maintained_test.go index 228f0882..7e7576ed 100644 --- a/e2e/maintained_test.go +++ b/e2e/maintained_test.go @@ -16,6 +16,7 @@ package e2e import ( "context" + "os" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -24,6 +25,7 @@ import ( "github.com/ossf/scorecard/v4/checks" "github.com/ossf/scorecard/v4/clients" "github.com/ossf/scorecard/v4/clients/githubrepo" + "github.com/ossf/scorecard/v4/clients/gitlabrepo" scut "github.com/ossf/scorecard/v4/utests" ) @@ -54,5 +56,34 @@ var _ = Describe("E2E TEST:"+checks.CheckMaintained, func() { Expect(scut.ValidateTestReturn(nil, "active repo", &expected, &result, &dl)).Should(BeTrue()) Expect(repoClient.Close()).Should(BeNil()) }) + It("Should return valid maintained status - GitLab", func() { + skipIfTokenIsNot(gitlabPATTokenType, "GitLab only") + + dl := scut.TestDetailLogger{} + repo, err := gitlabrepo.MakeGitlabRepo("gitlab.com/gitlab-org/gitlab") + Expect(err).Should(BeNil()) + repoClient, err := gitlabrepo.CreateGitlabClientWithToken(context.Background(), + os.Getenv("GITLAB_AUTH_TOKEN"), repo) + Expect(err).Should(BeNil()) + err = repoClient.InitRepo(repo, clients.HeadSHA, 0) + Expect(err).Should(BeNil()) + req := checker.CheckRequest{ + Ctx: context.Background(), + RepoClient: repoClient, + Repo: repo, + Dlogger: &dl, + } + expected := scut.TestReturn{ + Error: nil, + Score: checker.MaxResultScore, + NumberOfWarn: 0, + NumberOfInfo: 0, + NumberOfDebug: 0, + } + result := checks.Maintained(&req) + // New version. + Expect(scut.ValidateTestReturn(nil, "active repo", &expected, &result, &dl)).Should(BeTrue()) + Expect(repoClient.Close()).Should(BeNil()) + }) }) })