From 566e8ecce0df27e09d9f3ed9503f788827cc1102 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Mon, 18 Sep 2017 16:52:20 +0200 Subject: [PATCH] Fork permission bug fixes (#2534) * Hotfix for "Add time manually" (https://github.com/go-gitea/gitea/pull/2211#issuecomment-328780125) Signed-off-by: Jonas Franz * Checking if Code unit is enabled before creating a fork. Signed-off-by: Jonas Franz * Adding a discrete function for RepoIDAssignment Signed-off-by: Jonas Franz * Improved Documentation --- models/repo.go | 2 +- modules/context/repo.go | 68 ++++++++++++++++++++++++++++++++++++++++ routers/routes/routes.go | 6 ++-- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/models/repo.go b/models/repo.go index 4b3b0322d..4c844d9b5 100644 --- a/models/repo.go +++ b/models/repo.go @@ -638,7 +638,7 @@ func (repo *Repository) UpdateSize() error { // CanBeForked returns true if repository meets the requirements of being forked. func (repo *Repository) CanBeForked() bool { - return !repo.IsBare + return !repo.IsBare && repo.UnitEnabled(UnitTypeCode) } // CanEnablePulls returns true if repository meets the requirements of accepting pulls. diff --git a/modules/context/repo.go b/modules/context/repo.go index a82535a6d..acfccfcd0 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -171,6 +171,74 @@ func RedirectToRepo(ctx *Context, redirectRepoID int64) { ) ctx.Redirect(redirectPath) } +// RepoIDAssignment returns an macaron handler which assigns the repo to the context. +func RepoIDAssignment() macaron.Handler { + return func(ctx *Context) { + var ( + err error + ) + + repoID := ctx.ParamsInt64(":repoid") + + // Get repository. + repo, err := models.GetRepositoryByID(repoID) + if err != nil { + if models.IsErrRepoNotExist(err) { + ctx.Handle(404, "GetRepositoryByID", nil) + } else { + ctx.Handle(500, "GetRepositoryByID", err) + } + return + } + + if err = repo.GetOwner(); err != nil { + ctx.Handle(500, "GetOwner", err) + return + } + + // Admin has super access. + if ctx.IsSigned && ctx.User.IsAdmin { + ctx.Repo.AccessMode = models.AccessModeOwner + } else { + var userID int64 + if ctx.User != nil { + userID = ctx.User.ID + } + mode, err := models.AccessLevel(userID, repo) + if err != nil { + ctx.Handle(500, "AccessLevel", err) + return + } + ctx.Repo.AccessMode = mode + } + + // Check access. + if ctx.Repo.AccessMode == models.AccessModeNone { + if ctx.Query("go-get") == "1" { + earlyResponseForGoGetMeta(ctx) + return + } + ctx.Handle(404, "no access right", err) + return + } + ctx.Data["HasAccess"] = true + + if repo.IsMirror { + ctx.Repo.Mirror, err = models.GetMirrorByRepoID(repo.ID) + if err != nil { + ctx.Handle(500, "GetMirror", err) + return + } + ctx.Data["MirrorEnablePrune"] = ctx.Repo.Mirror.EnablePrune + ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval + ctx.Data["Mirror"] = ctx.Repo.Mirror + } + + ctx.Repo.Repository = repo + ctx.Data["RepoName"] = ctx.Repo.Repository.Name + ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare + } +} // RepoAssignment returns a macaron to handle repository assignment func RepoAssignment() macaron.Handler { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index a0684c847..c5d6793ff 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -419,8 +419,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost) m.Get("/migrate", repo.Migrate) m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost) - m.Combo("/fork/:repoid").Get(repo.Fork). - Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) + m.Group("/fork", func() { + m.Combo("/:repoid").Get(repo.Fork). + Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost) + }, context.RepoIDAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeCode)) }, reqSignIn) m.Group("/:username/:reponame", func() {