summaryrefslogtreecommitdiffstats
path: root/routers/api/v1
diff options
context:
space:
mode:
Diffstat (limited to 'routers/api/v1')
-rw-r--r--routers/api/v1/api.go142
-rw-r--r--routers/api/v1/org/team.go6
-rw-r--r--routers/api/v1/repo/collaborators.go18
-rw-r--r--routers/api/v1/repo/file.go6
-rw-r--r--routers/api/v1/repo/fork.go3
-rw-r--r--routers/api/v1/repo/issue.go15
-rw-r--r--routers/api/v1/repo/issue_label.go41
-rw-r--r--routers/api/v1/repo/label.go16
-rw-r--r--routers/api/v1/repo/pull.go15
-rw-r--r--routers/api/v1/repo/release.go12
-rw-r--r--routers/api/v1/repo/repo.go20
-rw-r--r--routers/api/v1/user/repo.go7
-rw-r--r--routers/api/v1/user/star.go10
-rw-r--r--routers/api/v1/user/watch.go10
14 files changed, 151 insertions, 170 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)
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 8b67eda42f..a22d25eae3 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -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 {
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index c52472b0f8..2f254f7103 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -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) {
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 610247bc27..81f2332089 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -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
diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go
index 843559d523..d10f668712 100644
--- a/routers/api/v1/repo/fork.go
+++ b/routers/api/v1/repo/fork.go
@@ -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
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index cd78135a62..7a8ed09b48 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -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
}
diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go
index 35defa25b5..715dd0ed77 100644
--- a/routers/api/v1/repo/issue_label.go
+++ b/routers/api/v1/repo/issue_label.go
@@ -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
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index 359ccf0e41..df7a370041 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -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
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 83ef886d7d..a0117794ad 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -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, "", ""
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index 282ff582c5..caa2905e93 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -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) {
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index bf6346eebd..6d8125a77f 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -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")
}
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 5dccfac960..1ddb3bd57b 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -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
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index 1cf4f5239c..b0016399c8 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -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)
}
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index 2971bf6869..4afa18be2a 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -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)
}