From 8e94b715cc27fcdf28bc3c5d1420ceba74e7ddfd Mon Sep 17 00:00:00 2001 From: Giteabot Date: Fri, 2 Jun 2023 17:13:33 -0400 Subject: [PATCH] GitLab migration: Sanitize response for reaction list (#25054) (#25059) Backport #25054 by @6543 Co-authored-by: 6543 <6543@obermui.de> --- services/migrations/gitlab.go | 35 ++++++++++++---------- services/migrations/gitlab_test.go | 47 ++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 8034869a4a..32f8d0b195 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -415,7 +415,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er milestone = issue.Milestone.Title } - var reactions []*base.Reaction + var reactions []*gitlab.AwardEmoji awardPage := 1 for { awards, _, err := g.client.AwardEmoji.ListIssueAwardEmoji(g.repoID, issue.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx)) @@ -423,9 +423,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er return nil, false, fmt.Errorf("error while listing issue awards: %w", err) } - for i := range awards { - reactions = append(reactions, g.awardToReaction(awards[i])) - } + reactions = append(reactions, awards...) if len(awards) < perPage { break @@ -444,7 +442,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er State: issue.State, Created: *issue.CreatedAt, Labels: labels, - Reactions: reactions, + Reactions: g.awardsToReactions(reactions), Closed: issue.ClosedAt, IsLocked: issue.DiscussionLocked, Updated: *issue.UpdatedAt, @@ -579,7 +577,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque milestone = pr.Milestone.Title } - var reactions []*base.Reaction + var reactions []*gitlab.AwardEmoji awardPage := 1 for { awards, _, err := g.client.AwardEmoji.ListMergeRequestAwardEmoji(g.repoID, pr.IID, &gitlab.ListAwardEmojiOptions{Page: awardPage, PerPage: perPage}, gitlab.WithContext(g.ctx)) @@ -587,9 +585,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque return nil, false, fmt.Errorf("error while listing merge requests awards: %w", err) } - for i := range awards { - reactions = append(reactions, g.awardToReaction(awards[i])) - } + reactions = append(reactions, awards...) if len(awards) < perPage { break @@ -616,7 +612,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque MergeCommitSHA: pr.MergeCommitSHA, MergedTime: mergeTime, IsLocked: locked, - Reactions: reactions, + Reactions: g.awardsToReactions(reactions), Head: base.PullRequestBranch{ Ref: pr.SourceBranch, SHA: pr.SHA, @@ -677,10 +673,19 @@ func (g *GitlabDownloader) GetReviews(reviewable base.Reviewable) ([]*base.Revie return reviews, nil } -func (g *GitlabDownloader) awardToReaction(award *gitlab.AwardEmoji) *base.Reaction { - return &base.Reaction{ - UserID: int64(award.User.ID), - UserName: award.User.Username, - Content: award.Name, +func (g *GitlabDownloader) awardsToReactions(awards []*gitlab.AwardEmoji) []*base.Reaction { + result := make([]*base.Reaction, 0, len(awards)) + uniqCheck := make(map[string]struct{}) + for _, award := range awards { + uid := fmt.Sprintf("%s%d", award.Name, award.User.ID) + if _, ok := uniqCheck[uid]; !ok { + result = append(result, &base.Reaction{ + UserID: int64(award.User.ID), + UserName: award.User.Username, + Content: award.Name, + }) + uniqCheck[uid] = struct{}{} + } } + return result } diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go index 1d8c5989bb..731486eff2 100644 --- a/services/migrations/gitlab_test.go +++ b/services/migrations/gitlab_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "code.gitea.io/gitea/modules/json" base "code.gitea.io/gitea/modules/migration" "github.com/stretchr/testify/assert" @@ -469,3 +470,49 @@ func TestGitlabGetReviews(t *testing.T) { assertReviewsEqual(t, []*base.Review{&review}, rvs) } } + +func TestAwardsToReactions(t *testing.T) { + downloader := &GitlabDownloader{} + // yes gitlab can have duplicated reactions (https://gitlab.com/jaywink/socialhome/-/issues/24) + testResponse := ` +[ + { + "name": "thumbsup", + "user": { + "id": 1241334, + "username": "lafriks" + } + }, + { + "name": "thumbsup", + "user": { + "id": 1241334, + "username": "lafriks" + } + }, + { + "name": "thumbsup", + "user": { + "id": 4575606, + "username": "real6543" + } + } +] +` + var awards []*gitlab.AwardEmoji + assert.NoError(t, json.Unmarshal([]byte(testResponse), &awards)) + + reactions := downloader.awardsToReactions(awards) + assert.EqualValues(t, []*base.Reaction{ + { + UserName: "lafriks", + UserID: 1241334, + Content: "thumbsup", + }, + { + UserName: "real6543", + UserID: 4575606, + Content: "thumbsup", + }, + }, reactions) +}