From 91788e0200aa9fdad32fec8f2aaee629be9d24aa Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Tue, 19 Sep 2017 01:12:29 +0200 Subject: [PATCH] Restricting access to fork functioanlity to users with Code access (#2542) Signed-off-by: Jonas Franz --- models/repo.go | 2 +- modules/context/repo.go | 69 ++++++++++++++++++++++++++++++++++++++++ routers/routes/routes.go | 6 ++-- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/models/repo.go b/models/repo.go index afe9668fc..fcb08f2d6 100644 --- a/models/repo.go +++ b/models/repo.go @@ -648,7 +648,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 b16d18842..72e922aaf 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -162,6 +162,75 @@ 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 { return func(ctx *Context) { diff --git a/routers/routes/routes.go b/routers/routes/routes.go index d765c4c03..e3db3d4f2 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -416,8 +416,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() {