diff options
Diffstat (limited to 'routers/api/v1/api.go')
-rw-r--r-- | routers/api/v1/api.go | 142 |
1 files changed, 88 insertions, 54 deletions
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 0be8f84836..47e556c881 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1,5 +1,5 @@ // Copyright 2015 The Gogs Authors. All rights reserved. -// Copyright 2018 The Gitea Authors. All rights reserved. +// Copyright 2016 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -71,7 +71,6 @@ import ( "code.gitea.io/gitea/routers/api/v1/repo" _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation "code.gitea.io/gitea/routers/api/v1/user" - "code.gitea.io/gitea/routers/api/v1/utils" api "code.gitea.io/sdk/gitea" "github.com/go-macaron/binding" @@ -152,24 +151,18 @@ func repoAssignment() macaron.Handler { return } repo.Owner = owner + ctx.Repo.Repository = repo - if ctx.IsSigned && ctx.User.IsAdmin { - ctx.Repo.AccessMode = models.AccessModeOwner - } else { - mode, err := models.AccessLevel(utils.UserID(ctx), repo) - if err != nil { - ctx.Error(500, "AccessLevel", err) - return - } - ctx.Repo.AccessMode = mode + ctx.Repo.Permission, err = models.GetUserRepoPermission(repo, ctx.User) + if err != nil { + ctx.Error(500, "GetUserRepoPermission", err) + return } if !ctx.Repo.HasAccess() { ctx.Status(404) return } - - ctx.Repo.Repository = repo } } @@ -196,7 +189,8 @@ func reqBasicAuth() macaron.Handler { } } -func reqAdmin() macaron.Handler { +// reqSiteAdmin user should be the site admin +func reqSiteAdmin() macaron.Handler { return func(ctx *context.Context) { if !ctx.IsSigned || !ctx.User.IsAdmin { ctx.Error(403) @@ -205,15 +199,56 @@ func reqAdmin() macaron.Handler { } } -func reqRepoWriter() macaron.Handler { +// reqOwner user should be the owner of the repo. +func reqOwner() macaron.Handler { + return func(ctx *context.Context) { + if !ctx.Repo.IsOwner() { + ctx.Error(403) + return + } + } +} + +// reqAdmin user should be an owner or a collaborator with admin write of a repository +func reqAdmin() macaron.Handler { + return func(ctx *context.Context) { + if !ctx.Repo.IsAdmin() { + ctx.Error(403) + return + } + } +} + +func reqRepoReader(unitType models.UnitType) macaron.Handler { + return func(ctx *context.Context) { + if !ctx.Repo.CanRead(unitType) { + ctx.Error(403) + return + } + } +} + +func reqAnyRepoReader() macaron.Handler { return func(ctx *context.Context) { - if !ctx.Repo.IsWriter() { + if !ctx.Repo.HasAccess() { ctx.Error(403) return } } } +func reqRepoWriter(unitTypes ...models.UnitType) macaron.Handler { + return func(ctx *context.Context) { + for _, unitType := range unitTypes { + if ctx.Repo.CanWrite(unitType) { + return + } + } + + ctx.Error(403) + } +} + func reqOrgMembership() macaron.Handler { return func(ctx *context.APIContext) { var orgID int64 @@ -308,22 +343,22 @@ func orgAssignment(args ...bool) macaron.Handler { } func mustEnableIssues(ctx *context.APIContext) { - if !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) { + if !ctx.Repo.CanRead(models.UnitTypeIssues) { ctx.Status(404) return } } func mustAllowPulls(ctx *context.Context) { - if !ctx.Repo.Repository.AllowsPulls() { + if !(ctx.Repo.Repository.CanEnablePulls() && ctx.Repo.CanRead(models.UnitTypePullRequests)) { ctx.Status(404) return } } func mustEnableIssuesOrPulls(ctx *context.Context) { - if !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) && - !ctx.Repo.Repository.AllowsPulls() { + if !ctx.Repo.CanRead(models.UnitTypeIssues) && + !(ctx.Repo.Repository.CanEnablePulls() && ctx.Repo.CanRead(models.UnitTypePullRequests)) { ctx.Status(404) return } @@ -443,7 +478,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/migrate", reqToken(), bind(auth.MigrateRepoForm{}), repo.Migrate) m.Group("/:username/:reponame", func() { - m.Combo("").Get(repo.Get).Delete(reqToken(), repo.Delete) + m.Combo("").Get(reqAnyRepoReader(), repo.Get). + Delete(reqToken(), reqOwner(), repo.Delete) m.Group("/hooks", func() { m.Combo("").Get(repo.ListHooks). Post(bind(api.CreateHookOption{}), repo.CreateHook) @@ -453,31 +489,30 @@ func RegisterRoutes(m *macaron.Macaron) { Delete(repo.DeleteHook) m.Post("/tests", context.RepoRef(), repo.TestHook) }) - }, reqToken(), reqRepoWriter()) + }, reqToken(), reqAdmin()) m.Group("/collaborators", func() { m.Get("", repo.ListCollaborators) m.Combo("/:collaborator").Get(repo.IsCollaborator). Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator). Delete(repo.DeleteCollaborator) - }, reqToken()) - m.Get("/raw/*", context.RepoRefByType(context.RepoRefAny), repo.GetRawFile) - m.Get("/archive/*", repo.GetArchive) + }, reqToken(), reqAdmin()) + m.Get("/raw/*", context.RepoRefByType(context.RepoRefAny), reqRepoReader(models.UnitTypeCode), repo.GetRawFile) + m.Get("/archive/*", reqRepoReader(models.UnitTypeCode), repo.GetArchive) m.Combo("/forks").Get(repo.ListForks). - Post(reqToken(), bind(api.CreateForkOption{}), repo.CreateFork) + Post(reqToken(), reqRepoReader(models.UnitTypeCode), bind(api.CreateForkOption{}), repo.CreateFork) m.Group("/branches", func() { m.Get("", repo.ListBranches) m.Get("/*", context.RepoRefByType(context.RepoRefBranch), repo.GetBranch) - }) + }, reqRepoReader(models.UnitTypeCode)) m.Group("/keys", func() { m.Combo("").Get(repo.ListDeployKeys). Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey) m.Combo("/:id").Get(repo.GetDeployKey). Delete(repo.DeleteDeploykey) - }, reqToken(), reqRepoWriter()) + }, reqToken(), reqAdmin()) m.Group("/times", func() { m.Combo("").Get(repo.ListTrackedTimesByRepository) m.Combo("/:timetrackingusername").Get(repo.ListTrackedTimesByUser) - }, mustEnableIssues) m.Group("/issues", func() { m.Combo("").Get(repo.ListIssues). @@ -517,17 +552,17 @@ func RegisterRoutes(m *macaron.Macaron) { }, mustEnableIssuesOrPulls) m.Group("/labels", func() { m.Combo("").Get(repo.ListLabels). - Post(reqToken(), bind(api.CreateLabelOption{}), repo.CreateLabel) + Post(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) m.Combo("/:id").Get(repo.GetLabel). - Patch(reqToken(), bind(api.EditLabelOption{}), repo.EditLabel). - Delete(reqToken(), repo.DeleteLabel) + Patch(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.EditLabelOption{}), repo.EditLabel). + Delete(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), repo.DeleteLabel) }) m.Group("/milestones", func() { m.Combo("").Get(repo.ListMilestones). - Post(reqToken(), reqRepoWriter(), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) + Post(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.CreateMilestoneOption{}), repo.CreateMilestone) m.Combo("/:id").Get(repo.GetMilestone). - Patch(reqToken(), reqRepoWriter(), bind(api.EditMilestoneOption{}), repo.EditMilestone). - Delete(reqToken(), reqRepoWriter(), repo.DeleteMilestone) + Patch(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone). + Delete(reqToken(), reqRepoWriter(models.UnitTypeIssues, models.UnitTypePullRequests), repo.DeleteMilestone) }) m.Get("/stargazers", repo.ListStargazers) m.Get("/subscribers", repo.ListSubscribers) @@ -538,45 +573,44 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Group("/releases", func() { m.Combo("").Get(repo.ListReleases). - Post(reqToken(), reqRepoWriter(), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) + Post(reqToken(), reqRepoWriter(models.UnitTypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease) m.Group("/:id", func() { m.Combo("").Get(repo.GetRelease). - Patch(reqToken(), reqRepoWriter(), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). - Delete(reqToken(), reqRepoWriter(), repo.DeleteRelease) + Patch(reqToken(), reqRepoWriter(models.UnitTypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease). + Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteRelease) m.Group("/assets", func() { m.Combo("").Get(repo.ListReleaseAttachments). - Post(reqToken(), reqRepoWriter(), repo.CreateReleaseAttachment) + Post(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.CreateReleaseAttachment) m.Combo("/:asset").Get(repo.GetReleaseAttachment). - Patch(reqToken(), reqRepoWriter(), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). - Delete(reqToken(), reqRepoWriter(), repo.DeleteReleaseAttachment) + Patch(reqToken(), reqRepoWriter(models.UnitTypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment). + Delete(reqToken(), reqRepoWriter(models.UnitTypeReleases), repo.DeleteReleaseAttachment) }) }) - }) - m.Post("/mirror-sync", reqToken(), reqRepoWriter(), repo.MirrorSync) - m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig) + }, reqRepoReader(models.UnitTypeReleases)) + m.Post("/mirror-sync", reqToken(), reqRepoWriter(models.UnitTypeCode), repo.MirrorSync) + m.Get("/editorconfig/:filename", context.RepoRef(), reqRepoReader(models.UnitTypeCode), repo.GetEditorconfig) m.Group("/pulls", func() { m.Combo("").Get(bind(api.ListPullRequestsOptions{}), repo.ListPullRequests). - Post(reqToken(), reqRepoWriter(), bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) + Post(reqToken(), bind(api.CreatePullRequestOption{}), repo.CreatePullRequest) m.Group("/:index", func() { m.Combo("").Get(repo.GetPullRequest). - Patch(reqToken(), reqRepoWriter(), bind(api.EditPullRequestOption{}), repo.EditPullRequest) + Patch(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(api.EditPullRequestOption{}), repo.EditPullRequest) m.Combo("/merge").Get(repo.IsPullRequestMerged). - Post(reqToken(), reqRepoWriter(), bind(auth.MergePullRequestForm{}), repo.MergePullRequest) + Post(reqToken(), reqRepoWriter(models.UnitTypePullRequests), bind(auth.MergePullRequestForm{}), repo.MergePullRequest) }) - - }, mustAllowPulls, context.ReferencesGitRepo()) + }, mustAllowPulls, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo()) m.Group("/statuses", func() { m.Combo("/:sha").Get(repo.GetCommitStatuses). - Post(reqToken(), reqRepoWriter(), bind(api.CreateStatusOption{}), repo.NewCommitStatus) - }) + Post(reqToken(), bind(api.CreateStatusOption{}), repo.NewCommitStatus) + }, reqRepoReader(models.UnitTypeCode)) m.Group("/commits/:ref", func() { m.Get("/status", repo.GetCombinedCommitStatusByRef) m.Get("/statuses", repo.GetCommitStatusesByRef) - }) + }, reqRepoReader(models.UnitTypeCode)) m.Group("/git", func() { m.Get("/refs", repo.GetGitAllRefs) m.Get("/refs/*", repo.GetGitRefs) - }) + }, reqRepoReader(models.UnitTypeCode)) }, repoAssignment()) }) @@ -645,7 +679,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo) }) }) - }, reqToken(), reqAdmin()) + }, reqToken(), reqSiteAdmin()) m.Group("/topics", func() { m.Get("/search", repo.TopicSearch) |