mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-21 08:31:27 -05:00
fix: check read permissions for code owner review requests
- Only send a review request based on the code owner file if the code owner user has read permissions to the pull requests of that repository. - This avoids leaking title of PRs from private repository when a CODEOWNER file is present which contains users that do not have access to the private repository. - Found by @oliverpool. - Integration test added.
This commit is contained in:
parent
8e94947ed9
commit
693f7731f9
2 changed files with 45 additions and 1 deletions
|
@ -10,6 +10,8 @@ import (
|
||||||
|
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
org_model "code.gitea.io/gitea/models/organization"
|
org_model "code.gitea.io/gitea/models/organization"
|
||||||
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
|
"code.gitea.io/gitea/models/unit"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/gitrepo"
|
"code.gitea.io/gitea/modules/gitrepo"
|
||||||
|
@ -117,7 +119,11 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, u := range uniqUsers {
|
for _, u := range uniqUsers {
|
||||||
if u.ID != issue.Poster.ID {
|
permission, err := access_model.GetUserRepoPermission(ctx, issue.Repo, u)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("GetUserRepoPermission: %w", err)
|
||||||
|
}
|
||||||
|
if u.ID != issue.Poster.ID && permission.CanRead(unit.TypePullRequests) {
|
||||||
comment, err := issues_model.AddReviewRequest(ctx, issue, u, issue.Poster)
|
comment, err := issues_model.AddReviewRequest(ctx, issue, u, issue.Poster)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed add assignee user: %s to PR review: %s#%d, error: %s", u.Name, pr.BaseRepo.Name, pr.ID, err)
|
log.Warn("Failed add assignee user: %s to PR review: %s#%d, error: %s", u.Name, pr.BaseRepo.Name, pr.ID, err)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
unit_model "code.gitea.io/gitea/models/unit"
|
unit_model "code.gitea.io/gitea/models/unit"
|
||||||
|
@ -159,5 +160,42 @@ func TestCodeOwner(t *testing.T) {
|
||||||
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "branch"})
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "branch"})
|
||||||
unittest.AssertExistsIf(t, true, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 4})
|
unittest.AssertExistsIf(t, true, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 4})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Codeowner user with no permission", func(t *testing.T) {
|
||||||
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
|
// Make repository private, only user2 (owner of repository) has now access to this repository.
|
||||||
|
repo.IsPrivate = true
|
||||||
|
_, err := db.GetEngine(db.DefaultContext).Cols("is_private").Update(repo)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = os.WriteFile(path.Join(dstPath, "README.md"), []byte("## very senstive info"), 0o666)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = git.AddChanges(dstPath, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = git.CommitChanges(dstPath, git.CommitChangesOptions{
|
||||||
|
Committer: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "user2",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Author: &git.Signature{
|
||||||
|
Email: "user2@example.com",
|
||||||
|
Name: "user2",
|
||||||
|
When: time.Now(),
|
||||||
|
},
|
||||||
|
Message: "Add secrets to the README.",
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = git.NewCommand(git.DefaultContext, "push", "origin", "HEAD:refs/for/main", "-o", "topic=codeowner-private").Run(&git.RunOpts{Dir: dstPath})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// In CODEOWNERS file the codeowner for README.md is user5, but does not have access to this private repository.
|
||||||
|
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{BaseRepoID: repo.ID, HeadBranch: "user2/codeowner-private"})
|
||||||
|
unittest.AssertExistsIf(t, false, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 5})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue