diff --git a/models/fixtures/TestPrivateRepoProjects/access.yml b/models/fixtures/TestPrivateRepoProjects/access.yml new file mode 100644 index 0000000000..4149e34b0b --- /dev/null +++ b/models/fixtures/TestPrivateRepoProjects/access.yml @@ -0,0 +1,5 @@ +- + id: 1001 + user_id: 29 + repo_id: 3 + mode: 1 diff --git a/models/fixtures/TestPrivateRepoProjects/project.yml b/models/fixtures/TestPrivateRepoProjects/project.yml new file mode 100644 index 0000000000..f66e4c8676 --- /dev/null +++ b/models/fixtures/TestPrivateRepoProjects/project.yml @@ -0,0 +1,11 @@ +- + id: 1001 + title: Org project that contains private issues + owner_id: 3 + repo_id: 0 + is_closed: false + creator_id: 2 + board_type: 1 + type: 3 + created_unix: 1738000000 + updated_unix: 1738000000 diff --git a/models/fixtures/TestPrivateRepoProjects/project_board.yml b/models/fixtures/TestPrivateRepoProjects/project_board.yml new file mode 100644 index 0000000000..9829cf7e27 --- /dev/null +++ b/models/fixtures/TestPrivateRepoProjects/project_board.yml @@ -0,0 +1,8 @@ +- + id: 1001 + project_id: 1001 + title: Triage + creator_id: 2 + default: true + created_unix: 1738000000 + updated_unix: 1738000000 diff --git a/models/fixtures/TestPrivateRepoProjects/project_issue.yml b/models/fixtures/TestPrivateRepoProjects/project_issue.yml new file mode 100644 index 0000000000..3e8c1dca9e --- /dev/null +++ b/models/fixtures/TestPrivateRepoProjects/project_issue.yml @@ -0,0 +1,11 @@ +- + id: 1001 + issue_id: 6 + project_id: 1001 + project_board_id: 1001 + +- + id: 1002 + issue_id: 15 + project_id: 1001 + project_board_id: 1001 diff --git a/models/issues/issue_project_test.go b/models/issues/issue_project_test.go index e28b52128e..d724922946 100644 --- a/models/issues/issue_project_test.go +++ b/models/issues/issue_project_test.go @@ -117,3 +117,57 @@ func TestPrivateIssueProjects(t *testing.T) { }) }) } + +func TestPrivateRepoProjects(t *testing.T) { + defer tests.AddFixtures("models/fixtures/TestPrivateRepoProjects/")() + require.NoError(t, unittest.PrepareTestDatabase()) + + org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) + orgProject := unittest.AssertExistsAndLoadBean(t, &project.Project{ID: 1001, OwnerID: org.ID}) + column := unittest.AssertExistsAndLoadBean(t, &project.Column{ID: 1001, ProjectID: orgProject.ID}) + + t.Run("Partial access", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}) + + issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user29, org, optional.None[bool]()) + require.NoError(t, err) + assert.Len(t, issueList, 1) + assert.EqualValues(t, 6, issueList[0].ID) + + issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.None[bool]()) + require.NoError(t, err) + assert.EqualValues(t, 1, issuesNum) + + issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.Some(true)) + require.NoError(t, err) + assert.EqualValues(t, 0, issuesNum) + + issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.Some(false)) + require.NoError(t, err) + assert.EqualValues(t, 1, issuesNum) + }) + + t.Run("Full access", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + + issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, org, optional.None[bool]()) + require.NoError(t, err) + assert.Len(t, issueList, 2) + assert.EqualValues(t, 15, issueList[0].ID) + assert.EqualValues(t, 6, issueList[1].ID) + + issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.None[bool]()) + require.NoError(t, err) + assert.EqualValues(t, 2, issuesNum) + + issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(true)) + require.NoError(t, err) + assert.EqualValues(t, 0, issuesNum) + + issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(false)) + require.NoError(t, err) + assert.EqualValues(t, 2, issuesNum) + }) +} diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 56c219af39..6592f3708c 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -341,6 +341,9 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati builder.Or( repo_model.UserOrgUnitRepoCond(repoIDstr, userID, org.ID, unitType), // team member repos repo_model.UserOrgPublicUnitRepoCond(userID, org.ID), // user org public non-member repos, TODO: check repo has issues + builder.And( + builder.In("issue.repo_id", builder.Select("id").From("repository").Where(builder.Eq{"owner_id": org.ID})), + repo_model.UserAccessRepoCond(repoIDstr, userID)), // user can access org repo in a unit independent way ), ) }