diff --git a/models/fixtures/project.yml b/models/fixtures/project.yml index 44d87bce04..54a3061859 100644 --- a/models/fixtures/project.yml +++ b/models/fixtures/project.yml @@ -42,7 +42,7 @@ is_closed: false creator_id: 2 board_type: 1 - type: 2 + type: 1 created_unix: 1688973000 updated_unix: 1688973000 @@ -54,7 +54,7 @@ is_closed: false creator_id: 2 board_type: 1 - type: 2 + type: 1 created_unix: 1688973000 updated_unix: 1688973000 @@ -66,6 +66,18 @@ is_closed: false creator_id: 2 board_type: 1 - type: 2 + type: 1 + created_unix: 1688973000 + updated_unix: 1688973000 + +- + id: 7 + title: project on org3 + owner_id: 3 + repo_id: 0 + is_closed: false + creator_id: 2 + board_type: 1 + type: 1 created_unix: 1688973000 updated_unix: 1688973000 diff --git a/models/project/project_test.go b/models/project/project_test.go index ab23bab0bf..b6f7c7db27 100644 --- a/models/project/project_test.go +++ b/models/project/project_test.go @@ -93,19 +93,19 @@ func TestProjectsSort(t *testing.T) { }{ { sortType: "default", - wants: []int64{1, 3, 2, 6, 5, 4}, + wants: []int64{1, 3, 2, 7, 6, 5, 4}, }, { sortType: "oldest", - wants: []int64{4, 5, 6, 2, 3, 1}, + wants: []int64{4, 5, 6, 7, 2, 3, 1}, }, { sortType: "recentupdate", - wants: []int64{1, 3, 2, 6, 5, 4}, + wants: []int64{1, 3, 2, 7, 6, 5, 4}, }, { sortType: "leastupdate", - wants: []int64{4, 5, 6, 2, 3, 1}, + wants: []int64{4, 5, 6, 7, 2, 3, 1}, }, } @@ -114,8 +114,8 @@ func TestProjectsSort(t *testing.T) { OrderBy: GetSearchOrderByBySortType(tt.sortType), }) require.NoError(t, err) - assert.Equal(t, int64(6), count) - if assert.Len(t, projects, 6) { + assert.Equal(t, int64(7), count) + if assert.Len(t, projects, 7) { for i := range projects { assert.Equal(t, tt.wants[i], projects[i].ID) } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index a8a1c69ab6..1fef838516 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -989,8 +989,10 @@ func NewIssue(ctx *context.Context) { project, err := project_model.GetProjectByID(ctx, projectID) if err != nil { log.Error("GetProjectByID: %d: %v", projectID, err) - } else if project.RepoID != ctx.Repo.Repository.ID { - log.Error("GetProjectByID: %d: %v", projectID, fmt.Errorf("project[%d] not in repo [%d]", project.ID, ctx.Repo.Repository.ID)) + } else if !project.CanBeAccessedByOwnerRepo(ctx.Repo.Repository.OwnerID, ctx.Repo.Repository) { + log.Error("GetProjectByID: %d: %v", projectID, + fmt.Errorf("project[%d] neither in repo[%d] nor has the same owner (project: [%d] ./. repo: [%d])", + project.ID, ctx.Repo.Repository.ID, project.OwnerID, ctx.Repo.Repository.OwnerID)) } else { ctx.Data["project_id"] = projectID ctx.Data["Project"] = project diff --git a/routers/web/repo/issue_test.go b/routers/web/repo/issue_test.go new file mode 100644 index 0000000000..3644dd131f --- /dev/null +++ b/routers/web/repo/issue_test.go @@ -0,0 +1,89 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "fmt" + "testing" + + "forgejo.org/models/unittest" + "forgejo.org/services/contexttest" + + "github.com/stretchr/testify/assert" +) + +func TestNewIssueValidateProject(t *testing.T) { + unittest.PrepareTestEnv(t) + + for _, testCase := range []struct { + name string + projectID int64 + userName string + userID int64 + repoName string + repoID int64 + isFound bool + }{ + { + name: "Project belongs to repository", + projectID: 1, + userName: "user2", + userID: 2, + repoName: "repo1", + repoID: 1, + isFound: true, + }, + { + name: "Project belongs to user", + projectID: 4, + userName: "user2", + userID: 2, + repoName: "repo1", + repoID: 1, + isFound: true, + }, + { + name: "Project belongs to org", + projectID: 7, + userName: "org3", + userID: 3, + repoName: "repo3", + repoID: 3, + isFound: true, + }, + { + name: "Project neither belongs to repo nor the user", + projectID: 2, + userName: "user2", + userID: 2, + repoName: "repo1", + repoID: 1, + isFound: false, + }, + } { + t.Run(testCase.name, func(t *testing.T) { + ctx, _ := contexttest.MockContext( + t, fmt.Sprintf( + "/%s/%s/issues/new?project=%d", + testCase.userName, + testCase.repoName, + testCase.projectID, + ), + ) + contexttest.LoadUser(t, ctx, testCase.userID) + contexttest.LoadRepo(t, ctx, testCase.repoID) + contexttest.LoadGitRepo(t, ctx) + + NewIssue(ctx) + + if testCase.isFound { + assert.Equal(t, testCase.projectID, ctx.Data["project_id"]) + assert.NotNil(t, ctx.Data["Project"]) + } else { + assert.Nil(t, ctx.Data["project_id"]) + assert.Nil(t, ctx.Data["Project"]) + } + }) + } +}