From 9db4acc62e2d253c21ce9aed2e21003ff235d5b5 Mon Sep 17 00:00:00 2001 From: Unknwon Date: Sat, 8 Aug 2015 17:10:34 +0800 Subject: improve fork process --- routers/repo/pull.go | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) (limited to 'routers/repo/pull.go') diff --git a/routers/repo/pull.go b/routers/repo/pull.go index d379a54e..cb516703 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -5,14 +5,109 @@ package repo import ( + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/auth" "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" + "github.com/gogits/gogs/modules/setting" ) const ( + FORK base.TplName = "repo/pulls/fork" PULLS base.TplName = "repo/pulls" ) +func getForkRepository(ctx *middleware.Context) *models.Repository { + forkRepo, err := models.GetRepositoryById(ctx.ParamsInt64(":repoid")) + if err != nil { + if models.IsErrRepoNotExist(err) { + ctx.Handle(404, "GetRepositoryById", nil) + } else { + ctx.Handle(500, "GetRepositoryById", err) + } + return nil + } + ctx.Data["repo_name"] = forkRepo.Name + ctx.Data["desc"] = forkRepo.Description + ctx.Data["IsPrivate"] = forkRepo.IsPrivate + + if err = forkRepo.GetOwner(); err != nil { + ctx.Handle(500, "GetOwner", err) + return nil + } + ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name + + if err := ctx.User.GetOrganizations(); err != nil { + ctx.Handle(500, "GetOrganizations", err) + return nil + } + ctx.Data["Orgs"] = ctx.User.Orgs + + return forkRepo +} + +func Fork(ctx *middleware.Context) { + ctx.Data["Title"] = ctx.Tr("new_fork") + + getForkRepository(ctx) + if ctx.Written() { + return + } + + ctx.Data["ContextUser"] = ctx.User + ctx.HTML(200, FORK) +} + +func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) { + ctx.Data["Title"] = ctx.Tr("new_fork") + + forkRepo := getForkRepository(ctx) + if ctx.Written() { + return + } + + ctxUser := checkContextUser(ctx, form.Uid) + if ctx.Written() { + return + } + ctx.Data["ContextUser"] = ctxUser + + if ctx.HasError() { + ctx.HTML(200, FORK) + return + } + + // Check ownership of organization. + if ctxUser.IsOrganization() { + if !ctxUser.IsOwnedBy(ctx.User.Id) { + ctx.Error(403) + return + } + } + + repo, err := models.ForkRepository(ctxUser, forkRepo, form.RepoName, form.Description) + if err != nil { + switch { + case models.IsErrRepoAlreadyExist(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), FORK, &form) + case models.IsErrNameReserved(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(models.ErrNameReserved).Name), FORK, &form) + case models.IsErrNamePatternNotAllowed(err): + ctx.Data["Err_RepoName"] = true + ctx.RenderWithErr(ctx.Tr("repo.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), FORK, &form) + default: + ctx.Handle(500, "ForkPost", err) + } + return + } + + log.Trace("Repository forked[%d]: %s/%s", forkRepo.Id, ctxUser.Name, repo.Name) + ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) +} + func Pulls(ctx *middleware.Context) { ctx.Data["IsRepoToolbarPulls"] = true ctx.HTML(200, PULLS) -- cgit v1.2.3 From e3bdfd51ff4a3987c9c14d46d4c145f550b42d01 Mon Sep 17 00:00:00 2001 From: Unknwon Date: Sat, 8 Aug 2015 17:24:10 +0800 Subject: better fork permission check --- models/repo.go | 7 +++++++ routers/repo/pull.go | 6 ++++++ templates/repo/pulls/fork.tmpl | 2 ++ 3 files changed, 15 insertions(+) (limited to 'routers/repo/pull.go') diff --git a/models/repo.go b/models/repo.go index 910ccee3..8135bc57 100644 --- a/models/repo.go +++ b/models/repo.go @@ -1421,6 +1421,13 @@ func IsStaring(uid, repoId int64) bool { // \___ / \____/|__| |__|_ \ // \/ \/ +// HasForkedRepo checks if given user has already forked a repository with given ID. +func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) { + repo := new(Repository) + has, _ := x.Where("owner_id=? AND fork_id=?", ownerID, repoID).Get(repo) + return repo, has +} + func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) { repo := &Repository{ OwnerId: u.Id, diff --git a/routers/repo/pull.go b/routers/repo/pull.go index cb516703..a4ebb91a 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -78,6 +78,12 @@ func ForkPost(ctx *middleware.Context, form auth.CreateRepoForm) { return } + repo, has := models.HasForkedRepo(ctxUser.Id, forkRepo.Id) + if has { + ctx.Redirect(setting.AppSubUrl + "/" + ctxUser.Name + "/" + repo.Name) + return + } + // Check ownership of organization. if ctxUser.IsOrganization() { if !ctxUser.IsOwnedBy(ctx.User.Id) { diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl index acac9040..2f76cf00 100644 --- a/templates/repo/pulls/fork.tmpl +++ b/templates/repo/pulls/fork.tmpl @@ -24,11 +24,13 @@ {{.SignedUser.Name}} {{range .Orgs}} + {{if .IsOwnedBy $.SignedUser.Id}}
{{.Name}}
{{end}} + {{end}} -- cgit v1.2.3