From cdc46007255c0f6161aed6ec4ee7e0e11cf299e7 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 6 Nov 2017 12:12:55 +0800 Subject: [PATCH] Fix fork repository cycle to self (#2860) * fix fork repository cycle to self * rename testForkRepo to traverseParentRepo --- routers/repo/pull.go | 50 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/routers/repo/pull.go b/routers/repo/pull.go index f80e8cb1e..ac0d36c27 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -62,7 +62,6 @@ func getForkRepository(ctx *context.Context) *models.Repository { ctx.Data["description"] = forkRepo.Description ctx.Data["IsPrivate"] = forkRepo.IsPrivate canForkToUser := forkRepo.OwnerID != ctx.User.ID && !ctx.User.HasForkedRepo(forkRepo.ID) - ctx.Data["CanForkToUser"] = canForkToUser if err = forkRepo.GetOwner(); err != nil { ctx.Handle(500, "GetOwner", err) @@ -81,6 +80,31 @@ func getForkRepository(ctx *context.Context) *models.Repository { orgs = append(orgs, org) } } + + var traverseParentRepo = forkRepo + for { + if ctx.User.ID == traverseParentRepo.OwnerID { + canForkToUser = false + } else { + for i, org := range orgs { + if org.ID == traverseParentRepo.OwnerID { + orgs = append(orgs[:i], orgs[i+1:]...) + break + } + } + } + + if !traverseParentRepo.IsFork { + break + } + traverseParentRepo, err = models.GetRepositoryByID(traverseParentRepo.ForkID) + if err != nil { + ctx.Handle(500, "GetRepositoryByID", err) + return nil + } + } + + ctx.Data["CanForkToUser"] = canForkToUser ctx.Data["Orgs"] = orgs if canForkToUser { @@ -125,10 +149,26 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) { return } - repo, has := models.HasForkedRepo(ctxUser.ID, forkRepo.ID) - if has { - ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) - return + var err error + var traverseParentRepo = forkRepo + for { + if ctxUser.ID == traverseParentRepo.OwnerID { + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) + return + } + repo, has := models.HasForkedRepo(ctxUser.ID, traverseParentRepo.ID) + if has { + ctx.Redirect(setting.AppSubURL + "/" + ctxUser.Name + "/" + repo.Name) + return + } + if !traverseParentRepo.IsFork { + break + } + traverseParentRepo, err = models.GetRepositoryByID(traverseParentRepo.ForkID) + if err != nil { + ctx.Handle(500, "GetRepositoryByID", err) + return + } } // Check ownership of organization.