Skip to content

Commit 67aa916

Browse files
committed
move check to lower functions
add admin exemption and custom error for the case
1 parent ef50263 commit 67aa916

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed

routers/api/v1/repo/transfer.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,6 @@ func Transfer(ctx *context.APIContext) {
6868
return
6969
}
7070

71-
if !newOwner.CanCreateRepo() {
72-
ctx.APIError(http.StatusForbidden, "The new owner cannot have more repositories")
73-
return
74-
}
75-
7671
if newOwner.Type == user_model.UserTypeOrganization {
7772
if !ctx.Doer.IsAdmin && newOwner.Visibility == api.VisibleTypePrivate && !organization.OrgFromUser(newOwner).HasMemberWithUserID(ctx, ctx.Doer.ID) {
7873
// The user shouldn't know about this organization
@@ -123,6 +118,11 @@ func Transfer(ctx *context.APIContext) {
123118
return
124119
}
125120

121+
if repo_service.IsRepositoryLimitReached(err) {
122+
ctx.APIError(http.StatusForbidden, err)
123+
return
124+
}
125+
126126
if errors.Is(err, user_model.ErrBlockedUser) {
127127
ctx.APIError(http.StatusForbidden, err)
128128
} else {
@@ -174,6 +174,8 @@ func AcceptTransfer(ctx *context.APIContext) {
174174
ctx.APIError(http.StatusNotFound, err)
175175
case errors.Is(err, util.ErrPermissionDenied):
176176
ctx.APIError(http.StatusForbidden, err)
177+
case repo_service.IsRepositoryLimitReached(err):
178+
ctx.APIError(http.StatusForbidden, err)
177179
default:
178180
ctx.APIErrorInternal(err)
179181
}

routers/web/repo/repo.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,15 @@ func CreatePost(ctx *context.Context) {
305305
}
306306

307307
func handleActionError(ctx *context.Context, err error) {
308-
if errors.Is(err, user_model.ErrBlockedUser) {
308+
switch {
309+
case errors.Is(err, user_model.ErrBlockedUser):
309310
ctx.Flash.Error(ctx.Tr("repo.action.blocked_user"))
310-
} else if errors.Is(err, util.ErrPermissionDenied) {
311+
case repo_service.IsRepositoryLimitReached(err):
312+
limit := err.(repo_service.RepositoryLimitReachedError).Limit
313+
ctx.Flash.Error(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit))
314+
case errors.Is(err, util.ErrPermissionDenied):
311315
ctx.HTTPError(http.StatusNotFound)
312-
} else {
316+
default:
313317
ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam("action")), err)
314318
}
315319
}

routers/web/repo/setting/setting.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -864,12 +864,6 @@ func handleSettingsPostTransfer(ctx *context.Context) {
864864
return
865865
}
866866

867-
if !newOwner.CanCreateRepo() {
868-
limit := util.Iif(newOwner.MaxRepoCreation >= 0, newOwner.MaxRepoCreation, setting.Repository.MaxCreationLimit)
869-
ctx.RenderWithErr(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit), tplSettingsOptions, nil)
870-
return
871-
}
872-
873867
if newOwner.Type == user_model.UserTypeOrganization {
874868
if !ctx.Doer.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !organization.OrgFromUser(newOwner).HasMemberWithUserID(ctx, ctx.Doer.ID) {
875869
// The user shouldn't know about this organization
@@ -890,6 +884,9 @@ func handleSettingsPostTransfer(ctx *context.Context) {
890884
ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil)
891885
} else if repo_model.IsErrRepoTransferInProgress(err) {
892886
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil)
887+
} else if repo_service.IsRepositoryLimitReached(err) {
888+
limit := err.(repo_service.RepositoryLimitReachedError).Limit
889+
ctx.RenderWithErr(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit), tplSettingsOptions, nil)
893890
} else if errors.Is(err, user_model.ErrBlockedUser) {
894891
ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil)
895892
} else {

services/repository/transfer.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,22 @@ import (
2020
"code.gitea.io/gitea/modules/gitrepo"
2121
"code.gitea.io/gitea/modules/globallock"
2222
"code.gitea.io/gitea/modules/log"
23+
"code.gitea.io/gitea/modules/setting"
2324
"code.gitea.io/gitea/modules/util"
2425
notify_service "code.gitea.io/gitea/services/notify"
2526
)
2627

28+
type RepositoryLimitReachedError struct{ Limit int }
29+
30+
func (RepositoryLimitReachedError) Error() string {
31+
return "Repository limit has been reached"
32+
}
33+
34+
func IsRepositoryLimitReached(err error) bool {
35+
_, ok := err.(RepositoryLimitReachedError)
36+
return ok
37+
}
38+
2739
func getRepoWorkingLockKey(repoID int64) string {
2840
return fmt.Sprintf("repo_working_%d", repoID)
2941
}
@@ -42,6 +54,11 @@ func AcceptTransferOwnership(ctx context.Context, repo *repo_model.Repository, d
4254
return err
4355
}
4456

57+
if !doer.IsAdmin && !repoTransfer.Recipient.CanCreateRepo() {
58+
limit := util.Iif(repoTransfer.Recipient.MaxRepoCreation >= 0, repoTransfer.Recipient.MaxRepoCreation, setting.Repository.MaxCreationLimit)
59+
return RepositoryLimitReachedError{Limit: limit}
60+
}
61+
4562
oldOwnerName := repo.OwnerName
4663

4764
if err := db.WithTx(ctx, func(ctx context.Context) error {
@@ -399,6 +416,11 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use
399416
return err
400417
}
401418

419+
if !doer.IsAdmin && !newOwner.CanCreateRepo() {
420+
limit := util.Iif(newOwner.MaxRepoCreation >= 0, newOwner.MaxRepoCreation, setting.Repository.MaxCreationLimit)
421+
return RepositoryLimitReachedError{Limit: limit}
422+
}
423+
402424
var isDirectTransfer bool
403425
oldOwnerName := repo.OwnerName
404426

0 commit comments

Comments
 (0)