loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(commenter roles): don't give system users roles (#6766)

Currently on every pull request Ghost would have a misleading "First-time contributor" role.
Also, if the issue author is a Ghost, all other ghosts who commented will be labeled as authors even if they are different ghosts.

I've added a missing check to abort all other permission and contribution checks early if the user is a ghost. Also applies to other system users, as suggested by @earl-warren.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6766
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Co-committed-by: 0ko <0ko@noreply.codeberg.org>

authored by

0ko
0ko
and committed by
Gusted
d1d78c1b 862f4ad6

+140 -5
+5
models/user/user_system.go
··· 1 1 // Copyright 2022 The Gitea Authors. All rights reserved. 2 + // Copyright 2024 The Forgejo Authors. All rights reserved. 2 3 // SPDX-License-Identifier: MIT 3 4 4 5 package user ··· 95 96 path, _ := url.JoinPath(setting.AppURL, "/api/v1/activitypub/actor") 96 97 return path 97 98 } 99 + 100 + func (u *User) IsAPActor() bool { 101 + return u != nil && u.ID == APActorUserID 102 + }
+10 -3
routers/web/repo/issue.go
··· 1 1 // Copyright 2014 The Gogs Authors. All rights reserved. 2 2 // Copyright 2018 The Gitea Authors. All rights reserved. 3 + // Copyright 2024 The Forgejo Authors. All rights reserved. 3 4 // SPDX-License-Identifier: MIT 4 5 5 6 package repo ··· 1308 1309 func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) { 1309 1310 roleDescriptor := issues_model.RoleDescriptor{} 1310 1311 1312 + // Migrated comment with no associated local user 1311 1313 if hasOriginalAuthor { 1312 1314 return roleDescriptor, nil 1313 1315 } 1314 1316 1315 - perm, err := access_model.GetUserRepoPermission(ctx, repo, poster) 1316 - if err != nil { 1317 - return roleDescriptor, err 1317 + // Special user that can't have associated contributions and permissions in the repo. 1318 + if poster.IsGhost() || poster.IsActions() || poster.IsAPActor() { 1319 + return roleDescriptor, nil 1318 1320 } 1319 1321 1320 1322 // If the poster is the actual poster of the issue, enable Poster role. 1321 1323 roleDescriptor.IsPoster = issue.IsPoster(poster.ID) 1324 + 1325 + perm, err := access_model.GetUserRepoPermission(ctx, repo, poster) 1326 + if err != nil { 1327 + return roleDescriptor, err 1328 + } 1322 1329 1323 1330 // Check if the poster is owner of the repo. 1324 1331 if perm.IsOwner() {
+56
tests/integration/comment_roles_system_test.go
··· 1 + // Copyright 2025 The Forgejo Authors. All rights reserved. 2 + // SPDX-License-Identifier: GPL-3.0-or-later 3 + 4 + package integration 5 + 6 + import ( 7 + "net/http" 8 + "testing" 9 + 10 + issues_model "code.gitea.io/gitea/models/issues" 11 + repo_model "code.gitea.io/gitea/models/repo" 12 + "code.gitea.io/gitea/models/unittest" 13 + "code.gitea.io/gitea/tests" 14 + 15 + "github.com/stretchr/testify/assert" 16 + ) 17 + 18 + // TestSystemCommentRoles verifies that system users don't have role labels. 19 + // As it is not possible to do actions as system users, the tests are done using fixtures. 20 + 21 + func TestSystemCommentRoles(t *testing.T) { 22 + defer tests.AddFixtures("tests/integration/fixtures/TestSystemCommentRoles/")() 23 + defer tests.PrepareTestEnv(t)() 24 + 25 + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 26 + 27 + testCases := []struct { 28 + name string 29 + username string 30 + index int64 31 + roleCount int64 32 + }{ 33 + {"user2", "user2", 1000, 1}, // As a verification, also check a normal user with one role. 34 + {"Ghost", "Ghost", 1001, 0}, // System users should not have any roles, so 0. 35 + {"Actions", "forgejo-actions", 1002, 0}, 36 + {"APActor", "Ghost", 1003, 0}, // actor is displayed as Ghost, could be a bug. 37 + } 38 + 39 + for _, tc := range testCases { 40 + t.Run(tc.name, func(t *testing.T) { 41 + defer tests.PrintCurrentTest(t)() 42 + 43 + issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ 44 + RepoID: repo.ID, 45 + Index: tc.index, 46 + }) 47 + 48 + req := NewRequestf(t, "GET", "%s/issues/%d", repo.Link(), issue.Index) 49 + resp := MakeRequest(t, req, http.StatusOK) 50 + htmlDoc := NewHTMLParser(t, resp.Body) 51 + 52 + assert.EqualValues(t, tc.username, htmlDoc.Find("a.author").Text()) 53 + assert.EqualValues(t, tc.roleCount, htmlDoc.Find(".role-label").Length()) 54 + }) 55 + } 56 + }
+67
tests/integration/fixtures/TestSystemCommentRoles/issue.yml
··· 1 + - 2 + id: 1000 3 + repo_id: 1 4 + index: 1000 5 + poster_id: 2 6 + original_author_id: 0 7 + name: issue1 8 + content: authored by a normal user 2 9 + milestone_id: 0 10 + priority: 0 11 + is_closed: false 12 + is_pull: false 13 + num_comments: 1 14 + created_unix: 946684800 15 + updated_unix: 978307200 16 + is_locked: false 17 + 18 + - 19 + id: 1001 20 + repo_id: 1 21 + index: 1001 22 + poster_id: -1 23 + original_author_id: 0 24 + name: issue1 25 + content: authored by the system user -1 / Ghost 26 + milestone_id: 0 27 + priority: 0 28 + is_closed: false 29 + is_pull: false 30 + num_comments: 1 31 + created_unix: 946684800 32 + updated_unix: 978307200 33 + is_locked: false 34 + 35 + - 36 + id: 1002 37 + repo_id: 1 38 + index: 1002 39 + poster_id: -2 40 + original_author_id: 0 41 + name: issue2 42 + content: authored by the system user -2 / Action 43 + milestone_id: 0 44 + priority: 0 45 + is_closed: false 46 + is_pull: false 47 + num_comments: 1 48 + created_unix: 946684800 49 + updated_unix: 978307200 50 + is_locked: false 51 + 52 + - 53 + id: 1003 54 + repo_id: 1 55 + index: 1003 56 + poster_id: -3 57 + original_author_id: 0 58 + name: issue3 59 + content: authored by the system user -3 / APActor 60 + milestone_id: 0 61 + priority: 0 62 + is_closed: false 63 + is_pull: false 64 + num_comments: 1 65 + created_unix: 946684800 66 + updated_unix: 978307200 67 + is_locked: false
+2 -2
tests/integration/issues_comment_labels_test.go tests/integration/comment_roles_test.go
··· 14 14 "github.com/stretchr/testify/assert" 15 15 ) 16 16 17 - // TestIssuesCommentLabels is a test for user (role) labels in comment headers in PRs and issues. 18 - func TestIssuesCommentLabels(t *testing.T) { 17 + // TestCommentRoles is a test for role labels of normal users in comment headers in PRs and issues. 18 + func TestCommentRoles(t *testing.T) { 19 19 user := "user2" 20 20 repo := "repo1" 21 21