From db7eb4d51b00e3df9b564df49f71d8058f540199 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 29 Mar 2026 11:21:14 +0200 Subject: [PATCH] Fix issue label deletion with Actions tokens (#37013) Use shared repo permission resolution for Actions task users in issue label remove and clear paths, and add a regression test for deleting issue labels with a Gitea Actions token. This fixes issue label deletion when the request is authenticated with a Gitea Actions token. Fixes #37011 The bug was that the delete path re-resolved repository permissions using the normal user permission helper, which does not handle Actions task users. As a result, `DELETE /api/v1/repos/{owner}/{repo}/issues/{index}/labels/{id}` could return `500` for Actions tokens even though label listing and label addition worked. --------- Co-authored-by: Codex Co-authored-by: wxiaoguang Co-authored-by: Lunny Xiao Co-authored-by: Giteabot --- models/git/protected_branch.go | 4 +- models/issues/issue_label.go | 2 +- models/issues/issue_update.go | 4 +- models/issues/issue_xref.go | 2 +- models/issues/pull_list.go | 2 +- models/issues/review.go | 2 +- models/perm/access/repo_permission.go | 30 +++++++--- models/perm/access/repo_permission_test.go | 44 +++++++++++--- routers/api/packages/npm/npm.go | 2 +- routers/api/v1/api.go | 2 +- routers/api/v1/org/team.go | 4 +- routers/api/v1/repo/collaborators.go | 2 +- routers/api/v1/repo/fork.go | 2 +- routers/api/v1/repo/issue_comment.go | 2 +- routers/api/v1/repo/issue_dependency.go | 6 +- routers/api/v1/repo/pull.go | 4 +- routers/api/v1/repo/pull_review.go | 2 +- routers/api/v1/repo/repo.go | 4 +- routers/api/v1/user/repo.go | 4 +- routers/api/v1/user/star.go | 2 +- routers/api/v1/user/watch.go | 2 +- routers/private/hook_post_receive.go | 2 +- routers/private/hook_pre_receive.go | 2 +- routers/private/serv.go | 2 +- routers/web/repo/attachment.go | 4 +- routers/web/repo/common_recentbranches.go | 4 +- routers/web/repo/compare.go | 4 +- routers/web/repo/githttp.go | 31 +++------- routers/web/repo/issue_dependency.go | 4 +- routers/web/repo/issue_view.go | 16 ++--- routers/web/repo/pull.go | 8 +-- routers/web/shared/user/header.go | 2 +- routers/web/user/package.go | 8 +-- services/actions/notifier.go | 28 ++++----- services/actions/notifier_helper.go | 6 +- services/automerge/automerge.go | 4 +- services/context/repo.go | 8 +-- services/contexttest/context_tests.go | 2 +- services/convert/activity.go | 4 +- services/convert/convert.go | 4 +- services/convert/issue.go | 4 +- services/convert/notification.go | 4 +- services/convert/package.go | 2 +- services/convert/pull.go | 16 ++--- services/feed/feed.go | 2 +- services/issue/assignee.go | 4 +- services/issue/commit.go | 2 +- services/issue/label.go | 2 +- services/lfs/server.go | 4 +- services/mailer/incoming/incoming_handler.go | 4 +- services/markup/renderhelper_codepreview.go | 2 +- .../markup/renderhelper_issueicontitle.go | 2 +- services/packages/package_update.go | 4 +- services/pull/edits.go | 2 +- services/pull/pull.go | 4 +- services/pull/update.go | 4 +- services/repository/branch.go | 4 +- services/repository/transfer.go | 4 +- services/webhook/notifier.go | 46 +++++++------- tests/integration/actions_job_token_test.go | 60 +++++++++++++++++++ tests/integration/api_pull_review_test.go | 2 +- 61 files changed, 268 insertions(+), 181 deletions(-) diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go index f4567a0aac..f242f94f7b 100644 --- a/models/git/protected_branch.go +++ b/models/git/protected_branch.go @@ -495,9 +495,9 @@ func updateUserWhitelist(ctx context.Context, repo *repo_model.Repository, curre if err != nil { return nil, fmt.Errorf("GetUserByID [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) } - perm, err := access_model.GetUserRepoPermission(ctx, repo, user) + perm, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { - return nil, fmt.Errorf("GetUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) + return nil, fmt.Errorf("GetIndividualUserRepoPermission [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) } if !perm.CanWrite(unit.TypeCode) { diff --git a/models/issues/issue_label.go b/models/issues/issue_label.go index 151469a9b8..697448cf5e 100644 --- a/models/issues/issue_label.go +++ b/models/issues/issue_label.go @@ -356,7 +356,7 @@ func ClearIssueLabels(ctx context.Context, issue *Issue, doer *user_model.User) return err } - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return err } diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 0a320ffc56..01a3eb9a2a 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -665,9 +665,9 @@ func ResolveIssueMentionsByVisibility(ctx context.Context, issue *Issue, doer *u continue } // Normal users must have read access to the referencing issue - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, user) + perm, err := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, user) if err != nil { - return nil, fmt.Errorf("GetUserRepoPermission [%d]: %w", user.ID, err) + return nil, fmt.Errorf("GetIndividualUserRepoPermission [%d]: %w", user.ID, err) } if !perm.CanReadIssuesOrPulls(issue.IsPull) { continue diff --git a/models/issues/issue_xref.go b/models/issues/issue_xref.go index f8495929cf..41a867c892 100644 --- a/models/issues/issue_xref.go +++ b/models/issues/issue_xref.go @@ -207,7 +207,7 @@ func (issue *Issue) verifyReferencedIssue(stdCtx context.Context, ctx *crossRefe // Check doer permissions; set action to None if the doer can't change the destination if refIssue.RepoID != ctx.OrigIssue.RepoID || ref.Action != references.XRefActionNone { - perm, err := access_model.GetUserRepoPermission(stdCtx, refIssue.Repo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(stdCtx, refIssue.Repo, ctx.Doer) if err != nil { return nil, references.XRefActionNone, err } diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go index 19d727ecbd..bf8f9b7d91 100644 --- a/models/issues/pull_list.go +++ b/models/issues/pull_list.go @@ -93,7 +93,7 @@ func CanMaintainerWriteToBranch(ctx context.Context, p access_model.Permission, if err != nil { continue } - prPerm, err := access_model.GetUserRepoPermission(ctx, pr.BaseRepo, user) + prPerm, err := access_model.GetIndividualUserRepoPermission(ctx, pr.BaseRepo, user) if err != nil { continue } diff --git a/models/issues/review.go b/models/issues/review.go index 22e2e186d9..af2600876e 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -919,7 +919,7 @@ func CanMarkConversation(ctx context.Context, issue *Issue, doer *user_model.Use return false, nil } if doer.ID != issue.PosterID { - p, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + p, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return false, err } diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go index 622fa5d99a..21821f1746 100644 --- a/models/perm/access/repo_permission.go +++ b/models/perm/access/repo_permission.go @@ -331,7 +331,7 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito // Check permission like simple user but limit to read-only (PR #36095) // Enhanced to also grant read-only access if isSameRepo is true and target repository is public - botPerm, err := GetUserRepoPermission(ctx, repo, user_model.NewActionsUser()) + botPerm, err := GetIndividualUserRepoPermission(ctx, repo, user_model.NewActionsUser()) if err != nil { return perm, err } @@ -379,8 +379,19 @@ func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Reposito return perm, nil } -// GetUserRepoPermission returns the user permissions to the repository -func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) { +// GetDoerRepoPermission returns the repository permission for the current actor, +// dispatching to GetActionsUserRepoPermission when the actor is an Actions token user. +func GetDoerRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) { + if taskID, ok := user_model.GetActionsUserTaskID(user); ok { + return GetActionsUserRepoPermission(ctx, repo, user, taskID) + } + return GetIndividualUserRepoPermission(ctx, repo, user) +} + +// GetIndividualUserRepoPermission returns the permissions for an explicit user identity. +// In most request paths, callers should use GetDoerRepoPermission instead. +// Unlike GetDoerRepoPermission, this helper does not resolve Actions task users. +func GetIndividualUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) { defer func() { if err == nil { finalProcessRepoUnitPermission(user, &perm) @@ -539,8 +550,9 @@ func AccessLevel(ctx context.Context, user *user_model.User, repo *repo_model.Re // AccessLevelUnit returns the Access a user has to a repository's. Will return NoneAccess if the // user does not have access. +// This helper only supports explicit user identities and does not resolve Actions task users. func AccessLevelUnit(ctx context.Context, user *user_model.User, repo *repo_model.Repository, unitType unit.Type) (perm_model.AccessMode, error) { //nolint:revive // export stutter - perm, err := GetUserRepoPermission(ctx, repo, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { return perm_model.AccessModeNone, err } @@ -559,7 +571,7 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model. if user.IsOrganization() { return false, fmt.Errorf("organization can't be added as assignee [user_id: %d, repo_id: %d]", user.ID, repo.ID) } - perm, err := GetUserRepoPermission(ctx, repo, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { return false, err } @@ -568,6 +580,7 @@ func CanBeAssigned(ctx context.Context, user *user_model.User, repo *repo_model. } // HasAnyUnitAccess see the comment of "perm.HasAnyUnitAccess" +// This helper only supports explicit user identities and does not resolve Actions task users. func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Repository) (bool, error) { var user *user_model.User var err error @@ -577,7 +590,7 @@ func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Reposi return false, err } } - perm, err := GetUserRepoPermission(ctx, repo, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { return false, err } @@ -625,13 +638,14 @@ func GetUserIDsWithUnitAccess(ctx context.Context, repo *repo_model.Repository, } // CheckRepoUnitUser check whether user could visit the unit of this repository +// This helper only supports explicit user identities and does not resolve Actions task users. func CheckRepoUnitUser(ctx context.Context, repo *repo_model.Repository, user *user_model.User, unitType unit.Type) bool { if user != nil && user.IsAdmin { return true } - perm, err := GetUserRepoPermission(ctx, repo, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { - log.Error("GetUserRepoPermission: %w", err) + log.Error("GetIndividualUserRepoPermission: %w", err) return false } diff --git a/models/perm/access/repo_permission_test.go b/models/perm/access/repo_permission_test.go index a36be213ec..29a8dac71d 100644 --- a/models/perm/access/repo_permission_test.go +++ b/models/perm/access/repo_permission_test.go @@ -6,6 +6,7 @@ package access import ( "testing" + actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/organization" perm_model "code.gitea.io/gitea/models/perm" @@ -157,8 +158,13 @@ func TestUnitAccessMode(t *testing.T) { assert.Equal(t, perm_model.AccessModeRead, perm.UnitAccessMode(unit.TypeWiki), "has unit, and map, use map") } -func TestGetUserRepoPermission(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) +func TestGetRepoPermission(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + t.Run("GetIndividualUserRepoPermission", testGetIndividualUserRepoPermission) + t.Run("GetDoerRepoPermission", testGetDoerRepoPermission) +} + +func testGetIndividualUserRepoPermission(t *testing.T) { ctx := t.Context() repo32 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}) // org public repo require.NoError(t, repo32.LoadOwner(ctx)) @@ -172,7 +178,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.Insert(ctx, &organization.TeamUser{OrgID: org.ID, TeamID: team.ID, UID: user.ID})) t.Run("DoerInTeamWithNoRepo", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo32, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo32, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode) assert.Nil(t, perm.unitsMode) // doer in the team, but has no access to the repo @@ -181,7 +187,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: org.ID, TeamID: team.ID, RepoID: repo32.ID})) require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeNone})) t.Run("DoerWithTeamUnitAccessNone", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo32, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo32, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode) assert.Equal(t, perm_model.AccessModeRead, perm.unitsMode[unit.TypeCode]) @@ -191,7 +197,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.TruncateBeans(ctx, &organization.TeamUnit{})) require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeWrite})) t.Run("DoerWithTeamUnitAccessWrite", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo32, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo32, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode) assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode]) @@ -204,7 +210,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.TruncateBeans(ctx, &organization.TeamUnit{}, &Access{})) // The user has access set of that repo, remove it, it is useless for our test require.NoError(t, db.Insert(ctx, &organization.TeamRepo{OrgID: org.ID, TeamID: team.ID, RepoID: repo3.ID})) t.Run("DoerWithNoopTeamOnPrivateRepo", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo3, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo3, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode) assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode]) @@ -214,7 +220,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeCode, AccessMode: perm_model.AccessModeNone})) require.NoError(t, db.Insert(ctx, &organization.TeamUnit{OrgID: org.ID, TeamID: team.ID, Type: unit.TypeIssues, AccessMode: perm_model.AccessModeRead})) t.Run("DoerWithReadIssueTeamOnPrivateRepo", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo3, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo3, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode) assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode]) @@ -233,7 +239,7 @@ func TestGetUserRepoPermission(t *testing.T) { require.NoError(t, db.Insert(ctx, repo_model.Collaboration{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite})) require.NoError(t, db.Insert(ctx, Access{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite})) t.Run("DoerWithReadIssueTeamAndWriteCollaboratorOnPrivateRepo", func(t *testing.T) { - perm, err := GetUserRepoPermission(ctx, repo3, user) + perm, err := GetIndividualUserRepoPermission(ctx, repo3, user) require.NoError(t, err) assert.Equal(t, perm_model.AccessModeWrite, perm.AccessMode) assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode]) @@ -245,3 +251,25 @@ func TestGetUserRepoPermission(t *testing.T) { assert.Equal(t, user.ID, users[0].ID) }) } + +func testGetDoerRepoPermission(t *testing.T) { + ctx := t.Context() + + repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + task47 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 47}) + actionsDoer := user_model.NewActionsUserWithTaskID(task47.ID) + regularUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + actionsPerm, err := GetDoerRepoPermission(ctx, repo4, actionsDoer) + require.NoError(t, err) + directPerm, err := GetActionsUserRepoPermission(ctx, repo4, actionsDoer, task47.ID) + require.NoError(t, err) + assert.Equal(t, directPerm, actionsPerm) + + doerPerm, err := GetDoerRepoPermission(ctx, repo1, regularUser) + require.NoError(t, err) + individualPerm, err := GetIndividualUserRepoPermission(ctx, repo1, regularUser) + require.NoError(t, err) + assert.Equal(t, individualPerm, doerPerm) +} diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index cc2aff8ea0..b65edf2334 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -169,7 +169,7 @@ func UploadPackage(ctx *context.Context) { canWrite := repo.OwnerID == ctx.Doer.ID if !canWrite { - perms, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + perms, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { apiError(ctx, http.StatusInternalServerError, err) return diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 454bae73db..ea595407d1 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -202,7 +202,7 @@ func repoAssignment() func(ctx *context.APIContext) { if needTwoFactor { ctx.Repo.Permission = access_model.PermissionNoAccess() } else { - ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + ctx.Repo.Permission, err = access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 3b5711eea3..659218e837 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -576,7 +576,7 @@ func GetTeamRepos(ctx *context.APIContext) { } repos := make([]*api.Repository, len(teamRepos)) for i, repo := range teamRepos { - permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return @@ -628,7 +628,7 @@ func GetTeamRepo(ctx *context.APIContext) { return } - permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index eed9c19fe1..2c40e26508 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -291,7 +291,7 @@ func GetRepoPermissions(ctx *context.APIContext) { return } - permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, ctx.Repo.Repository, collaborator) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 58f66954e1..16bfce9f19 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -71,7 +71,7 @@ func ListForks(ctx *context.APIContext) { apiForks := make([]*api.Repository, len(forks)) for i, fork := range forks { - permission, err := access_model.GetUserRepoPermission(ctx, fork, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, fork, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 37b5836e1d..091fe6998c 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -219,7 +219,7 @@ func isXRefCommentAccessible(ctx stdCtx.Context, user *user_model.User, c *issue if err != nil { return false } - perm, err := access_model.GetUserRepoPermission(ctx, c.RefRepo, user) + perm, err := access_model.GetDoerRepoPermission(ctx, c.RefRepo, user) if err != nil { return false } diff --git a/routers/api/v1/repo/issue_dependency.go b/routers/api/v1/repo/issue_dependency.go index 139779dcec..28cdbb3091 100644 --- a/routers/api/v1/repo/issue_dependency.go +++ b/routers/api/v1/repo/issue_dependency.go @@ -102,7 +102,7 @@ func GetIssueDependencies(ctx *context.APIContext) { perm = existPerm } else { var err error - perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) + perm, err = access_model.GetDoerRepoPermission(ctx, &blocker.Repository, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return @@ -351,7 +351,7 @@ func GetIssueBlocks(ctx *context.APIContext) { perm = existPerm } else { var err error - perm, err = access_model.GetUserRepoPermission(ctx, &depMeta.Repository, ctx.Doer) + perm, err = access_model.GetDoerRepoPermission(ctx, &depMeta.Repository, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return @@ -537,7 +537,7 @@ func getPermissionForRepo(ctx *context.APIContext, repo *repo_model.Repository) return &ctx.Repo.Permission } - perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return nil diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index af2f6fae5d..f405a3152f 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1113,7 +1113,7 @@ func parseCompareInfo(ctx *context.APIContext, compareParam string) (result *git }() // user should have permission to read baseRepo's codes and pulls, NOT headRepo's - permBase, err := access_model.GetUserRepoPermission(ctx, baseRepo, ctx.Doer) + permBase, err := access_model.GetDoerRepoPermission(ctx, baseRepo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return nil, nil @@ -1127,7 +1127,7 @@ func parseCompareInfo(ctx *context.APIContext, compareParam string) (result *git // user should have permission to read headRepo's codes // TODO: could the logic be simplified if the headRepo is the same as the baseRepo? Need to think more about it. - permHead, err := access_model.GetUserRepoPermission(ctx, headRepo, ctx.Doer) + permHead, err := access_model.GetDoerRepoPermission(ctx, headRepo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return nil, nil diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index d4b268c009..1e3a05212d 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -833,7 +833,7 @@ func apiReviewRequest(ctx *context.APIContext, opts api.PullReviewRequestOptions return } - permDoer, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, ctx.Doer) + permDoer, err := access_model.GetDoerRepoPermission(ctx, pr.Issue.Repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 1b3d85346b..81618fd25d 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -221,7 +221,7 @@ func Search(ctx *context.APIContext) { }) return } - permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.JSON(http.StatusInternalServerError, api.SearchError{ OK: false, @@ -588,7 +588,7 @@ func GetByID(ctx *context.APIContext) { return } - permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index e24a7543a1..a664888dbf 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -37,7 +37,7 @@ func listUserRepos(ctx *context.APIContext, u *user_model.User, private bool) { apiRepos := make([]*api.Repository, 0, len(repos)) for i := range repos { - permission, err := access_model.GetUserRepoPermission(ctx, repos[i], ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repos[i], ctx.Doer) if err != nil { ctx.APIErrorInternal(err) return @@ -123,7 +123,7 @@ func ListMyRepos(ctx *context.APIContext) { ctx.APIErrorInternal(err) return } - permission, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 4464d53936..50a54b2683 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -31,7 +31,7 @@ func getStarredRepos(ctx *context.APIContext, user *user_model.User, private boo repos := make([]*api.Repository, len(starredRepos)) for i, starred := range starredRepos { - permission, err := access_model.GetUserRepoPermission(ctx, starred, user) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, starred, user) if err != nil { return nil, err } diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 751b0ae3bc..9c11d5ca35 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -29,7 +29,7 @@ func getWatchedRepos(ctx *context.APIContext, user *user_model.User, private boo repos := make([]*api.Repository, len(watchedRepos)) for i, watched := range watchedRepos { - permission, err := access_model.GetUserRepoPermission(ctx, watched, user) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, watched, user) if err != nil { return nil, 0, err } diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index b595a95b23..3d070a18ab 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -192,7 +192,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { }) return } - perm, err := access_model.GetUserRepoPermission(ctx, repo, pusher) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, pusher) if err != nil { log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err) ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{ diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 2dbf072f3a..3936e223d5 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -525,7 +525,7 @@ func (ctx *preReceiveContext) loadPusherAndPermission() bool { return false } ctx.user = user - userPerm, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, user) + userPerm, err := access_model.GetDoerRepoPermission(ctx, ctx.Repo.Repository, user) if err != nil { log.Error("Unable to get Repo permission of repo %s/%s of User %s: %v", ctx.Repo.Repository.OwnerName, ctx.Repo.Repository.Name, user.Name, err) ctx.JSON(http.StatusInternalServerError, private.Response{ diff --git a/routers/private/serv.go b/routers/private/serv.go index b752556c23..7c6eb907fa 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -338,7 +338,7 @@ func ServCommand(ctx *context.PrivateContext) { mode = perm.AccessModeRead } - perm, err := access_model.GetUserRepoPermission(ctx, repo, user) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, user) if err != nil { log.Error("Unable to get permissions for %-v with key %d in %-v Error: %v", user, key.ID, repo, err) ctx.JSON(http.StatusInternalServerError, private.Response{ diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index 9b2c64049b..8b35f52ed6 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -157,9 +157,9 @@ func ServeAttachment(ctx *context.Context, uuid string) { ctx.ServerError("GetRepositoryByID", err) return } - perm, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + perm, err = access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } } else { diff --git a/routers/web/repo/common_recentbranches.go b/routers/web/repo/common_recentbranches.go index c2083dec73..c749f15755 100644 --- a/routers/web/repo/common_recentbranches.go +++ b/routers/web/repo/common_recentbranches.go @@ -33,9 +33,9 @@ func prepareRecentlyPushedNewBranches(ctx *context.Context) { opts.BaseRepo = ctx.Repo.Repository.BaseRepo } - baseRepoPerm, err := access_model.GetUserRepoPermission(ctx, opts.BaseRepo, ctx.Doer) + baseRepoPerm, err := access_model.GetDoerRepoPermission(ctx, opts.BaseRepo, ctx.Doer) if err != nil { - log.Error("GetUserRepoPermission: %v", err) + log.Error("GetDoerRepoPermission: %v", err) return } if !opts.Repo.CanContentChange() || !opts.BaseRepo.CanContentChange() { diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index e034731e5c..285f3968d4 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -226,9 +226,9 @@ func ParseCompareInfo(ctx *context.Context) *git_service.CompareInfo { // If we're not merging from the same repo: if !isSameRepo { // Assert ctx.Doer has permission to read headRepo's codes - permHead, err := access_model.GetUserRepoPermission(ctx, headRepo, ctx.Doer) + permHead, err := access_model.GetDoerRepoPermission(ctx, headRepo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return nil } if !permHead.CanRead(unit.TypeCode) { diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index fb9445aed0..928c78a61f 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -22,7 +22,6 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git/gitcmd" "code.gitea.io/gitea/modules/gitrepo" @@ -186,29 +185,15 @@ func httpBase(ctx *context.Context, optGitService ...string) *serviceHandler { accessMode = perm.AccessModeRead } - taskID, isActionsUser := user_model.GetActionsUserTaskID(ctx.Doer) - if isActionsUser { - p, err := access_model.GetActionsUserRepoPermission(ctx, repo, ctx.Doer, taskID) - if err != nil { - ctx.ServerError("GetActionsUserRepoPermission", err) - return nil - } + p, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) + if err != nil { + ctx.ServerError("GetDoerRepoPermission", err) + return nil + } - if !p.CanAccess(accessMode, unitType) { - ctx.PlainText(http.StatusNotFound, "Repository not found") - return nil - } - } else { - p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return nil - } - - if !p.CanAccess(accessMode, unitType) { - ctx.PlainText(http.StatusNotFound, "Repository not found") - return nil - } + if !p.CanAccess(accessMode, unitType) { + ctx.PlainText(http.StatusNotFound, "Repository not found") + return nil } if !isPull && repo.IsMirror { diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go index bb2dc5b0fd..b5b252f8a1 100644 --- a/routers/web/repo/issue_dependency.go +++ b/routers/web/repo/issue_dependency.go @@ -55,9 +55,9 @@ func AddDependency(ctx *context.Context) { return } // Can ctx.Doer read issues in the dep repo? - depRepoPerm, err := access_model.GetUserRepoPermission(ctx, dep.Repo, ctx.Doer) + depRepoPerm, err := access_model.GetDoerRepoPermission(ctx, dep.Repo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } if !depRepoPerm.CanReadIssuesOrPulls(dep.IsPull) { diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index 2cd8be4533..250a54fc24 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -57,7 +57,7 @@ func roleDescriptor(ctx *context.Context, repo *repo_model.Repository, poster *u // Guess the role of the poster in the repo by permission perm, hasPermCache := permsCache[poster.ID] if !hasPermCache { - perm, err = access_model.GetUserRepoPermission(ctx, repo, poster) + perm, err = access_model.GetIndividualUserRepoPermission(ctx, repo, poster) if err != nil { return roleDesc, err } @@ -145,9 +145,9 @@ func checkBlockedByIssues(ctx *context.Context, blockers []*issues_model.Depende perm = existPerm } else { var err error - perm, err = access_model.GetUserRepoPermission(ctx, &blocker.Repository, ctx.Doer) + perm, err = access_model.GetDoerRepoPermission(ctx, &blocker.Repository, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return nil, nil } repoPerms[blocker.RepoID] = perm @@ -192,7 +192,7 @@ func filterXRefComments(ctx *context.Context, issue *issues_model.Issue) error { if err != nil { return err } - perm, err := access_model.GetUserRepoPermission(ctx, c.RefRepo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, c.RefRepo, ctx.Doer) if err != nil { return err } @@ -845,9 +845,9 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss if err := pull.LoadHeadRepo(ctx); err != nil { log.Error("LoadHeadRepo: %v", err) } else if pull.HeadRepo != nil { - perm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, pull.HeadRepo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } if perm.CanWrite(unit.TypeCode) { @@ -867,9 +867,9 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss if err := pull.LoadBaseRepo(ctx); err != nil { log.Error("LoadBaseRepo: %v", err) } - perm, err := access_model.GetUserRepoPermission(ctx, pull.BaseRepo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, pull.BaseRepo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } if !canWriteToHeadRepo { // maintainers maybe allowed to push to head repo even if they can't write to it diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 03dea19db6..e312fc9d2a 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -95,9 +95,9 @@ func getRepository(ctx *context.Context, repoID int64) *repo_model.Repository { return nil } - perm, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return nil } @@ -958,9 +958,9 @@ func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) { if pull.HeadRepo != nil { if !pull.HasMerged && ctx.Doer != nil { - perm, err := access_model.GetUserRepoPermission(ctx, pull.HeadRepo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, pull.HeadRepo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go index 2bd0abc4c0..2ba45fc5a7 100644 --- a/routers/web/shared/user/header.go +++ b/routers/web/shared/user/header.go @@ -101,7 +101,7 @@ func FindOwnerProfileReadme(ctx *context.Context, doer *user_model.User, optProf return nil, nil } - perm, err := access_model.GetUserRepoPermission(ctx, profileDbRepo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, profileDbRepo, doer) if err != nil { log.Error("FindOwnerProfileReadme failed to GetRepositoryByName: %v", err) return nil, nil diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 2dad5be554..ffbfaa229b 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -84,9 +84,9 @@ func ListPackages(ctx *context.Context) { continue } - permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pd.Repository, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } repositoryAccessMap[pd.Repository.ID] = permission.HasAnyUnitAccess() @@ -320,9 +320,9 @@ func ViewPackageVersion(ctx *context.Context) { hasRepositoryAccess := false if pd.Repository != nil { - permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, ctx.Doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pd.Repository, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } hasRepositoryAccess = permission.HasAnyUnitAccess() diff --git a/services/actions/notifier.go b/services/actions/notifier.go index c4bfe5c11b..abcaff09a3 100644 --- a/services/actions/notifier.go +++ b/services/actions/notifier.go @@ -47,7 +47,7 @@ func (n *actionsNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu log.Error("issue.LoadPoster: %v", err) return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) newNotifyInputFromIssue(issue, webhook_module.HookEventIssues).WithPayload(&api.IssuePayload{ Action: api.HookIssueOpened, @@ -76,7 +76,7 @@ func (n *actionsNotifier) notifyIssueChangeWithTitleOrContent(ctx context.Contex return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { log.Error("loadPullRequest: %v", err) @@ -110,7 +110,7 @@ func (n *actionsNotifier) notifyIssueChangeWithTitleOrContent(ctx context.Contex // IssueChangeStatus notifies close or reopen issue to notifiers func (n *actionsNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, _ *issues_model.Comment, isClosed bool) { ctx = withMethod(ctx, "IssueChangeStatus") - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) if issue.IsPull { if err := issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest: %v", err) @@ -259,7 +259,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) payload := &api.IssuePayload{ Action: action, Index: issue.Index, @@ -322,7 +322,7 @@ func notifyIssueCommentChange(ctx context.Context, doer *user_model.User, commen return } - permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, comment.Issue.Repo, doer) payload := &api.IssueCommentPayload{ Action: action, @@ -376,7 +376,7 @@ func (n *actionsNotifier) NewPullRequest(ctx context.Context, pull *issues_model return } - permission, _ := access_model.GetUserRepoPermission(ctx, pull.Issue.Repo, pull.Issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, pull.Issue.Repo, pull.Issue.Poster) newNotifyInputFromIssue(pull.Issue, webhook_module.HookEventPullRequest). WithPayload(&api.PullRequestPayload{ @@ -404,8 +404,8 @@ func (n *actionsNotifier) CreateRepository(ctx context.Context, doer, u *user_mo func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) { ctx = withMethod(ctx, "ForkRepository") - oldPermission, _ := access_model.GetUserRepoPermission(ctx, oldRepo, doer) - permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) + oldPermission, _ := access_model.GetDoerRepoPermission(ctx, oldRepo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, repo, doer) // forked webhook newNotifyInput(oldRepo, doer, webhook_module.HookEventFork).WithPayload(&api.ForkPayload{ @@ -452,9 +452,9 @@ func (n *actionsNotifier) PullRequestReview(ctx context.Context, pr *issues_mode return } - permission, err := access_model.GetUserRepoPermission(ctx, review.Issue.Repo, review.Issue.Poster) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, review.Issue.Repo, review.Issue.Poster) if err != nil { - log.Error("models.GetUserRepoPermission: %v", err) + log.Error("models.GetIndividualUserRepoPermission: %v", err) return } @@ -481,7 +481,7 @@ func (n *actionsNotifier) PullRequestReviewRequest(ctx context.Context, doer *us ctx = withMethod(ctx, "PullRequestReviewRequest") - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err := issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest failed: %v", err) return @@ -525,9 +525,9 @@ func (*actionsNotifier) MergePullRequest(ctx context.Context, doer *user_model.U return } - permission, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pr.Issue.Repo, doer) if err != nil { - log.Error("models.GetUserRepoPermission: %v", err) + log.Error("models.GetDoerRepoPermission: %v", err) return } @@ -723,7 +723,7 @@ func (n *actionsNotifier) PullRequestChangeTargetBranch(ctx context.Context, doe return } - permission, _ := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, pr.Issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, pr.Issue.Repo, pr.Issue.Poster) newNotifyInput(pr.Issue.Repo, doer, webhook_module.HookEventPullRequest). WithPayload(&api.PullRequestPayload{ Action: api.HookIssueEdited, diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go index 10b36a5a52..4d2a7113b9 100644 --- a/services/actions/notifier_helper.go +++ b/services/actions/notifier_helper.go @@ -362,7 +362,7 @@ func notifyRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R return } - permission, _ := access_model.GetUserRepoPermission(ctx, rel.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, rel.Repo, doer) newNotifyInput(rel.Repo, doer, webhook_module.HookEventRelease). WithRef(git.RefNameFromTag(rel.TagName).String()). @@ -413,8 +413,8 @@ func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *rep } // don't need approval if the user can write - if perm, err := access_model.GetUserRepoPermission(ctx, repo, user); err != nil { - return false, fmt.Errorf("GetUserRepoPermission: %w", err) + if perm, err := access_model.GetDoerRepoPermission(ctx, repo, user); err != nil { + return false, fmt.Errorf("GetDoerRepoPermission: %w", err) } else if perm.CanWrite(unit_model.TypeActions) { log.Trace("do not need approval because user %d can write", user.ID) return false, nil diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 10a31f4d7b..b3a988320b 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -245,9 +245,9 @@ func handlePullRequestAutoMerge(pullID int64, sha string) { return } - perm, err := access_model.GetUserRepoPermission(ctx, pr.BaseRepo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, pr.BaseRepo, doer) if err != nil { - log.Error("GetUserRepoPermission %-v: %v", pr.BaseRepo, err) + log.Error("GetDoerRepoPermission %-v: %v", pr.BaseRepo, err) return } diff --git a/services/context/repo.go b/services/context/repo.go index c39ab551f2..3155ad3de9 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -344,9 +344,9 @@ func RetrieveTemplateRepo(ctx *Context, repo *repo_model.Repository) { return } - perm, err := access_model.GetUserRepoPermission(ctx, templateRepo, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, templateRepo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } @@ -421,9 +421,9 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) { if ctx.DoerNeedTwoFactorAuth() { ctx.Repo.Permission = access_model.PermissionNoAccess() } else { - ctx.Repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) + ctx.Repo.Permission, err = access_model.GetDoerRepoPermission(ctx, repo, ctx.Doer) if err != nil { - ctx.ServerError("GetUserRepoPermission", err) + ctx.ServerError("GetDoerRepoPermission", err) return } } diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go index 701c25e442..afa6a422a7 100644 --- a/services/contexttest/context_tests.go +++ b/services/contexttest/context_tests.go @@ -125,7 +125,7 @@ func LoadRepo(t *testing.T, ctx gocontext.Context, repoID int64) { repo.Owner, err = user_model.GetUserByID(ctx, repo.Repository.OwnerID) assert.NoError(t, err) repo.RepoLink = repo.Repository.Link() - repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo.Repository, doer) + repo.Permission, err = access_model.GetDoerRepoPermission(ctx, repo.Repository, doer) assert.NoError(t, err) } diff --git a/services/convert/activity.go b/services/convert/activity.go index 01fef73e58..7fc3a0eb82 100644 --- a/services/convert/activity.go +++ b/services/convert/activity.go @@ -15,9 +15,9 @@ import ( ) func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_model.User) *api.Activity { - p, err := access_model.GetUserRepoPermission(ctx, ac.Repo, doer) + p, err := access_model.GetDoerRepoPermission(ctx, ac.Repo, doer) if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", ac.RepoID, err) + log.Error("GetDoerRepoPermission[%d]: %v", ac.RepoID, err) p.AccessMode = perm_model.AccessModeNone } diff --git a/services/convert/convert.go b/services/convert/convert.go index d9aea7d7fa..e79cb343e4 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -72,7 +72,7 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin return nil, err } - perms, err := access_model.GetUserRepoPermission(ctx, repo, user) + perms, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { return nil, err } @@ -105,7 +105,7 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin } if user != nil { - permission, err := access_model.GetUserRepoPermission(ctx, repo, user) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { return nil, err } diff --git a/services/convert/issue.go b/services/convert/issue.go index fe4870b5db..acd67fece4 100644 --- a/services/convert/issue.go +++ b/services/convert/issue.go @@ -200,7 +200,7 @@ func ToStopWatches(ctx context.Context, doer *user_model.User, sws []*issues_mod // ADD: Check user permissions perm, ok := permCache[repo.ID] if !ok { - perm, err = access_model.GetUserRepoPermission(ctx, repo, doer) + perm, err = access_model.GetDoerRepoPermission(ctx, repo, doer) if err != nil { continue } @@ -234,7 +234,7 @@ func ToTrackedTimeList(ctx context.Context, doer *user_model.User, tl issues_mod continue } perm, err := cache.GetWithEphemeralCache(ctx, permCache, "repo-perm", t.Issue.RepoID, func(ctx context.Context, repoID int64) (access_model.Permission, error) { - return access_model.GetUserRepoPermission(ctx, t.Issue.Repo, doer) + return access_model.GetDoerRepoPermission(ctx, t.Issue.Repo, doer) }) if err != nil { continue diff --git a/services/convert/notification.go b/services/convert/notification.go index 87166501a6..e91bc7dcde 100644 --- a/services/convert/notification.go +++ b/services/convert/notification.go @@ -25,9 +25,9 @@ func ToNotificationThread(ctx context.Context, n *activities_model.Notification) // since user only get notifications when he has access to use minimal access mode if n.Repository != nil { - perm, err := access_model.GetUserRepoPermission(ctx, n.Repository, n.User) + perm, err := access_model.GetIndividualUserRepoPermission(ctx, n.Repository, n.User) if err != nil { - log.Error("GetUserRepoPermission failed: %v", err) + log.Error("GetIndividualUserRepoPermission failed: %v", err) return result } if perm.HasAnyUnitAccessOrPublicAccess() { // if user has been revoked access to repo, do not show repo info diff --git a/services/convert/package.go b/services/convert/package.go index 08310dd7f6..2e5b15d84b 100644 --- a/services/convert/package.go +++ b/services/convert/package.go @@ -16,7 +16,7 @@ import ( func ToPackage(ctx context.Context, pd *packages.PackageDescriptor, doer *user_model.User) (*api.Package, error) { var repo *api.Repository if pd.Repository != nil { - permission, err := access_model.GetUserRepoPermission(ctx, pd.Repository, doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pd.Repository, doer) if err != nil { return nil, err } diff --git a/services/convert/pull.go b/services/convert/pull.go index 8b783d396a..bb675811f2 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -63,11 +63,11 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u repoUserPerm, err := cache.GetWithContextCache(ctx, cachegroup.RepoUserPermission, fmt.Sprintf("%d-%d", pr.BaseRepoID, doerID), func(ctx context.Context, _ string) (access_model.Permission, error) { - return access_model.GetUserRepoPermission(ctx, pr.BaseRepo, doer) + return access_model.GetDoerRepoPermission(ctx, pr.BaseRepo, doer) }, ) if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", pr.BaseRepoID, err) + log.Error("GetDoerRepoPermission[%d]: %v", pr.BaseRepoID, err) repoUserPerm.AccessMode = perm.AccessModeNone } @@ -181,9 +181,9 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u } if pr.HeadRepo != nil && pr.Flow == issues_model.PullRequestFlowGithub { - p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) + p, err := access_model.GetDoerRepoPermission(ctx, pr.HeadRepo, doer) if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) + log.Error("GetDoerRepoPermission[%d]: %v", pr.HeadRepoID, err) p.AccessMode = perm.AccessModeNone } @@ -334,9 +334,9 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs } defer gitRepo.Close() - baseRepoPerm, err := access_model.GetUserRepoPermission(ctx, baseRepo, doer) + baseRepoPerm, err := access_model.GetDoerRepoPermission(ctx, baseRepo, doer) if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", baseRepo.ID, err) + log.Error("GetDoerRepoPermission[%d]: %v", baseRepo.ID, err) baseRepoPerm.AccessMode = perm.AccessModeNone } @@ -435,9 +435,9 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs apiPullRequest.Head.Ref = pr.HeadBranch } if pr.HeadRepoID != pr.BaseRepoID { - p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) + p, err := access_model.GetDoerRepoPermission(ctx, pr.HeadRepo, doer) if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) + log.Error("GetDoerRepoPermission[%d]: %v", pr.HeadRepoID, err) p.AccessMode = perm.AccessModeNone } apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p) diff --git a/services/feed/feed.go b/services/feed/feed.go index 8d39a34fbc..87ba224c89 100644 --- a/services/feed/feed.go +++ b/services/feed/feed.go @@ -132,7 +132,7 @@ func NotifyWatchers(ctx context.Context, acts ...*activities_model.Action) error permPR[i] = false continue } - perm, err := access_model.GetUserRepoPermission(ctx, repo, user) + perm, err := access_model.GetIndividualUserRepoPermission(ctx, repo, user) if err != nil { permCode[i] = false permIssue[i] = false diff --git a/services/issue/assignee.go b/services/issue/assignee.go index 9b76687c46..5a64c722b3 100644 --- a/services/issue/assignee.go +++ b/services/issue/assignee.go @@ -103,14 +103,14 @@ func isValidReviewRequest(ctx context.Context, reviewer, doer *user_model.User, } } - permReviewer, err := access_model.GetUserRepoPermission(ctx, issue.Repo, reviewer) + permReviewer, err := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, reviewer) if err != nil { return err } if permDoer == nil { permDoer = new(access_model.Permission) - *permDoer, err = access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + *permDoer, err = access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return err } diff --git a/services/issue/commit.go b/services/issue/commit.go index 6cc120697a..68ccc906b6 100644 --- a/services/issue/commit.go +++ b/services/issue/commit.go @@ -157,7 +157,7 @@ func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_m continue } - perm, err := access_model.GetUserRepoPermission(ctx, refRepo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, refRepo, doer) if err != nil { return err } diff --git a/services/issue/label.go b/services/issue/label.go index e30983df37..93a3c2588e 100644 --- a/services/issue/label.go +++ b/services/issue/label.go @@ -51,7 +51,7 @@ func RemoveLabel(ctx context.Context, issue *issues_model.Issue, doer *user_mode return err } - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return err } diff --git a/services/lfs/server.go b/services/lfs/server.go index d0fd841041..0d4243a47e 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -550,9 +550,9 @@ func authenticate(ctx *context.Context, repository *repo_model.Repository, autho } // it works for both anonymous request and signed-in user, then perm.CanAccess will do the permission check - perm, err := access_model.GetUserRepoPermission(ctx, repository, ctx.Doer) + perm, err := access_model.GetDoerRepoPermission(ctx, repository, ctx.Doer) if err != nil { - log.Error("Unable to GetUserRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository, err) + log.Error("Unable to GetDoerRepoPermission for user %-v in repo %-v Error: %v", ctx.Doer, repository, err) return false } diff --git a/services/mailer/incoming/incoming_handler.go b/services/mailer/incoming/incoming_handler.go index 440b3a6b59..dfb7b1244c 100644 --- a/services/mailer/incoming/incoming_handler.go +++ b/services/mailer/incoming/incoming_handler.go @@ -67,7 +67,7 @@ func (h *ReplyHandler) Handle(ctx context.Context, content *MailContent, doer *u return err } - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return err } @@ -171,7 +171,7 @@ func (h *UnsubscribeHandler) Handle(ctx context.Context, _ *MailContent, doer *u return err } - perm, err := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err != nil { return err } diff --git a/services/markup/renderhelper_codepreview.go b/services/markup/renderhelper_codepreview.go index 44c0596dce..87c3bd1d48 100644 --- a/services/markup/renderhelper_codepreview.go +++ b/services/markup/renderhelper_codepreview.go @@ -42,7 +42,7 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie } doer := webCtx.Doer - perms, err := access.GetUserRepoPermission(ctx, dbRepo, doer) + perms, err := access.GetDoerRepoPermission(ctx, dbRepo, doer) if err != nil { return "", err } diff --git a/services/markup/renderhelper_issueicontitle.go b/services/markup/renderhelper_issueicontitle.go index 27b5595fa9..651e2997e0 100644 --- a/services/markup/renderhelper_issueicontitle.go +++ b/services/markup/renderhelper_issueicontitle.go @@ -43,7 +43,7 @@ func renderRepoIssueIconTitle(ctx context.Context, opts markup.RenderIssueIconTi } if webCtx.Repo.Repository == nil || dbRepo.ID != webCtx.Repo.Repository.ID { - perms, err := access.GetUserRepoPermission(ctx, dbRepo, webCtx.Doer) + perms, err := access.GetDoerRepoPermission(ctx, dbRepo, webCtx.Doer) if err != nil { return "", err } diff --git a/services/packages/package_update.go b/services/packages/package_update.go index 4a22ee7a62..d0ec43b748 100644 --- a/services/packages/package_update.go +++ b/services/packages/package_update.go @@ -24,7 +24,7 @@ func LinkToRepository(ctx context.Context, pkg *packages_model.Package, repo *re return util.ErrInvalidArgument } - perms, err := access_model.GetUserRepoPermission(ctx, repo, doer) + perms, err := access_model.GetDoerRepoPermission(ctx, repo, doer) if err != nil { return fmt.Errorf("error getting permissions for user %d on repository %d: %w", doer.ID, repo.ID, err) } @@ -48,7 +48,7 @@ func UnlinkFromRepository(ctx context.Context, pkg *packages_model.Package, doer return fmt.Errorf("error getting repository %d: %w", pkg.RepoID, err) } if err == nil { - perms, err := access_model.GetUserRepoPermission(ctx, repo, doer) + perms, err := access_model.GetDoerRepoPermission(ctx, repo, doer) if err != nil { return fmt.Errorf("error getting permissions for user %d on repository %d: %w", doer.ID, repo.ID, err) } diff --git a/services/pull/edits.go b/services/pull/edits.go index c7550dcb07..193e385d2a 100644 --- a/services/pull/edits.go +++ b/services/pull/edits.go @@ -26,7 +26,7 @@ func SetAllowEdits(ctx context.Context, doer *user_model.User, pr *issues_model. return err } - permission, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pr.HeadRepo, doer) if err != nil { return err } diff --git a/services/pull/pull.go b/services/pull/pull.go index 285e489078..779d2b13e1 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -79,7 +79,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { if err := pr.LoadHeadRepo(ctx); err != nil { return err } - perm, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, issue.Poster) + perm, err := access_model.GetDoerRepoPermission(ctx, pr.HeadRepo, issue.Poster) if err != nil { return err } @@ -159,7 +159,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error { // Request reviews, these should be requested before other notifications because they will add request reviews record // on database - permDoer, err := access_model.GetUserRepoPermission(ctx, repo, issue.Poster) + permDoer, err := access_model.GetDoerRepoPermission(ctx, repo, issue.Poster) if err != nil { return err } diff --git a/services/pull/update.go b/services/pull/update.go index c9dbb34ef6..4033e11e2b 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -108,7 +108,7 @@ func isUserAllowedToPushOrForcePushInRepoBranch(ctx context.Context, user *user_ } // 1. check user push permission on the given repository - repoPerm, err := access_model.GetUserRepoPermission(ctx, repo, user) + repoPerm, err := access_model.GetDoerRepoPermission(ctx, repo, user) if err != nil { if repo_model.IsErrUnitTypeNotExist(err) { return false, false, nil @@ -166,7 +166,7 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest, // 4. if the pull creator allows maintainer to edit, we need to check whether // user is a maintainer (has permission to merge into base branch) and inherit pull request poster's permission if pull.AllowMaintainerEdit && (!pushAllowed || !rebaseAllowed) { - baseRepoPerm, err := access_model.GetUserRepoPermission(ctx, pull.BaseRepo, user) + baseRepoPerm, err := access_model.GetDoerRepoPermission(ctx, pull.BaseRepo, user) if err != nil { return false, false, err } diff --git a/services/repository/branch.go b/services/repository/branch.go index 87aa3bbc33..dc17e4f2fe 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -419,7 +419,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m return "", err } - perm, err := access_model.GetUserRepoPermission(ctx, repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, doer) if err != nil { return "", err } @@ -555,7 +555,7 @@ func CanDeleteBranch(ctx context.Context, repo *repo_model.Repository, branchNam return ErrBranchIsDefault } - perm, err := access_model.GetUserRepoPermission(ctx, repo, doer) + perm, err := access_model.GetDoerRepoPermission(ctx, repo, doer) if err != nil { return err } diff --git a/services/repository/transfer.go b/services/repository/transfer.go index fbf357c366..217ecb0124 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -539,9 +539,9 @@ func canUserCancelTransfer(ctx context.Context, r *repo_model.RepoTransfer, u *u return r.Repo.OwnerID == u.ID } - perm, err := access_model.GetUserRepoPermission(ctx, r.Repo, u) + perm, err := access_model.GetIndividualUserRepoPermission(ctx, r.Repo, u) if err != nil { - log.Error("GetUserRepoPermission: %v", err) + log.Error("GetIndividualUserRepoPermission: %v", err) return false } return perm.IsOwner() diff --git a/services/webhook/notifier.go b/services/webhook/notifier.go index 80de6b00fd..0a5661009e 100644 --- a/services/webhook/notifier.go +++ b/services/webhook/notifier.go @@ -53,7 +53,7 @@ func (m *webhookNotifier) IssueClearLabels(ctx context.Context, doer *user_model return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) var err error if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { @@ -83,8 +83,8 @@ func (m *webhookNotifier) IssueClearLabels(ctx context.Context, doer *user_model } func (m *webhookNotifier) ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) { - oldPermission, _ := access_model.GetUserRepoPermission(ctx, oldRepo, doer) - permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) + oldPermission, _ := access_model.GetDoerRepoPermission(ctx, oldRepo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, repo, doer) // forked webhook if err := PrepareWebhooks(ctx, EventSource{Repository: oldRepo}, webhook_module.HookEventFork, &api.ForkPayload{ @@ -147,7 +147,7 @@ func (m *webhookNotifier) MigrateRepository(ctx context.Context, doer, u *user_m func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { if issue.IsPull { - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err := issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest failed: %v", err) @@ -170,7 +170,7 @@ func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo return } } else { - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) apiIssue := &api.IssuePayload{ Index: issue.Index, Issue: convert.ToAPIIssue(ctx, doer, issue), @@ -191,7 +191,7 @@ func (m *webhookNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo } func (m *webhookNotifier) IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) { - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) var err error if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { @@ -231,7 +231,7 @@ func (m *webhookNotifier) IssueChangeTitle(ctx context.Context, doer *user_model } func (m *webhookNotifier) IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, isClosed bool) { - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) var err error if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { @@ -282,7 +282,7 @@ func (m *webhookNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventIssues, &api.IssuePayload{ Action: api.HookIssueOpened, Index: issue.Index, @@ -295,7 +295,7 @@ func (m *webhookNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu } func (m *webhookNotifier) DeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) { - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if issue.IsPull { if err := issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest: %v", err) @@ -345,7 +345,7 @@ func (m *webhookNotifier) NewPullRequest(ctx context.Context, pull *issues_model return } - permission, _ := access_model.GetUserRepoPermission(ctx, pull.Issue.Repo, pull.Issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, pull.Issue.Repo, pull.Issue.Poster) if err := PrepareWebhooks(ctx, EventSource{Repository: pull.Issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueOpened, Index: pull.Issue.Index, @@ -363,7 +363,7 @@ func (m *webhookNotifier) IssueChangeContent(ctx context.Context, doer *user_mod return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) var err error if issue.IsPull { if err := issue.LoadPullRequest(ctx); err != nil { @@ -425,7 +425,7 @@ func (m *webhookNotifier) UpdateComment(ctx context.Context, doer *user_model.Us eventType = webhook_module.HookEventIssueComment } - permission, _ := access_model.GetUserRepoPermission(ctx, c.Issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, c.Issue.Repo, doer) if err := PrepareWebhooks(ctx, EventSource{Repository: c.Issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentEdited, Issue: convert.ToAPIIssue(ctx, doer, c.Issue), @@ -460,7 +460,7 @@ func (m *webhookNotifier) CreateIssueComment(ctx context.Context, doer *user_mod eventType = webhook_module.HookEventIssueComment } - permission, _ := access_model.GetUserRepoPermission(ctx, repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, repo, doer) if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentCreated, Issue: convert.ToAPIIssue(ctx, doer, issue), @@ -501,7 +501,7 @@ func (m *webhookNotifier) DeleteComment(ctx context.Context, doer *user_model.Us eventType = webhook_module.HookEventIssueComment } - permission, _ := access_model.GetUserRepoPermission(ctx, comment.Issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, comment.Issue.Repo, doer) if err := PrepareWebhooks(ctx, EventSource{Repository: comment.Issue.Repo}, eventType, &api.IssueCommentPayload{ Action: api.HookIssueCommentDeleted, Issue: convert.ToAPIIssue(ctx, doer, comment.Issue), @@ -568,7 +568,7 @@ func (m *webhookNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + permission, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) if issue.IsPull { if err = issue.LoadPullRequest(ctx); err != nil { log.Error("loadPullRequest: %v", err) @@ -613,7 +613,7 @@ func (m *webhookNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if issue.IsPull { err = issue.PullRequest.LoadIssue(ctx) if err != nil { @@ -687,9 +687,9 @@ func (*webhookNotifier) MergePullRequest(ctx context.Context, doer *user_model.U return } - permission, err := access_model.GetUserRepoPermission(ctx, pr.Issue.Repo, doer) + permission, err := access_model.GetDoerRepoPermission(ctx, pr.Issue.Repo, doer) if err != nil { - log.Error("models.GetUserRepoPermission: %v", err) + log.Error("models.GetDoerRepoPermission: %v", err) return } @@ -715,7 +715,7 @@ func (m *webhookNotifier) PullRequestChangeTargetBranch(ctx context.Context, doe issue := pr.Issue - mode, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, issue.Poster) + mode, _ := access_model.GetIndividualUserRepoPermission(ctx, issue.Repo, issue.Poster) if err := PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ Action: api.HookIssueEdited, Index: issue.Index, @@ -753,9 +753,9 @@ func (m *webhookNotifier) PullRequestReview(ctx context.Context, pr *issues_mode return } - permission, err := access_model.GetUserRepoPermission(ctx, review.Issue.Repo, review.Issue.Poster) + permission, err := access_model.GetIndividualUserRepoPermission(ctx, review.Issue.Repo, review.Issue.Poster) if err != nil { - log.Error("models.GetUserRepoPermission: %v", err) + log.Error("models.GetIndividualUserRepoPermission: %v", err) return } if err := PrepareWebhooks(ctx, EventSource{Repository: review.Issue.Repo}, reviewHookType, &api.PullRequestPayload{ @@ -779,7 +779,7 @@ func (m *webhookNotifier) PullRequestReviewRequest(ctx context.Context, doer *us log.Warn("PullRequestReviewRequest: issue is not a pull request: %v", issue.ID) return } - permission, _ := access_model.GetUserRepoPermission(ctx, issue.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, issue.Repo, doer) if err := issue.LoadPullRequest(ctx); err != nil { log.Error("LoadPullRequest failed: %v", err) return @@ -857,7 +857,7 @@ func sendReleaseHook(ctx context.Context, doer *user_model.User, rel *repo_model return } - permission, _ := access_model.GetUserRepoPermission(ctx, rel.Repo, doer) + permission, _ := access_model.GetDoerRepoPermission(ctx, rel.Repo, doer) if err := PrepareWebhooks(ctx, EventSource{Repository: rel.Repo}, webhook_module.HookEventRelease, &api.ReleasePayload{ Action: action, Release: convert.ToAPIRelease(ctx, rel.Repo, rel), diff --git a/tests/integration/actions_job_token_test.go b/tests/integration/actions_job_token_test.go index f5a37380f1..14e2bfafb1 100644 --- a/tests/integration/actions_job_token_test.go +++ b/tests/integration/actions_job_token_test.go @@ -24,6 +24,7 @@ import ( "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -284,6 +285,65 @@ func TestActionsCrossRepoAccess(t *testing.T) { }) } +func TestActionsJobTokenPermissions(t *testing.T) { + defer tests.PrepareTestEnv(t)() + t.Run("WriteIssue", TestActionsJobTokenPermissionsWriteIssue) +} + +func TestActionsJobTokenPermissionsWriteIssue(t *testing.T) { + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) + task := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 53}) + require.Equal(t, repo.ID, task.RepoID) + + require.NoError(t, db.Insert(t.Context(), &repo_model.RepoUnit{ + RepoID: repo.ID, + Type: unit_model.TypeActions, + Config: &repo_model.ActionsConfig{}, + })) + + repoActionsUnit := repo.MustGetUnit(t.Context(), unit_model.TypeActions) + repoActionsCfg := repoActionsUnit.ActionsConfig() + repoActionsCfg.OverrideOwnerConfig = true + repoActionsCfg.TokenPermissionMode = repo_model.ActionsTokenPermissionModePermissive + repoActionsCfg.MaxTokenPermissions = nil + require.NoError(t, repo_model.UpdateRepoUnitConfig(t.Context(), repoActionsUnit)) + + require.NoError(t, task.GenerateToken()) + task.Status = actions_model.StatusRunning + require.NoError(t, actions_model.UpdateTask(t.Context(), task, "token_hash", "token_salt", "token_last_eight", "status")) + + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue, auth_model.AccessTokenScopeWriteRepository) + + labelURL := fmt.Sprintf("/api/v1/repos/%s/%s/labels", user.Name, repo.Name) + req := NewRequestWithJSON(t, "POST", labelURL, &structs.CreateLabelOption{ + Name: "task-label", + Color: "0e8a16", + }).AddTokenAuth(token) + resp := MakeRequest(t, req, http.StatusCreated) + label := DecodeJSON(t, resp, &structs.Label{}) + + issueURL := fmt.Sprintf("/api/v1/repos/%s/%s/issues", user.Name, repo.Name) + req = NewRequestWithJSON(t, "POST", issueURL, &structs.CreateIssueOption{ + Title: "issue for actions token label deletion", + }).AddTokenAuth(token) + resp = MakeRequest(t, req, http.StatusCreated) + issue := DecodeJSON(t, resp, &structs.Issue{}) + + taskToken := task.Token + require.NotEmpty(t, taskToken) + + issueLabelsURL := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", user.Name, repo.Name, issue.Index) + req = NewRequestWithJSON(t, "POST", issueLabelsURL, &structs.IssueLabelsOption{ + Labels: []any{label.ID}, + }).AddTokenAuth(taskToken) + MakeRequest(t, req, http.StatusOK) + + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%d", issueLabelsURL, label.ID)).AddTokenAuth(taskToken) + MakeRequest(t, req, http.StatusNoContent) +} + func createActionTask(t *testing.T, repoID int64, isFork bool) *actions_model.ActionTask { job := &actions_model.ActionRunJob{ RepoID: repoID, diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index bdec278426..51402b5098 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -498,7 +498,7 @@ func TestAPIPullReviewStayDismissed(t *testing.T) { pullIssue.ID, user8.ID, 1, 1, 2, false) // user8 dismiss review - permUser8, err := access_model.GetUserRepoPermission(t.Context(), pullIssue.Repo, user8) + permUser8, err := access_model.GetIndividualUserRepoPermission(t.Context(), pullIssue.Repo, user8) assert.NoError(t, err) _, err = issue_service.ReviewRequest(t.Context(), pullIssue, user8, &permUser8, user8, false) assert.NoError(t, err)