Skip to content

Commit 1f0375b

Browse files
committed
fix
1 parent 30008fc commit 1f0375b

File tree

5 files changed

+44
-5
lines changed

5 files changed

+44
-5
lines changed

custom/conf/app.example.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,9 +1040,13 @@ LEVEL = Info
10401040
;; Don't allow download source archive files from UI
10411041
;DISABLE_DOWNLOAD_SOURCE_ARCHIVES = false
10421042

1043-
;; Allow fork repositories without maximum number limit
1043+
;; Allow to fork repositories without maximum number limit
10441044
;ALLOW_FORK_WITHOUT_MAXIMUM_LIMIT = true
10451045

1046+
;; Allow to fork repositories into the same owner (user or organization)
1047+
;; This feature is experimental, not fully tested, and may be changed in the future
1048+
;ALLOW_FORK_INTO_SAME_OWNER = false
1049+
10461050
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10471051
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10481052
;[repository.editor]

modules/repository/fork.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,22 @@ import (
99
"code.gitea.io/gitea/models/organization"
1010
repo_model "code.gitea.io/gitea/models/repo"
1111
user_model "code.gitea.io/gitea/models/user"
12+
"code.gitea.io/gitea/modules/setting"
1213
)
1314

15+
func CanUserForkBetweenOwners(id1, id2 int64) bool {
16+
if id1 != id2 {
17+
return true
18+
}
19+
return setting.Repository.AllowForkIntoSameOwner
20+
}
21+
1422
// CanUserForkRepo returns true if specified user can fork repository.
1523
func CanUserForkRepo(ctx context.Context, user *user_model.User, repo *repo_model.Repository) (bool, error) {
1624
if user == nil {
1725
return false, nil
1826
}
19-
if repo.OwnerID != user.ID && !repo_model.HasForkedRepo(ctx, user.ID, repo.ID) {
27+
if CanUserForkBetweenOwners(repo.OwnerID, user.ID) && !repo_model.HasForkedRepo(ctx, user.ID, repo.ID) {
2028
return true, nil
2129
}
2230
ownedOrgs, err := organization.GetOrgsCanCreateRepoByUserID(ctx, user.ID)

modules/repository/fork_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package repository
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/modules/setting"
10+
"code.gitea.io/gitea/modules/test"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func TestCanUserForkBetweenOwners(t *testing.T) {
16+
defer test.MockVariableValue(&setting.Repository.AllowForkIntoSameOwner)
17+
18+
setting.Repository.AllowForkIntoSameOwner = true
19+
assert.True(t, CanUserForkBetweenOwners(1, 1))
20+
assert.True(t, CanUserForkBetweenOwners(1, 2))
21+
22+
setting.Repository.AllowForkIntoSameOwner = false
23+
assert.False(t, CanUserForkBetweenOwners(1, 1))
24+
assert.True(t, CanUserForkBetweenOwners(1, 2))
25+
}

modules/setting/repository.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ var (
5353
AllowDeleteOfUnadoptedRepositories bool
5454
DisableDownloadSourceArchives bool
5555
AllowForkWithoutMaximumLimit bool
56+
AllowForkIntoSameOwner bool
5657

5758
// Repository editor settings
5859
Editor struct {

routers/web/repo/fork.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"code.gitea.io/gitea/modules/base"
1717
"code.gitea.io/gitea/modules/log"
1818
"code.gitea.io/gitea/modules/optional"
19+
"code.gitea.io/gitea/modules/repository"
1920
"code.gitea.io/gitea/modules/setting"
2021
"code.gitea.io/gitea/modules/structs"
2122
"code.gitea.io/gitea/modules/web"
@@ -48,7 +49,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
4849
ctx.Data["repo_name"] = forkRepo.Name
4950
ctx.Data["description"] = forkRepo.Description
5051
ctx.Data["IsPrivate"] = forkRepo.IsPrivate || forkRepo.Owner.Visibility == structs.VisibleTypePrivate
51-
canForkToUser := forkRepo.OwnerID != ctx.Doer.ID && !repo_model.HasForkedRepo(ctx, ctx.Doer.ID, forkRepo.ID)
52+
canForkToUser := repository.CanUserForkBetweenOwners(forkRepo.OwnerID, ctx.Doer.ID) && !repo_model.HasForkedRepo(ctx, ctx.Doer.ID, forkRepo.ID)
5253

5354
ctx.Data["ForkRepo"] = forkRepo
5455

@@ -66,7 +67,7 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository {
6667

6768
traverseParentRepo := forkRepo
6869
for {
69-
if ctx.Doer.ID == traverseParentRepo.OwnerID {
70+
if !repository.CanUserForkBetweenOwners(ctx.Doer.ID, traverseParentRepo.OwnerID) {
7071
canForkToUser = false
7172
} else {
7273
for i, org := range orgs {
@@ -162,7 +163,7 @@ func ForkPost(ctx *context.Context) {
162163
var err error
163164
traverseParentRepo := forkRepo
164165
for {
165-
if ctxUser.ID == traverseParentRepo.OwnerID {
166+
if !repository.CanUserForkBetweenOwners(ctxUser.ID, traverseParentRepo.OwnerID) {
166167
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form)
167168
return
168169
}

0 commit comments

Comments
 (0)