Skip to content

Commit 91788e0

Browse files
jonasfranzbkcsoft
authored andcommitted
Restricting access to fork functioanlity to users with Code access (#2542)
Signed-off-by: Jonas Franz <[email protected]>
1 parent fc0c6f4 commit 91788e0

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

models/repo.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ func (repo *Repository) UpdateSize() error {
648648

649649
// CanBeForked returns true if repository meets the requirements of being forked.
650650
func (repo *Repository) CanBeForked() bool {
651-
return !repo.IsBare
651+
return !repo.IsBare && repo.UnitEnabled(UnitTypeCode)
652652
}
653653

654654
// CanEnablePulls returns true if repository meets the requirements of accepting pulls.

modules/context/repo.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,75 @@ func RedirectToRepo(ctx *Context, redirectRepoID int64) {
162162
ctx.Redirect(redirectPath)
163163
}
164164

165+
// RepoIDAssignment returns an macaron handler which assigns the repo to the context.
166+
func RepoIDAssignment() macaron.Handler {
167+
return func(ctx *Context) {
168+
var (
169+
err error
170+
)
171+
172+
repoID := ctx.ParamsInt64(":repoid")
173+
174+
// Get repository.
175+
repo, err := models.GetRepositoryByID(repoID)
176+
if err != nil {
177+
if models.IsErrRepoNotExist(err) {
178+
ctx.Handle(404, "GetRepositoryByID", nil)
179+
} else {
180+
ctx.Handle(500, "GetRepositoryByID", err)
181+
}
182+
return
183+
}
184+
185+
if err = repo.GetOwner(); err != nil {
186+
ctx.Handle(500, "GetOwner", err)
187+
return
188+
}
189+
190+
// Admin has super access.
191+
if ctx.IsSigned && ctx.User.IsAdmin {
192+
ctx.Repo.AccessMode = models.AccessModeOwner
193+
} else {
194+
var userID int64
195+
if ctx.User != nil {
196+
userID = ctx.User.ID
197+
}
198+
mode, err := models.AccessLevel(userID, repo)
199+
if err != nil {
200+
ctx.Handle(500, "AccessLevel", err)
201+
return
202+
}
203+
ctx.Repo.AccessMode = mode
204+
}
205+
206+
// Check access.
207+
if ctx.Repo.AccessMode == models.AccessModeNone {
208+
if ctx.Query("go-get") == "1" {
209+
earlyResponseForGoGetMeta(ctx)
210+
return
211+
}
212+
ctx.Handle(404, "no access right", err)
213+
return
214+
}
215+
ctx.Data["HasAccess"] = true
216+
217+
if repo.IsMirror {
218+
ctx.Repo.Mirror, err = models.GetMirrorByRepoID(repo.ID)
219+
if err != nil {
220+
ctx.Handle(500, "GetMirror", err)
221+
return
222+
}
223+
ctx.Data["MirrorEnablePrune"] = ctx.Repo.Mirror.EnablePrune
224+
ctx.Data["MirrorInterval"] = ctx.Repo.Mirror.Interval
225+
ctx.Data["Mirror"] = ctx.Repo.Mirror
226+
}
227+
228+
ctx.Repo.Repository = repo
229+
ctx.Data["RepoName"] = ctx.Repo.Repository.Name
230+
ctx.Data["IsBareRepo"] = ctx.Repo.Repository.IsBare
231+
}
232+
}
233+
165234
// RepoAssignment returns a macaron to handle repository assignment
166235
func RepoAssignment() macaron.Handler {
167236
return func(ctx *Context) {

routers/routes/routes.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,10 @@ func RegisterRoutes(m *macaron.Macaron) {
416416
m.Post("/create", bindIgnErr(auth.CreateRepoForm{}), repo.CreatePost)
417417
m.Get("/migrate", repo.Migrate)
418418
m.Post("/migrate", bindIgnErr(auth.MigrateRepoForm{}), repo.MigratePost)
419-
m.Combo("/fork/:repoid").Get(repo.Fork).
420-
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
419+
m.Group("/fork", func() {
420+
m.Combo("/:repoid").Get(repo.Fork).
421+
Post(bindIgnErr(auth.CreateRepoForm{}), repo.ForkPost)
422+
}, context.RepoIDAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeCode))
421423
}, reqSignIn)
422424

423425
m.Group("/:username/:reponame", func() {

0 commit comments

Comments
 (0)