fix: consider issues in repository accessible via access table ()

- Consider the following scenario: a private repository in an organization with a team that has no specific access to that repository. Members of that team are still able to visit the repository because of entries in the `access` table.
- Consider this specific scenario for the gathering of issues for project tables.
- Unit test added
- Resolves 
- Ref: 

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7270
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
(cherry picked from commit 72ee7f3b00)
This commit is contained in:
Gusted 2025-03-19 16:45:42 +00:00 committed by forgejo-backport-action
parent 400bd08cfe
commit c1e9fd738b
6 changed files with 92 additions and 0 deletions

View file

@ -0,0 +1,5 @@
-
id: 1001
user_id: 29
repo_id: 3
mode: 1

View file

@ -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

View file

@ -0,0 +1,8 @@
-
id: 1001
project_id: 1001
title: Triage
creator_id: 2
default: true
created_unix: 1738000000
updated_unix: 1738000000

View file

@ -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

View file

@ -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)
})
}

View file

@ -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
),
)
}