mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-31 11:52:10 +00:00
Restrict permission check on repositories and fix some problems (#5314)
* fix units permission problems * fix some bugs and merge LoadUnits to repoAssignment * refactor permission struct and add some copyright heads * remove unused codes * fix routes units check * improve permission check * add unit tests for permission * fix typo * fix tests * fix some routes * fix api permission check * improve permission check * fix some permission check * fix tests * fix tests * improve some permission check * fix some permission check * refactor AccessLevel * fix bug * fix tests * fix tests * fix tests * fix AccessLevel * rename CanAccess * fix tests * fix comment * fix bug * add missing unit for test repos * fix bug * rename some functions * fix routes check
This commit is contained in:
parent
0222623be9
commit
eabbddcd98
80 changed files with 1360 additions and 774 deletions
|
@ -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.IsWriter() {
|
||||
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.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)
|
||||
|
|
|
@ -311,7 +311,7 @@ func GetTeamRepos(ctx *context.APIContext) {
|
|||
}
|
||||
repos := make([]*api.Repository, len(team.Repos))
|
||||
for i, repo := range team.Repos {
|
||||
access, err := models.AccessLevel(ctx.User.ID, repo)
|
||||
access, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetTeamRepos", err)
|
||||
return
|
||||
|
@ -366,7 +366,7 @@ func AddTeamRepository(ctx *context.APIContext) {
|
|||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
|
||||
if access, err := models.AccessLevel(ctx.User, repo); err != nil {
|
||||
ctx.Error(500, "AccessLevel", err)
|
||||
return
|
||||
} else if access < models.AccessModeAdmin {
|
||||
|
@ -413,7 +413,7 @@ func RemoveTeamRepository(ctx *context.APIContext) {
|
|||
if ctx.Written() {
|
||||
return
|
||||
}
|
||||
if access, err := models.AccessLevel(ctx.User.ID, repo); err != nil {
|
||||
if access, err := models.AccessLevel(ctx.User, repo); err != nil {
|
||||
ctx.Error(500, "AccessLevel", err)
|
||||
return
|
||||
} else if access < models.AccessModeAdmin {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 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.
|
||||
|
||||
|
@ -34,10 +35,6 @@ func ListCollaborators(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/UserList"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Error(403, "", "User does not have push access")
|
||||
return
|
||||
}
|
||||
collaborators, err := ctx.Repo.Repository.GetCollaborators()
|
||||
if err != nil {
|
||||
ctx.Error(500, "ListCollaborators", err)
|
||||
|
@ -78,10 +75,6 @@ func IsCollaborator(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/empty"
|
||||
// "404":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Error(403, "", "User does not have push access")
|
||||
return
|
||||
}
|
||||
user, err := models.GetUserByName(ctx.Params(":collaborator"))
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
|
@ -133,10 +126,6 @@ func AddCollaborator(ctx *context.APIContext, form api.AddCollaboratorOption) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Error(403, "", "User does not have push access")
|
||||
return
|
||||
}
|
||||
collaborator, err := models.GetUserByName(ctx.Params(":collaborator"))
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
|
@ -193,11 +182,6 @@ func DeleteCollaborator(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Error(403, "", "User does not have push access")
|
||||
return
|
||||
}
|
||||
|
||||
collaborator, err := models.GetUserByName(ctx.Params(":collaborator"))
|
||||
if err != nil {
|
||||
if models.IsErrUserNotExist(err) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 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.
|
||||
|
||||
|
@ -38,11 +39,6 @@ func GetRawFile(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// 200:
|
||||
// description: success
|
||||
if !ctx.Repo.HasAccess() {
|
||||
ctx.Status(404)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.Repo.Repository.IsBare {
|
||||
ctx.Status(404)
|
||||
return
|
||||
|
|
|
@ -7,7 +7,6 @@ package repo
|
|||
import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
|
||||
api "code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
@ -40,7 +39,7 @@ func ListForks(ctx *context.APIContext) {
|
|||
}
|
||||
apiForks := make([]*api.Repository, len(forks))
|
||||
for i, fork := range forks {
|
||||
access, err := models.AccessLevel(utils.UserID(ctx), fork)
|
||||
access, err := models.AccessLevel(ctx.User, fork)
|
||||
if err != nil {
|
||||
ctx.Error(500, "AccessLevel", err)
|
||||
return
|
||||
|
|
|
@ -169,7 +169,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
|
|||
// "$ref": "#/responses/Issue"
|
||||
|
||||
var deadlineUnix util.TimeStamp
|
||||
if form.Deadline != nil && ctx.Repo.IsWriter() {
|
||||
if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
|
|||
|
||||
var assigneeIDs = make([]int64, 0)
|
||||
var err error
|
||||
if ctx.Repo.IsWriter() {
|
||||
if ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
issue.MilestoneID = form.Milestone
|
||||
assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees)
|
||||
if err != nil {
|
||||
|
@ -274,7 +274,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||
return
|
||||
}
|
||||
|
||||
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.IsWriter() {
|
||||
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||
|
||||
// Update the deadline
|
||||
var deadlineUnix util.TimeStamp
|
||||
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.IsWriter() {
|
||||
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
|
||||
}
|
||||
|
||||
|
@ -305,8 +305,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||
// Pass one or more user logins to replace the set of assignees on this Issue.
|
||||
// Send an empty array ([]) to clear all assignees from the Issue.
|
||||
|
||||
if ctx.Repo.IsWriter() && (form.Assignees != nil || form.Assignee != nil) {
|
||||
|
||||
if ctx.Repo.CanWrite(models.UnitTypeIssues) && (form.Assignees != nil || form.Assignee != nil) {
|
||||
oneAssignee := ""
|
||||
if form.Assignee != nil {
|
||||
oneAssignee = *form.Assignee
|
||||
|
@ -319,7 +318,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.IsWriter() && form.Milestone != nil &&
|
||||
if ctx.Repo.CanWrite(models.UnitTypeIssues) && form.Milestone != nil &&
|
||||
issue.MilestoneID != *form.Milestone {
|
||||
oldMilestoneID := issue.MilestoneID
|
||||
issue.MilestoneID = *form.Milestone
|
||||
|
@ -403,7 +402,7 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
|
|||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.IsWriter() {
|
||||
if !ctx.Repo.CanWrite(models.UnitTypeIssues) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 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.
|
||||
|
||||
|
@ -90,11 +91,6 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/LabelList"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
|
@ -105,6 +101,11 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) {
|
|||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetLabelsInRepoByIDs", err)
|
||||
|
@ -162,11 +163,6 @@ func DeleteIssueLabel(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
|
@ -177,6 +173,11 @@ func DeleteIssueLabel(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrLabelNotExist(err) {
|
||||
|
@ -228,11 +229,6 @@ func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/LabelList"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
|
@ -243,6 +239,11 @@ func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) {
|
|||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetLabelsInRepoByIDs", err)
|
||||
|
@ -294,11 +295,6 @@ func ClearIssueLabels(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||
if err != nil {
|
||||
if models.IsErrIssueNotExist(err) {
|
||||
|
@ -309,6 +305,11 @@ func ClearIssueLabels(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
if err := issue.ClearLabels(ctx.User); err != nil {
|
||||
ctx.Error(500, "ClearLabels", err)
|
||||
return
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2016 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 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.
|
||||
|
||||
|
@ -123,11 +124,6 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) {
|
|||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/Label"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
label := &models.Label{
|
||||
Name: form.Name,
|
||||
Color: form.Color,
|
||||
|
@ -173,11 +169,6 @@ func EditLabel(ctx *context.APIContext, form api.EditLabelOption) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/Label"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if models.IsErrLabelNotExist(err) {
|
||||
|
@ -226,11 +217,6 @@ func DeleteLabel(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if !ctx.Repo.IsWriter() {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
||||
if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil {
|
||||
ctx.Error(500, "DeleteLabel", err)
|
||||
return
|
||||
|
|
|
@ -351,7 +351,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||
pr.LoadIssue()
|
||||
issue := pr.Issue
|
||||
|
||||
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.IsWriter() {
|
||||
if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypePullRequests) {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||
// Pass one or more user logins to replace the set of assignees on this Issue.
|
||||
// Send an empty array ([]) to clear all assignees from the Issue.
|
||||
|
||||
if ctx.Repo.IsWriter() && (form.Assignees != nil || len(form.Assignee) > 0) {
|
||||
if ctx.Repo.CanWrite(models.UnitTypePullRequests) && (form.Assignees != nil || len(form.Assignee) > 0) {
|
||||
|
||||
err = models.UpdateAPIAssignee(issue, form.Assignee, form.Assignees, ctx.User)
|
||||
if err != nil {
|
||||
|
@ -395,7 +395,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.IsWriter() && form.Milestone != 0 &&
|
||||
if ctx.Repo.CanWrite(models.UnitTypePullRequests) && form.Milestone != 0 &&
|
||||
issue.MilestoneID != form.Milestone {
|
||||
oldMilestoneID := issue.MilestoneID
|
||||
issue.MilestoneID = form.Milestone
|
||||
|
@ -405,7 +405,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.Repo.IsWriter() && (form.Labels != nil && len(form.Labels) > 0) {
|
||||
if ctx.Repo.CanWrite(models.UnitTypePullRequests) && (form.Labels != nil && len(form.Labels) > 0) {
|
||||
labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels)
|
||||
if err != nil {
|
||||
ctx.Error(500, "GetLabelsInRepoByIDsError", err)
|
||||
|
@ -663,7 +663,12 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
|||
}
|
||||
}
|
||||
|
||||
if !ctx.User.IsWriterOfRepo(headRepo) && !ctx.User.IsAdmin {
|
||||
perm, err := models.GetUserRepoPermission(headRepo, ctx.User)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetUserRepoPermission", err)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
}
|
||||
if !perm.CanWrite(models.UnitTypeCode) {
|
||||
log.Trace("ParseCompareInfo[%d]: does not have write access or site admin", baseRepo.ID)
|
||||
ctx.Status(404)
|
||||
return nil, nil, nil, nil, "", ""
|
||||
|
|
|
@ -122,10 +122,6 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
|
|||
// responses:
|
||||
// "201":
|
||||
// "$ref": "#/responses/Release"
|
||||
if ctx.Repo.AccessMode < models.AccessModeWrite {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
|
||||
if err != nil {
|
||||
if !models.IsErrReleaseNotExist(err) {
|
||||
|
@ -209,10 +205,6 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/Release"
|
||||
if ctx.Repo.AccessMode < models.AccessModeWrite {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
rel, err := models.GetReleaseByID(id)
|
||||
if err != nil && !models.IsErrReleaseNotExist(err) {
|
||||
|
@ -285,10 +277,6 @@ func DeleteRelease(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
if ctx.Repo.AccessMode < models.AccessModeWrite {
|
||||
ctx.Status(403)
|
||||
return
|
||||
}
|
||||
id := ctx.ParamsInt64(":id")
|
||||
rel, err := models.GetReleaseByID(id)
|
||||
if err != nil && !models.IsErrReleaseNotExist(err) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 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.
|
||||
|
||||
|
@ -183,11 +184,6 @@ func Search(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
var userID int64
|
||||
if ctx.IsSigned {
|
||||
userID = ctx.User.ID
|
||||
}
|
||||
|
||||
results := make([]*api.Repository, len(repos))
|
||||
for i, repo := range repos {
|
||||
if err = repo.GetOwner(); err != nil {
|
||||
|
@ -197,7 +193,7 @@ func Search(ctx *context.APIContext) {
|
|||
})
|
||||
return
|
||||
}
|
||||
accessMode, err := models.AccessLevel(userID, repo)
|
||||
accessMode, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.JSON(500, api.SearchError{
|
||||
OK: false,
|
||||
|
@ -469,15 +465,15 @@ func GetByID(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
access, err := models.AccessLevel(ctx.User.ID, repo)
|
||||
perm, err := models.GetUserRepoPermission(repo, ctx.User)
|
||||
if err != nil {
|
||||
ctx.Error(500, "AccessLevel", err)
|
||||
return
|
||||
} else if access < models.AccessModeRead {
|
||||
} else if !perm.HasAccess() {
|
||||
ctx.Status(404)
|
||||
return
|
||||
}
|
||||
ctx.JSON(200, repo.APIFormat(access))
|
||||
ctx.JSON(200, repo.APIFormat(perm.AccessMode))
|
||||
}
|
||||
|
||||
// Delete one repository
|
||||
|
@ -503,10 +499,6 @@ func Delete(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
if !ctx.Repo.IsAdmin() {
|
||||
ctx.Error(403, "", "Must have admin rights")
|
||||
return
|
||||
}
|
||||
owner := ctx.Repo.Owner
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
|
@ -553,7 +545,7 @@ func MirrorSync(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/empty"
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
if !ctx.Repo.IsWriter() {
|
||||
if !ctx.Repo.CanWrite(models.UnitTypeCode) {
|
||||
ctx.Error(403, "MirrorSync", "Must have write access")
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,10 @@ func listUserRepos(ctx *context.APIContext, u *models.User, private bool) {
|
|||
ctx.Error(500, "GetUserRepositories", err)
|
||||
return
|
||||
}
|
||||
|
||||
apiRepos := make([]*api.Repository, 0, len(repos))
|
||||
var ctxUserID int64
|
||||
if ctx.User != nil {
|
||||
ctxUserID = ctx.User.ID
|
||||
}
|
||||
for i := range repos {
|
||||
access, err := models.AccessLevel(ctxUserID, repos[i])
|
||||
access, err := models.AccessLevel(ctx.User, repos[i])
|
||||
if err != nil {
|
||||
ctx.Error(500, "AccessLevel", err)
|
||||
return
|
||||
|
|
|
@ -13,15 +13,15 @@ import (
|
|||
|
||||
// getStarredRepos returns the repos that the user with the specified userID has
|
||||
// starred
|
||||
func getStarredRepos(userID int64, private bool) ([]*api.Repository, error) {
|
||||
starredRepos, err := models.GetStarredRepos(userID, private)
|
||||
func getStarredRepos(user *models.User, private bool) ([]*api.Repository, error) {
|
||||
starredRepos, err := models.GetStarredRepos(user.ID, private)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := make([]*api.Repository, len(starredRepos))
|
||||
for i, starred := range starredRepos {
|
||||
access, err := models.AccessLevel(userID, starred)
|
||||
access, err := models.AccessLevel(user, starred)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func GetStarredRepos(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/RepositoryList"
|
||||
user := GetUserByParams(ctx)
|
||||
private := user.ID == ctx.User.ID
|
||||
repos, err := getStarredRepos(user.ID, private)
|
||||
repos, err := getStarredRepos(user, private)
|
||||
if err != nil {
|
||||
ctx.Error(500, "getStarredRepos", err)
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func GetMyStarredRepos(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/RepositoryList"
|
||||
repos, err := getStarredRepos(ctx.User.ID, true)
|
||||
repos, err := getStarredRepos(ctx.User, true)
|
||||
if err != nil {
|
||||
ctx.Error(500, "getStarredRepos", err)
|
||||
}
|
||||
|
|
|
@ -14,15 +14,15 @@ import (
|
|||
|
||||
// getWatchedRepos returns the repos that the user with the specified userID is
|
||||
// watching
|
||||
func getWatchedRepos(userID int64, private bool) ([]*api.Repository, error) {
|
||||
watchedRepos, err := models.GetWatchedRepos(userID, private)
|
||||
func getWatchedRepos(user *models.User, private bool) ([]*api.Repository, error) {
|
||||
watchedRepos, err := models.GetWatchedRepos(user.ID, private)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repos := make([]*api.Repository, len(watchedRepos))
|
||||
for i, watched := range watchedRepos {
|
||||
access, err := models.AccessLevel(userID, watched)
|
||||
access, err := models.AccessLevel(user, watched)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func GetWatchedRepos(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/RepositoryList"
|
||||
user := GetUserByParams(ctx)
|
||||
private := user.ID == ctx.User.ID
|
||||
repos, err := getWatchedRepos(user.ID, private)
|
||||
repos, err := getWatchedRepos(user, private)
|
||||
if err != nil {
|
||||
ctx.Error(500, "getWatchedRepos", err)
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ func GetMyWatchedRepos(ctx *context.APIContext) {
|
|||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/RepositoryList"
|
||||
repos, err := getWatchedRepos(ctx.User.ID, true)
|
||||
repos, err := getWatchedRepos(ctx.User, true)
|
||||
if err != nil {
|
||||
ctx.Error(500, "getWatchedRepos", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue