diff options
author | 6543 <6543@obermui.de> | 2019-12-20 18:07:12 +0100 |
---|---|---|
committer | Lauris BH <lauris@nix.lv> | 2019-12-20 19:07:12 +0200 |
commit | 2848c5eb8f7333b6791afd296b12d21751d0516b (patch) | |
tree | 67ff6244026174116edbff1b4c4cdb5934401968 /routers/api/v1/repo | |
parent | 050a8af4243d7f5fff0a2f492b9166f4dfdf0ecf (diff) | |
download | gitea-2848c5eb8f7333b6791afd296b12d21751d0516b.tar.gz gitea-2848c5eb8f7333b6791afd296b12d21751d0516b.zip |
Swagger info corrections (#9441)
* use numbers and not http.Status___ enum
* fix test
* add many missing swagger responses
* code format
* Deletion Sould return 204 ...
* error handling improvements
* if special error type ... then add it to swagger too
* one smal nit
* invalidTopicsError is []string
* valid swagger specification 2.0
- if you add responses swagger can tell you if you do it right :+1:
* use ctx.InternalServerError
* Revert "use numbers and not http.Status___ enum"
This reverts commit b1ff386e2418ed6a7f183e756b13277d701278ef.
* use http.Status* enum everywhere
Diffstat (limited to 'routers/api/v1/repo')
29 files changed, 664 insertions, 420 deletions
diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go index d6265e16ce..3918a49d51 100644 --- a/routers/api/v1/repo/blob.go +++ b/routers/api/v1/repo/blob.go @@ -37,6 +37,8 @@ func GetBlob(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/GitBlobResponse" + // "400": + // "$ref": "#/responses/error" sha := ctx.Params("sha") if len(sha) == 0 { diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 9745903a95..afc4763b52 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -6,6 +6,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" @@ -38,6 +40,7 @@ func GetBranch(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Branch" + if ctx.Repo.TreePath != "" { // if TreePath != "", then URL contained extra slashes // (i.e. "master/subbranch" instead of "master"), so branch does @@ -50,24 +53,24 @@ func GetBranch(ctx *context.APIContext) { if git.IsErrBranchNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetBranch", err) + ctx.Error(http.StatusInternalServerError, "GetBranch", err) } return } c, err := branch.GetCommit() if err != nil { - ctx.Error(500, "GetCommit", err) + ctx.Error(http.StatusInternalServerError, "GetCommit", err) return } branchProtection, err := ctx.Repo.Repository.GetBranchProtection(ctx.Repo.BranchName) if err != nil { - ctx.Error(500, "GetBranchProtection", err) + ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err) return } - ctx.JSON(200, convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.User)) + ctx.JSON(http.StatusOK, convert.ToBranch(ctx.Repo.Repository, branch, c, branchProtection, ctx.User)) } // ListBranches list all the branches of a repository @@ -91,9 +94,10 @@ func ListBranches(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/BranchList" + branches, err := ctx.Repo.Repository.GetBranches() if err != nil { - ctx.Error(500, "GetBranches", err) + ctx.Error(http.StatusInternalServerError, "GetBranches", err) return } @@ -101,16 +105,16 @@ func ListBranches(ctx *context.APIContext) { for i := range branches { c, err := branches[i].GetCommit() if err != nil { - ctx.Error(500, "GetCommit", err) + ctx.Error(http.StatusInternalServerError, "GetCommit", err) return } branchProtection, err := ctx.Repo.Repository.GetBranchProtection(branches[i].Name) if err != nil { - ctx.Error(500, "GetBranchProtection", err) + ctx.Error(http.StatusInternalServerError, "GetBranchProtection", err) return } apiBranches[i] = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.User) } - ctx.JSON(200, &apiBranches) + ctx.JSON(http.StatusOK, &apiBranches) } diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index 81d472dffb..aec389ab31 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -7,6 +7,7 @@ package repo import ( "errors" + "net/http" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -35,16 +36,17 @@ func ListCollaborators(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/UserList" + collaborators, err := ctx.Repo.Repository.GetCollaborators() if err != nil { - ctx.Error(500, "ListCollaborators", err) + ctx.Error(http.StatusInternalServerError, "ListCollaborators", err) return } users := make([]*api.User, len(collaborators)) for i, collaborator := range collaborators { users[i] = convert.ToUser(collaborator.User, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin) } - ctx.JSON(200, users) + ctx.JSON(http.StatusOK, users) } // IsCollaborator check if a user is a collaborator of a repository @@ -74,23 +76,26 @@ func IsCollaborator(ctx *context.APIContext) { // "204": // "$ref": "#/responses/empty" // "404": - // "$ref": "#/responses/empty" + // "$ref": "#/responses/notFound" + // "422": + // "$ref": "#/responses/validationError" + user, err := models.GetUserByName(ctx.Params(":collaborator")) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetUserByName", err) + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) } return } isColab, err := ctx.Repo.Repository.IsCollaborator(user.ID) if err != nil { - ctx.Error(500, "IsCollaborator", err) + ctx.Error(http.StatusInternalServerError, "IsCollaborator", err) return } if isColab { - ctx.Status(204) + ctx.Status(http.StatusNoContent) } else { ctx.NotFound() } @@ -126,34 +131,37 @@ func AddCollaborator(ctx *context.APIContext, form api.AddCollaboratorOption) { // responses: // "204": // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/validationError" + collaborator, err := models.GetUserByName(ctx.Params(":collaborator")) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetUserByName", err) + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) } return } if !collaborator.IsActive { - ctx.Error(500, "InactiveCollaborator", errors.New("collaborator's account is inactive")) + ctx.Error(http.StatusInternalServerError, "InactiveCollaborator", errors.New("collaborator's account is inactive")) return } if err := ctx.Repo.Repository.AddCollaborator(collaborator); err != nil { - ctx.Error(500, "AddCollaborator", err) + ctx.Error(http.StatusInternalServerError, "AddCollaborator", err) return } if form.Permission != nil { if err := ctx.Repo.Repository.ChangeCollaborationAccessMode(collaborator.ID, models.ParseAccessMode(*form.Permission)); err != nil { - ctx.Error(500, "ChangeCollaborationAccessMode", err) + ctx.Error(http.StatusInternalServerError, "ChangeCollaborationAccessMode", err) return } } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } // DeleteCollaborator delete a collaborator from a repository @@ -182,19 +190,22 @@ func DeleteCollaborator(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/validationError" + collaborator, err := models.GetUserByName(ctx.Params(":collaborator")) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetUserByName", err) + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) } return } if err := ctx.Repo.Repository.DeleteCollaboration(collaborator.ID); err != nil { - ctx.Error(500, "DeleteCollaboration", err) + ctx.Error(http.StatusInternalServerError, "DeleteCollaboration", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 163a06a95e..d8777eaf3a 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -7,6 +7,7 @@ package repo import ( "math" + "net/http" "strconv" "time" @@ -64,7 +65,7 @@ func GetSingleCommit(ctx *context.APIContext) { return } - ctx.JSON(200, json) + ctx.JSON(http.StatusOK, json) } // GetAllCommits get all commits via @@ -102,7 +103,7 @@ func GetAllCommits(ctx *context.APIContext) { // "$ref": "#/responses/EmptyRepository" if ctx.Repo.Repository.IsEmpty { - ctx.JSON(409, api.APIError{ + ctx.JSON(http.StatusConflict, api.APIError{ Message: "Git Repository is empty.", URL: setting.API.SwaggerURL, }) @@ -188,7 +189,7 @@ func GetAllCommits(ctx *context.APIContext) { ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount)) ctx.Header().Set("X-HasMore", strconv.FormatBool(page < pageCount)) - ctx.JSON(200, &apiCommits) + ctx.JSON(http.StatusOK, &apiCommits) } func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Commit, userCache map[string]*models.User) (*api.Commit, error) { diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 175235c5ef..8cfe039df5 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -43,6 +43,9 @@ func GetRawFile(ctx *context.APIContext) { // responses: // 200: // description: success + // "404": + // "$ref": "#/responses/notFound" + if ctx.Repo.Repository.IsEmpty { ctx.NotFound() return @@ -88,6 +91,9 @@ func GetArchive(ctx *context.APIContext) { // responses: // 200: // description: success + // "404": + // "$ref": "#/responses/notFound" + repoPath := models.RepoPath(ctx.Params(":username"), ctx.Params(":reponame")) gitRepo, err := git.OpenRepository(repoPath) if err != nil { @@ -126,6 +132,9 @@ func GetEditorconfig(ctx *context.APIContext) { // responses: // 200: // description: success + // "404": + // "$ref": "#/responses/notFound" + ec, err := ctx.Repo.GetEditorconfig() if err != nil { if git.IsErrNotExist(err) { @@ -332,6 +341,7 @@ func DeleteFile(ctx *context.APIContext, apiOpts api.DeleteFileOptions) { // responses: // "200": // "$ref": "#/responses/FileDeleteResponse" + if !CanWriteFiles(ctx.Repo) { ctx.Error(http.StatusInternalServerError, "DeleteFile", models.ErrUserDoesNotHaveAccessToRepo{ UserID: ctx.User.ID, diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 31f2389478..0bf7fc6cef 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -5,6 +5,9 @@ package repo import ( + "fmt" + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" @@ -32,21 +35,22 @@ func ListForks(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/RepositoryList" + forks, err := ctx.Repo.Repository.GetForks() if err != nil { - ctx.Error(500, "GetForks", err) + ctx.Error(http.StatusInternalServerError, "GetForks", err) return } apiForks := make([]*api.Repository, len(forks)) for i, fork := range forks { access, err := models.AccessLevel(ctx.User, fork) if err != nil { - ctx.Error(500, "AccessLevel", err) + ctx.Error(http.StatusInternalServerError, "AccessLevel", err) return } apiForks[i] = fork.APIFormat(access) } - ctx.JSON(200, apiForks) + ctx.JSON(http.StatusOK, apiForks) } // CreateFork create a fork of a repo @@ -74,6 +78,11 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { // responses: // "202": // "$ref": "#/responses/Repository" + // "403": + // "$ref": "#/responses/forbidden" + // "422": + // "$ref": "#/responses/validationError" + repo := ctx.Repo.Repository var forker *models.User // user/org that will own the fork if form.Organization == nil { @@ -82,9 +91,9 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { org, err := models.GetOrgByName(*form.Organization) if err != nil { if models.IsErrOrgNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetOrgByName", err) + ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) } return } @@ -93,7 +102,7 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { ctx.ServerError("IsOrgMember", err) return } else if !isMember { - ctx.Status(403) + ctx.Error(http.StatusForbidden, "isMemberNot", fmt.Sprintf("User is no Member of Organisation '%s'", org.Name)) return } forker = org @@ -101,9 +110,10 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) { fork, err := repo_service.ForkRepository(ctx.User, forker, repo, repo.Name, repo.Description) if err != nil { - ctx.Error(500, "ForkRepository", err) + ctx.Error(http.StatusInternalServerError, "ForkRepository", err) return } - ctx.JSON(202, fork.APIFormat(models.AccessModeOwner)) + //TODO change back to 201 + ctx.JSON(http.StatusAccepted, fork.APIFormat(models.AccessModeOwner)) } diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go index 46651ef614..0c538ac6b3 100644 --- a/routers/api/v1/repo/git_hook.go +++ b/routers/api/v1/repo/git_hook.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" @@ -32,9 +34,10 @@ func ListGitHooks(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/GitHookList" + hooks, err := ctx.Repo.GitRepo.Hooks() if err != nil { - ctx.Error(500, "Hooks", err) + ctx.Error(http.StatusInternalServerError, "Hooks", err) return } @@ -42,7 +45,7 @@ func ListGitHooks(ctx *context.APIContext) { for i := range hooks { apiHooks[i] = convert.ToGitHook(hooks[i]) } - ctx.JSON(200, &apiHooks) + ctx.JSON(http.StatusOK, &apiHooks) } // GetGitHook get a repo's Git hook by id @@ -73,17 +76,18 @@ func GetGitHook(ctx *context.APIContext) { // "$ref": "#/responses/GitHook" // "404": // "$ref": "#/responses/notFound" + hookID := ctx.Params(":id") hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if err == git.ErrNotValidHook { ctx.NotFound() } else { - ctx.Error(500, "GetHook", err) + ctx.Error(http.StatusInternalServerError, "GetHook", err) } return } - ctx.JSON(200, convert.ToGitHook(hook)) + ctx.JSON(http.StatusOK, convert.ToGitHook(hook)) } // EditGitHook modify a Git hook of a repository @@ -118,24 +122,25 @@ func EditGitHook(ctx *context.APIContext, form api.EditGitHookOption) { // "$ref": "#/responses/GitHook" // "404": // "$ref": "#/responses/notFound" + hookID := ctx.Params(":id") hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if err == git.ErrNotValidHook { ctx.NotFound() } else { - ctx.Error(500, "GetHook", err) + ctx.Error(http.StatusInternalServerError, "GetHook", err) } return } hook.Content = form.Content if err = hook.Update(); err != nil { - ctx.Error(500, "hook.Update", err) + ctx.Error(http.StatusInternalServerError, "hook.Update", err) return } - ctx.JSON(200, convert.ToGitHook(hook)) + ctx.JSON(http.StatusOK, convert.ToGitHook(hook)) } // DeleteGitHook delete a Git hook of a repository @@ -166,22 +171,23 @@ func DeleteGitHook(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "404": // "$ref": "#/responses/notFound" + hookID := ctx.Params(":id") hook, err := ctx.Repo.GitRepo.GetHook(hookID) if err != nil { if err == git.ErrNotValidHook { ctx.NotFound() } else { - ctx.Error(500, "GetHook", err) + ctx.Error(http.StatusInternalServerError, "GetHook", err) } return } hook.Content = "" if err = hook.Update(); err != nil { - ctx.Error(500, "hook.Update", err) + ctx.Error(http.StatusInternalServerError, "hook.Update", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go index c2bcbb3603..bd43ad4fc8 100644 --- a/routers/api/v1/repo/git_ref.go +++ b/routers/api/v1/repo/git_ref.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" @@ -88,7 +90,7 @@ func getGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, strin func getGitRefsInternal(ctx *context.APIContext, filter string) { refs, lastMethodName, err := getGitRefs(ctx, filter) if err != nil { - ctx.Error(500, lastMethodName, err) + ctx.Error(http.StatusInternalServerError, lastMethodName, err) return } @@ -111,8 +113,8 @@ func getGitRefsInternal(ctx *context.APIContext, filter string) { } // If single reference is found and it matches filter exactly return it as object if len(apiRefs) == 1 && apiRefs[0].Ref == filter { - ctx.JSON(200, &apiRefs[0]) + ctx.JSON(http.StatusOK, &apiRefs[0]) return } - ctx.JSON(200, &apiRefs) + ctx.JSON(http.StatusOK, &apiRefs) } diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 3666d79fa0..7fd7cd1be3 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" @@ -35,9 +37,10 @@ func ListHooks(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/HookList" + hooks, err := models.GetWebhooksByRepoID(ctx.Repo.Repository.ID) if err != nil { - ctx.Error(500, "GetWebhooksByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetWebhooksByRepoID", err) return } @@ -45,7 +48,7 @@ func ListHooks(ctx *context.APIContext) { for i := range hooks { apiHooks[i] = convert.ToHook(ctx.Repo.RepoLink, hooks[i]) } - ctx.JSON(200, &apiHooks) + ctx.JSON(http.StatusOK, &apiHooks) } // GetHook get a repo's hook by id @@ -75,13 +78,16 @@ func GetHook(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Hook" + // "404": + // "$ref": "#/responses/notFound" + repo := ctx.Repo hookID := ctx.ParamsInt64(":id") hook, err := utils.GetRepoHook(ctx, repo.Repository.ID, hookID) if err != nil { return } - ctx.JSON(200, convert.ToHook(repo.RepoLink, hook)) + ctx.JSON(http.StatusOK, convert.ToHook(repo.RepoLink, hook)) } // TestHook tests a hook @@ -111,9 +117,10 @@ func TestHook(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + if ctx.Repo.Commit == nil { // if repo does not have any commits, then don't send a webhook - ctx.Status(204) + ctx.Status(http.StatusNoContent) return } @@ -134,11 +141,11 @@ func TestHook(ctx *context.APIContext) { Pusher: convert.ToUser(ctx.User, ctx.IsSigned, false), Sender: convert.ToUser(ctx.User, ctx.IsSigned, false), }); err != nil { - ctx.Error(500, "PrepareWebhook: ", err) + ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } // CreateHook create a hook for a repository @@ -242,9 +249,9 @@ func DeleteHook(ctx *context.APIContext) { if models.IsErrWebhookNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "DeleteWebhookByRepoID", err) + ctx.Error(http.StatusInternalServerError, "DeleteWebhookByRepoID", err) } return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 6972d447a6..4396e6faae 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -54,6 +54,7 @@ func SearchIssues(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/IssueList" + var isClosed util.OptionalBool switch ctx.Query("state") { case "closed": @@ -81,7 +82,7 @@ func SearchIssues(ctx *context.APIContext) { OrderBy: models.SearchOrderByRecentUpdated, }) if err != nil { - ctx.Error(500, "SearchRepositoryByName", err) + ctx.Error(http.StatusInternalServerError, "SearchRepositoryByName", err) return } @@ -119,7 +120,7 @@ func SearchIssues(ctx *context.APIContext) { if splitted := strings.Split(labels, ","); labels != "" && len(splitted) > 0 { labelIDs, err = models.GetLabelIDsInReposByNames(repoIDs, splitted) if err != nil { - ctx.Error(500, "GetLabelIDsInRepoByNames", err) + ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) return } } @@ -140,7 +141,7 @@ func SearchIssues(ctx *context.APIContext) { } if err != nil { - ctx.Error(500, "Issues", err) + ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -150,7 +151,7 @@ func SearchIssues(ctx *context.APIContext) { } ctx.SetLinkHeader(issueCount, setting.UI.IssuePagingNum) - ctx.JSON(200, &apiIssues) + ctx.JSON(http.StatusOK, &apiIssues) } // ListIssues list the issues of a repository @@ -190,6 +191,7 @@ func ListIssues(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/IssueList" + var isClosed util.OptionalBool switch ctx.Query("state") { case "closed": @@ -216,7 +218,7 @@ func ListIssues(ctx *context.APIContext) { if splitted := strings.Split(ctx.Query("labels"), ","); len(splitted) > 0 { labelIDs, err = models.GetLabelIDsInRepoByNames(ctx.Repo.Repository.ID, splitted) if err != nil { - ctx.Error(500, "GetLabelIDsInRepoByNames", err) + ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err) return } } @@ -235,7 +237,7 @@ func ListIssues(ctx *context.APIContext) { } if err != nil { - ctx.Error(500, "Issues", err) + ctx.Error(http.StatusInternalServerError, "Issues", err) return } @@ -245,7 +247,7 @@ func ListIssues(ctx *context.APIContext) { } ctx.SetLinkHeader(ctx.Repo.Repository.NumIssues, setting.UI.IssuePagingNum) - ctx.JSON(200, &apiIssues) + ctx.JSON(http.StatusOK, &apiIssues) } // GetIssue get an issue of a repository @@ -275,16 +277,19 @@ func GetIssue(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Issue" + // "404": + // "$ref": "#/responses/notFound" + issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } - ctx.JSON(200, issue.APIFormat()) + ctx.JSON(http.StatusOK, issue.APIFormat()) } // CreateIssue create an issue of a repository @@ -314,6 +319,12 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { // responses: // "201": // "$ref": "#/responses/Issue" + // "403": + // "$ref": "#/responses/forbidden" + // "412": + // "$ref": "#/responses/error" + // "422": + // "$ref": "#/responses/validationError" var deadlineUnix timeutil.TimeStamp if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) { @@ -337,9 +348,9 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { assigneeIDs, err = models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else { - ctx.Error(500, "AddAssigneeByName", err) + ctx.Error(http.StatusInternalServerError, "AddAssigneeByName", err) } return } @@ -348,17 +359,17 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { for _, aID := range assigneeIDs { assignee, err := models.GetUserByID(aID) if err != nil { - ctx.Error(500, "GetUserByID", err) + ctx.Error(http.StatusInternalServerError, "GetUserByID", err) return } valid, err := models.CanBeAssigned(assignee, ctx.Repo.Repository, false) if err != nil { - ctx.Error(500, "canBeAssigned", err) + ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) return } if !valid { - ctx.Error(422, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: ctx.Repo.Repository.Name}) return } } @@ -369,10 +380,10 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { if err := issue_service.NewIssue(ctx.Repo.Repository, issue, form.Labels, nil, assigneeIDs); err != nil { if models.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(400, "UserDoesNotHaveAccessToRepo", err) + ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } - ctx.Error(500, "NewIssue", err) + ctx.Error(http.StatusInternalServerError, "NewIssue", err) return } @@ -382,7 +393,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } - ctx.Error(500, "ChangeStatus", err) + ctx.Error(http.StatusInternalServerError, "ChangeStatus", err) return } } @@ -390,10 +401,10 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) { // Refetch from database to assign some automatic values issue, err = models.GetIssueByID(issue.ID) if err != nil { - ctx.Error(500, "GetIssueByID", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) return } - ctx.JSON(201, issue.APIFormat()) + ctx.JSON(http.StatusCreated, issue.APIFormat()) } // EditIssue modify an issue of a repository @@ -429,12 +440,19 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { // responses: // "201": // "$ref": "#/responses/Issue" + // "403": + // "$ref": "#/responses/forbidden" + // "404": + // "$ref": "#/responses/notFound" + // "412": + // "$ref": "#/responses/error" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } @@ -442,12 +460,12 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { err = issue.LoadAttributes() if err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypeIssues) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } @@ -469,7 +487,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { } if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { - ctx.Error(500, "UpdateIssueDeadline", err) + ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } issue.DeadlineUnix = deadlineUnix @@ -491,7 +509,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { err = issue_service.UpdateAssignees(issue, oneAssignee, form.Assignees, ctx.User) if err != nil { - ctx.Error(500, "UpdateAssignees", err) + ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err) return } } @@ -501,13 +519,13 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = *form.Milestone if err = issue_service.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil { - ctx.Error(500, "ChangeMilestoneAssign", err) + ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err) return } } if err = models.UpdateIssue(issue); err != nil { - ctx.Error(500, "UpdateIssue", err) + ctx.Error(http.StatusInternalServerError, "UpdateIssue", err) return } if form.State != nil { @@ -516,7 +534,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies") return } - ctx.Error(500, "ChangeStatus", err) + ctx.Error(http.StatusInternalServerError, "ChangeStatus", err) return } } @@ -524,10 +542,10 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) { // Refetch from database to assign some automatic values issue, err = models.GetIssueByID(issue.ID) if err != nil { - ctx.Error(500, "GetIssueByID", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByID", err) return } - ctx.JSON(201, issue.APIFormat()) + ctx.JSON(http.StatusCreated, issue.APIFormat()) } // UpdateIssueDeadline updates an issue deadline @@ -564,22 +582,22 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { // "201": // "$ref": "#/responses/IssueDeadline" // "403": - // description: Not repo writer + // "$ref": "#/responses/forbidden" // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanWrite(models.UnitTypeIssues) { - ctx.Status(403) + ctx.Error(http.StatusForbidden, "", "Not repo writer") return } @@ -592,9 +610,9 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) { } if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { - ctx.Error(500, "UpdateIssueDeadline", err) + ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } - ctx.JSON(201, api.IssueDeadline{Deadline: &deadline}) + ctx.JSON(http.StatusCreated, api.IssueDeadline{Deadline: &deadline}) } diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 3a5f6d2447..c13fc93cdf 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -6,6 +6,7 @@ package repo import ( "errors" + "net/http" "time" "code.gitea.io/gitea/models" @@ -45,6 +46,7 @@ func ListIssueComments(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/CommentList" + var since time.Time if len(ctx.Query("since")) > 0 { since, _ = time.Parse(time.RFC3339, ctx.Query("since")) @@ -53,7 +55,7 @@ func ListIssueComments(ctx *context.APIContext) { // comments,err:=models.GetCommentsByIssueIDSince(, since) issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - ctx.Error(500, "GetRawIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err) return } issue.Repo = ctx.Repo.Repository @@ -64,12 +66,12 @@ func ListIssueComments(ctx *context.APIContext) { Type: models.CommentTypeComment, }) if err != nil { - ctx.Error(500, "FindComments", err) + ctx.Error(http.StatusInternalServerError, "FindComments", err) return } if err := models.CommentList(comments).LoadPosters(); err != nil { - ctx.Error(500, "LoadPosters", err) + ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } @@ -78,7 +80,7 @@ func ListIssueComments(ctx *context.APIContext) { comment.Issue = issue apiComments[i] = comments[i].APIFormat() } - ctx.JSON(200, &apiComments) + ctx.JSON(http.StatusOK, &apiComments) } // ListRepoIssueComments returns all issue-comments for a repo @@ -106,6 +108,7 @@ func ListRepoIssueComments(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/CommentList" + var since time.Time if len(ctx.Query("since")) > 0 { since, _ = time.Parse(time.RFC3339, ctx.Query("since")) @@ -117,32 +120,32 @@ func ListRepoIssueComments(ctx *context.APIContext) { Type: models.CommentTypeComment, }) if err != nil { - ctx.Error(500, "FindComments", err) + ctx.Error(http.StatusInternalServerError, "FindComments", err) return } if err = models.CommentList(comments).LoadPosters(); err != nil { - ctx.Error(500, "LoadPosters", err) + ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } apiComments := make([]*api.Comment, len(comments)) if err := models.CommentList(comments).LoadIssues(); err != nil { - ctx.Error(500, "LoadIssues", err) + ctx.Error(http.StatusInternalServerError, "LoadIssues", err) return } if err := models.CommentList(comments).LoadPosters(); err != nil { - ctx.Error(500, "LoadPosters", err) + ctx.Error(http.StatusInternalServerError, "LoadPosters", err) return } if _, err := models.CommentList(comments).Issues().LoadRepositories(); err != nil { - ctx.Error(500, "LoadRepositories", err) + ctx.Error(http.StatusInternalServerError, "LoadRepositories", err) return } for i := range comments { apiComments[i] = comments[i].APIFormat() } - ctx.JSON(200, &apiComments) + ctx.JSON(http.StatusOK, &apiComments) } // CreateIssueComment create a comment for an issue @@ -178,24 +181,27 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti // responses: // "201": // "$ref": "#/responses/Comment" + // "403": + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) return } if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin { - ctx.Error(403, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked"))) + ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked"))) return } comment, err := comment_service.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Body, nil) if err != nil { - ctx.Error(500, "CreateIssueComment", err) + ctx.Error(http.StatusInternalServerError, "CreateIssueComment", err) return } - ctx.JSON(201, comment.APIFormat()) + ctx.JSON(http.StatusCreated, comment.APIFormat()) } // EditIssueComment modify a comment of an issue @@ -273,6 +279,11 @@ func EditIssueCommentDeprecated(ctx *context.APIContext, form api.EditIssueComme // responses: // "200": // "$ref": "#/responses/Comment" + // "204": + // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + editIssueComment(ctx, form) } @@ -282,27 +293,27 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) if models.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetCommentByID", err) + ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) } return } if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } else if comment.Type != models.CommentTypeComment { - ctx.Status(204) + ctx.Status(http.StatusNoContent) return } oldContent := comment.Content comment.Content = form.Body if err := comment_service.UpdateComment(comment, ctx.User, oldContent); err != nil { - ctx.Error(500, "UpdateComment", err) + ctx.Error(http.StatusInternalServerError, "UpdateComment", err) return } - ctx.JSON(200, comment.APIFormat()) + ctx.JSON(http.StatusOK, comment.APIFormat()) } // DeleteIssueComment delete a comment from an issue @@ -330,6 +341,9 @@ func DeleteIssueComment(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + deleteIssueComment(ctx) } @@ -364,6 +378,9 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + deleteIssueComment(ctx) } @@ -373,23 +390,23 @@ func deleteIssueComment(ctx *context.APIContext) { if models.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetCommentByID", err) + ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) } return } if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.IsAdmin()) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } else if comment.Type != models.CommentTypeComment { - ctx.Status(204) + ctx.Status(http.StatusNoContent) return } if err = comment_service.DeleteComment(comment, ctx.User); err != nil { - ctx.Error(500, "DeleteCommentByID", err) + ctx.Error(http.StatusInternalServerError, "DeleteCommentByID", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index e41c1512e2..492da244f2 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -6,6 +6,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" @@ -41,18 +43,19 @@ func ListIssueLabels(ctx *context.APIContext) { // "$ref": "#/responses/LabelList" // "404": // "$ref": "#/responses/notFound" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if err := issue.LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } @@ -60,7 +63,7 @@ func ListIssueLabels(ctx *context.APIContext) { for i := range issue.Labels { apiLabels[i] = issue.Labels[i].APIFormat() } - ctx.JSON(200, &apiLabels) + ctx.JSON(http.StatusOK, &apiLabels) } // AddIssueLabels add labels for an issue @@ -96,35 +99,38 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { // responses: // "200": // "$ref": "#/responses/LabelList" + // "403": + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(500, "GetLabelsInRepoByIDs", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) return } if err = issue_service.AddLabels(issue, ctx.User, labels); err != nil { - ctx.Error(500, "AddLabels", err) + ctx.Error(http.StatusInternalServerError, "AddLabels", err) return } labels, err = models.GetLabelsByIssueID(issue.ID) if err != nil { - ctx.Error(500, "GetLabelsByIssueID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return } @@ -132,7 +138,7 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { for i := range labels { apiLabels[i] = labels[i].APIFormat() } - ctx.JSON(200, &apiLabels) + ctx.JSON(http.StatusOK, &apiLabels) } // DeleteIssueLabel delete a label for an issue @@ -168,37 +174,42 @@ func DeleteIssueLabel(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + // "422": + // "$ref": "#/responses/validationError" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrLabelNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetLabelInRepoByID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelInRepoByID", err) } return } if err := models.DeleteIssueLabel(issue, label, ctx.User); err != nil { - ctx.Error(500, "DeleteIssueLabel", err) + ctx.Error(http.StatusInternalServerError, "DeleteIssueLabel", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } // ReplaceIssueLabels replace labels for an issue @@ -234,35 +245,38 @@ func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { // responses: // "200": // "$ref": "#/responses/LabelList" + // "403": + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(500, "GetLabelsInRepoByIDs", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) return } if err := issue.ReplaceLabels(labels, ctx.User); err != nil { - ctx.Error(500, "ReplaceLabels", err) + ctx.Error(http.StatusInternalServerError, "ReplaceLabels", err) return } labels, err = models.GetLabelsByIssueID(issue.ID) if err != nil { - ctx.Error(500, "GetLabelsByIssueID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsByIssueID", err) return } @@ -270,7 +284,7 @@ func ReplaceIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) { for i := range labels { apiLabels[i] = labels[i].APIFormat() } - ctx.JSON(200, &apiLabels) + ctx.JSON(http.StatusOK, &apiLabels) } // ClearIssueLabels delete all the labels for an issue @@ -300,25 +314,28 @@ func ClearIssueLabels(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } if err := issue_service.ClearLabels(issue, ctx.User); err != nil { - ctx.Error(500, "ClearLabels", err) + ctx.Error(http.StatusInternalServerError, "ClearLabels", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index 56e12ccdcc..4b06bb987c 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -6,6 +6,7 @@ package repo import ( "errors" + "net/http" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -41,29 +42,32 @@ func GetIssueCommentReactions(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/ReactionResponseList" + // "403": + // "$ref": "#/responses/forbidden" + comment, err := models.GetCommentByID(ctx.ParamsInt64(":id")) if err != nil { if models.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetCommentByID", err) + ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) } return } if !ctx.Repo.CanRead(models.UnitTypeIssues) && !ctx.User.IsAdmin { - ctx.Error(403, "GetIssueCommentReactions", errors.New("no permission to get reactions")) + ctx.Error(http.StatusForbidden, "GetIssueCommentReactions", errors.New("no permission to get reactions")) return } reactions, err := models.FindCommentReactions(comment) if err != nil { - ctx.Error(500, "FindIssueReactions", err) + ctx.Error(http.StatusInternalServerError, "FindIssueReactions", err) return } _, err = reactions.LoadUsers() if err != nil { - ctx.Error(500, "ReactionList.LoadUsers()", err) + ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) return } @@ -76,7 +80,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) { }) } - ctx.JSON(200, result) + ctx.JSON(http.StatusOK, result) } // PostIssueCommentReaction add a reaction to a comment of a issue @@ -112,6 +116,9 @@ func PostIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOpti // responses: // "201": // "$ref": "#/responses/ReactionResponse" + // "403": + // "$ref": "#/responses/forbidden" + changeIssueCommentReaction(ctx, form, true) } @@ -148,6 +155,9 @@ func DeleteIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp // responses: // "200": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + changeIssueCommentReaction(ctx, form, false) } @@ -157,18 +167,18 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp if models.IsErrCommentNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetCommentByID", err) + ctx.Error(http.StatusInternalServerError, "GetCommentByID", err) } return } err = comment.LoadIssue() if err != nil { - ctx.Error(500, "comment.LoadIssue() failed", err) + ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err) } if comment.Issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin { - ctx.Error(403, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) + ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) return } @@ -177,19 +187,19 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp reaction, err := models.CreateCommentReaction(ctx.User, comment.Issue, comment, form.Reaction) if err != nil { if models.IsErrForbiddenIssueReaction(err) { - ctx.Error(403, err.Error(), err) + ctx.Error(http.StatusForbidden, err.Error(), err) } else { - ctx.Error(500, "CreateCommentReaction", err) + ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) } return } _, err = reaction.LoadUser() if err != nil { - ctx.Error(500, "Reaction.LoadUser()", err) + ctx.Error(http.StatusInternalServerError, "Reaction.LoadUser()", err) return } - ctx.JSON(201, api.ReactionResponse{ + ctx.JSON(http.StatusCreated, api.ReactionResponse{ User: reaction.User.APIFormat(), Reaction: reaction.Type, Created: reaction.CreatedUnix.AsTime(), @@ -198,10 +208,11 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp // DeleteIssueCommentReaction part err = models.DeleteCommentReaction(ctx.User, comment.Issue, comment, form.Reaction) if err != nil { - ctx.Error(500, "DeleteCommentReaction", err) + ctx.Error(http.StatusInternalServerError, "DeleteCommentReaction", err) return } - ctx.Status(200) + //ToDo respond 204 + ctx.Status(http.StatusOK) } } @@ -234,29 +245,32 @@ func GetIssueReactions(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/ReactionResponseList" + // "403": + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueWithAttrsByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanRead(models.UnitTypeIssues) && !ctx.User.IsAdmin { - ctx.Error(403, "GetIssueReactions", errors.New("no permission to get reactions")) + ctx.Error(http.StatusForbidden, "GetIssueReactions", errors.New("no permission to get reactions")) return } reactions, err := models.FindIssueReactions(issue) if err != nil { - ctx.Error(500, "FindIssueReactions", err) + ctx.Error(http.StatusInternalServerError, "FindIssueReactions", err) return } _, err = reactions.LoadUsers() if err != nil { - ctx.Error(500, "ReactionList.LoadUsers()", err) + ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) return } @@ -269,7 +283,7 @@ func GetIssueReactions(ctx *context.APIContext) { }) } - ctx.JSON(200, result) + ctx.JSON(http.StatusOK, result) } // PostIssueReaction add a reaction to a comment of a issue @@ -305,6 +319,9 @@ func PostIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { // responses: // "201": // "$ref": "#/responses/ReactionResponse" + // "403": + // "$ref": "#/responses/forbidden" + changeIssueReaction(ctx, form, true) } @@ -341,6 +358,9 @@ func DeleteIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { // responses: // "200": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + changeIssueReaction(ctx, form, false) } @@ -350,13 +370,13 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if issue.IsLocked && !ctx.Repo.CanWrite(models.UnitTypeIssues) && !ctx.User.IsAdmin { - ctx.Error(403, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) + ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction")) return } @@ -365,19 +385,19 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i reaction, err := models.CreateIssueReaction(ctx.User, issue, form.Reaction) if err != nil { if models.IsErrForbiddenIssueReaction(err) { - ctx.Error(403, err.Error(), err) + ctx.Error(http.StatusForbidden, err.Error(), err) } else { - ctx.Error(500, "CreateCommentReaction", err) + ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) } return } _, err = reaction.LoadUser() if err != nil { - ctx.Error(500, "Reaction.LoadUser()", err) + ctx.Error(http.StatusInternalServerError, "Reaction.LoadUser()", err) return } - ctx.JSON(201, api.ReactionResponse{ + ctx.JSON(http.StatusCreated, api.ReactionResponse{ User: reaction.User.APIFormat(), Reaction: reaction.Type, Created: reaction.CreatedUnix.AsTime(), @@ -386,9 +406,10 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i // DeleteIssueReaction part err = models.DeleteIssueReaction(ctx.User, issue, form.Reaction) if err != nil { - ctx.Error(500, "DeleteIssueReaction", err) + ctx.Error(http.StatusInternalServerError, "DeleteIssueReaction", err) return } - ctx.Status(200) + //ToDo respond 204 + ctx.Status(http.StatusOK) } } diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 48b2f6498f..3ffdf24404 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" ) @@ -41,20 +43,21 @@ func StartIssueStopwatch(ctx *context.APIContext) { // "403": // description: Not repo writer, user does not have rights to toggle stopwatch // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" // "409": // description: Cannot start a stopwatch again if it already exists + issue, err := prepareIssueStopwatch(ctx, false) if err != nil { return } if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { - ctx.Error(500, "CreateOrStopIssueStopwatch", err) + ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } - ctx.Status(201) + ctx.Status(http.StatusCreated) } // StopIssueStopwatch stops a stopwatch for the given issue. @@ -89,20 +92,21 @@ func StopIssueStopwatch(ctx *context.APIContext) { // "403": // description: Not repo writer, user does not have rights to toggle stopwatch // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" // "409": // description: Cannot stop a non existent stopwatch + issue, err := prepareIssueStopwatch(ctx, true) if err != nil { return } if err := models.CreateOrStopIssueStopwatch(ctx.User, issue); err != nil { - ctx.Error(500, "CreateOrStopIssueStopwatch", err) + ctx.Error(http.StatusInternalServerError, "CreateOrStopIssueStopwatch", err) return } - ctx.Status(201) + ctx.Status(http.StatusCreated) } // DeleteIssueStopwatch delete a specific stopwatch @@ -137,20 +141,21 @@ func DeleteIssueStopwatch(ctx *context.APIContext) { // "403": // description: Not repo writer, user does not have rights to toggle stopwatch // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" // "409": // description: Cannot cancel a non existent stopwatch + issue, err := prepareIssueStopwatch(ctx, true) if err != nil { return } if err := models.CancelStopwatch(ctx.User, issue); err != nil { - ctx.Error(500, "CancelStopwatch", err) + ctx.Error(http.StatusInternalServerError, "CancelStopwatch", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.Issue, error) { @@ -159,27 +164,27 @@ func prepareIssueStopwatch(ctx *context.APIContext, shouldExist bool) (*models.I if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return nil, err } if !ctx.Repo.CanWrite(models.UnitTypeIssues) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return nil, err } if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return nil, err } if models.StopwatchExists(ctx.User.ID, issue.ID) != shouldExist { if shouldExist { - ctx.Error(409, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") + ctx.Error(http.StatusConflict, "StopwatchExists", "cannot stop/cancel a non existent stopwatch") } else { - ctx.Error(409, "StopwatchExists", "cannot start a stopwatch again if it already exists") + ctx.Error(http.StatusConflict, "StopwatchExists", "cannot start a stopwatch again if it already exists") } return nil, err } @@ -202,15 +207,15 @@ func GetStopwatches(ctx *context.APIContext) { sws, err := models.GetUserStopwatches(ctx.User.ID) if err != nil { - ctx.Error(500, "GetUserStopwatches", err) + ctx.Error(http.StatusInternalServerError, "GetUserStopwatches", err) return } apiSWs, err := sws.APIFormat() if err != nil { - ctx.Error(500, "APIFormat", err) + ctx.Error(http.StatusInternalServerError, "APIFormat", err) return } - ctx.JSON(200, apiSWs) + ctx.JSON(http.StatusOK, apiSWs) } diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 2c5f75f1ec..153b01de61 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" ) @@ -46,7 +48,8 @@ func AddIssueSubscription(ctx *context.APIContext) { // "304": // description: User can only subscribe itself if he is no admin // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" + setIssueSubscription(ctx, true) } @@ -87,7 +90,8 @@ func DelIssueSubscription(ctx *context.APIContext) { // "304": // description: User can only subscribe itself if he is no admin // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" + setIssueSubscription(ctx, false) } @@ -97,7 +101,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return @@ -108,7 +112,7 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { if models.IsErrUserNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetUserByName", err) + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) } return @@ -116,16 +120,16 @@ func setIssueSubscription(ctx *context.APIContext, watch bool) { //only admin and user for itself can change subscription if user.ID != ctx.User.ID && !ctx.User.IsAdmin { - ctx.Error(403, "User", nil) + ctx.Error(http.StatusForbidden, "User", nil) return } if err := models.CreateOrUpdateIssueWatch(user.ID, issue.ID, watch); err != nil { - ctx.Error(500, "CreateOrUpdateIssueWatch", err) + ctx.Error(http.StatusInternalServerError, "CreateOrUpdateIssueWatch", err) return } - ctx.Status(201) + ctx.Status(http.StatusCreated) } // GetIssueSubscribers return subscribers of an issue @@ -158,13 +162,14 @@ func GetIssueSubscribers(ctx *context.APIContext) { // "200": // "$ref": "#/responses/UserList" // "404": - // description: Issue not found + // "$ref": "#/responses/notFound" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return @@ -172,15 +177,15 @@ func GetIssueSubscribers(ctx *context.APIContext) { iwl, err := models.GetIssueWatchers(issue.ID) if err != nil { - ctx.Error(500, "GetIssueWatchers", err) + ctx.Error(http.StatusInternalServerError, "GetIssueWatchers", err) return } users, err := iwl.LoadWatchUsers() if err != nil { - ctx.Error(500, "LoadWatchUsers", err) + ctx.Error(http.StatusInternalServerError, "LoadWatchUsers", err) return } - ctx.JSON(200, users.APIFormat()) + ctx.JSON(http.StatusOK, users.APIFormat()) } diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index c38ea05c36..0d3ca5c177 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" @@ -45,6 +47,9 @@ func ListTrackedTimes(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/TrackedTimeList" + // "404": + // "$ref": "#/responses/notFound" + if !ctx.Repo.Repository.IsTimetrackerEnabled() { ctx.NotFound("Timetracker is disabled") return @@ -54,18 +59,18 @@ func ListTrackedTimes(ctx *context.APIContext) { if models.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{IssueID: issue.ID}) if err != nil { - ctx.Error(500, "GetTrackedTimesByIssue", err) + ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByIssue", err) return } apiTrackedTimes := trackedTimesToAPIFormat(trackedTimes) - ctx.JSON(200, &apiTrackedTimes) + ctx.JSON(http.StatusOK, &apiTrackedTimes) } // AddTime adds time manual to the given issue @@ -104,31 +109,32 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) { // "400": // "$ref": "#/responses/error" // "403": - // "$ref": "#/responses/error" + // "$ref": "#/responses/forbidden" + issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrIssueNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetIssueByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) } return } if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { if !ctx.Repo.Repository.IsTimetrackerEnabled() { - ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"}) + ctx.Error(http.StatusBadRequest, "", "time tracking disabled") return } - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } trackedTime, err := models.AddTime(ctx.User, issue, form.Time) if err != nil { - ctx.Error(500, "AddTime", err) + ctx.Error(http.StatusInternalServerError, "AddTime", err) return } - ctx.JSON(200, trackedTime.APIFormat()) + ctx.JSON(http.StatusOK, trackedTime.APIFormat()) } // ListTrackedTimesByUser lists all tracked times of the user @@ -157,8 +163,11 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/TrackedTimeList" + // "400": + // "$ref": "#/responses/error" + if !ctx.Repo.Repository.IsTimetrackerEnabled() { - ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"}) + ctx.Error(http.StatusBadRequest, "", "time tracking disabled") return } user, err := models.GetUserByName(ctx.Params(":timetrackingusername")) @@ -166,7 +175,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { if models.IsErrUserNotExist(err) { ctx.NotFound(err) } else { - ctx.Error(500, "GetUserByName", err) + ctx.Error(http.StatusInternalServerError, "GetUserByName", err) } return } @@ -178,11 +187,11 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { UserID: user.ID, RepositoryID: ctx.Repo.Repository.ID}) if err != nil { - ctx.Error(500, "GetTrackedTimesByUser", err) + ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) return } apiTrackedTimes := trackedTimesToAPIFormat(trackedTimes) - ctx.JSON(200, &apiTrackedTimes) + ctx.JSON(http.StatusOK, &apiTrackedTimes) } // ListTrackedTimesByRepository lists all tracked times of the repository @@ -206,18 +215,21 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/TrackedTimeList" + // "400": + // "$ref": "#/responses/error" + if !ctx.Repo.Repository.IsTimetrackerEnabled() { - ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"}) + ctx.Error(http.StatusBadRequest, "", "time tracking disabled") return } trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{ RepositoryID: ctx.Repo.Repository.ID}) if err != nil { - ctx.Error(500, "GetTrackedTimesByUser", err) + ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) return } apiTrackedTimes := trackedTimesToAPIFormat(trackedTimes) - ctx.JSON(200, &apiTrackedTimes) + ctx.JSON(http.StatusOK, &apiTrackedTimes) } // ListMyTrackedTimes lists all tracked times of the current user @@ -230,11 +242,12 @@ func ListMyTrackedTimes(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/TrackedTimeList" + trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{UserID: ctx.User.ID}) if err != nil { - ctx.Error(500, "GetTrackedTimesByUser", err) + ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) return } apiTrackedTimes := trackedTimesToAPIFormat(trackedTimes) - ctx.JSON(200, &apiTrackedTimes) + ctx.JSON(http.StatusOK, &apiTrackedTimes) } diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 6b499d2fb1..4ced8ec42f 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -6,6 +6,7 @@ package repo import ( "fmt" + "net/http" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -62,6 +63,7 @@ func ListDeployKeys(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/DeployKeyList" + var keys []*models.DeployKey var err error @@ -74,7 +76,7 @@ func ListDeployKeys(ctx *context.APIContext) { } if err != nil { - ctx.Error(500, "ListDeployKeys", err) + ctx.Error(http.StatusInternalServerError, "ListDeployKeys", err) return } @@ -82,7 +84,7 @@ func ListDeployKeys(ctx *context.APIContext) { apiKeys := make([]*api.DeployKey, len(keys)) for i := range keys { if err = keys[i].GetContent(); err != nil { - ctx.Error(500, "GetContent", err) + ctx.Error(http.StatusInternalServerError, "GetContent", err) return } apiKeys[i] = convert.ToDeployKey(apiLink, keys[i]) @@ -91,7 +93,7 @@ func ListDeployKeys(ctx *context.APIContext) { } } - ctx.JSON(200, &apiKeys) + ctx.JSON(http.StatusOK, &apiKeys) } // GetDeployKey get a deploy key by id @@ -121,18 +123,19 @@ func GetDeployKey(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/DeployKey" + key, err := models.GetDeployKeyByID(ctx.ParamsInt64(":id")) if err != nil { if models.IsErrDeployKeyNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetDeployKeyByID", err) + ctx.Error(http.StatusInternalServerError, "GetDeployKeyByID", err) } return } if err = key.GetContent(); err != nil { - ctx.Error(500, "GetContent", err) + ctx.Error(http.StatusInternalServerError, "GetContent", err) return } @@ -141,17 +144,17 @@ func GetDeployKey(ctx *context.APIContext) { if ctx.User.IsAdmin || ((ctx.Repo.Repository.ID == key.RepoID) && (ctx.User.ID == ctx.Repo.Owner.ID)) { apiKey, _ = appendPrivateInformation(apiKey, key, ctx.Repo.Repository) } - ctx.JSON(200, apiKey) + ctx.JSON(http.StatusOK, apiKey) } // HandleCheckKeyStringError handle check key error func HandleCheckKeyStringError(ctx *context.APIContext, err error) { if models.IsErrSSHDisabled(err) { - ctx.Error(422, "", "SSH is disabled") + ctx.Error(http.StatusUnprocessableEntity, "", "SSH is disabled") } else if models.IsErrKeyUnableVerify(err) { - ctx.Error(422, "", "Unable to verify key content") + ctx.Error(http.StatusUnprocessableEntity, "", "Unable to verify key content") } else { - ctx.Error(422, "", fmt.Errorf("Invalid key content: %v", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("Invalid key content: %v", err)) } } @@ -159,13 +162,13 @@ func HandleCheckKeyStringError(ctx *context.APIContext, err error) { func HandleAddKeyError(ctx *context.APIContext, err error) { switch { case models.IsErrDeployKeyAlreadyExist(err): - ctx.Error(422, "", "This key has already been added to this repository") + ctx.Error(http.StatusUnprocessableEntity, "", "This key has already been added to this repository") case models.IsErrKeyAlreadyExist(err): - ctx.Error(422, "", "Key content has been used as non-deploy key") + ctx.Error(http.StatusUnprocessableEntity, "", "Key content has been used as non-deploy key") case models.IsErrKeyNameAlreadyUsed(err): - ctx.Error(422, "", "Key title has been used") + ctx.Error(http.StatusUnprocessableEntity, "", "Key title has been used") default: - ctx.Error(500, "AddKey", err) + ctx.Error(http.StatusInternalServerError, "AddKey", err) } } @@ -196,6 +199,9 @@ func CreateDeployKey(ctx *context.APIContext, form api.CreateKeyOption) { // responses: // "201": // "$ref": "#/responses/DeployKey" + // "422": + // "$ref": "#/responses/validationError" + content, err := models.CheckPublicKeyString(form.Key) if err != nil { HandleCheckKeyStringError(ctx, err) @@ -210,7 +216,7 @@ func CreateDeployKey(ctx *context.APIContext, form api.CreateKeyOption) { key.Content = content apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name) - ctx.JSON(201, convert.ToDeployKey(apiLink, key)) + ctx.JSON(http.StatusCreated, convert.ToDeployKey(apiLink, key)) } // DeleteDeploykey delete deploy key for a repository @@ -238,14 +244,17 @@ func DeleteDeploykey(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + if err := models.DeleteDeployKey(ctx.User, ctx.ParamsInt64(":id")); err != nil { if models.IsErrKeyAccessDenied(err) { - ctx.Error(403, "", "You do not have access to this key") + ctx.Error(http.StatusForbidden, "", "You do not have access to this key") } else { - ctx.Error(500, "DeleteDeployKey", err) + ctx.Error(http.StatusInternalServerError, "DeleteDeployKey", err) } return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 33574c481e..16c905878d 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -6,6 +6,7 @@ package repo import ( + "net/http" "strconv" "code.gitea.io/gitea/models" @@ -34,9 +35,10 @@ func ListLabels(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/LabelList" + labels, err := models.GetLabelsByRepoID(ctx.Repo.Repository.ID, ctx.Query("sort")) if err != nil { - ctx.Error(500, "GetLabelsByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsByRepoID", err) return } @@ -44,7 +46,7 @@ func ListLabels(ctx *context.APIContext) { for i := range labels { apiLabels[i] = labels[i].APIFormat() } - ctx.JSON(200, &apiLabels) + ctx.JSON(http.StatusOK, &apiLabels) } // GetLabel get label by repository and label id @@ -74,6 +76,7 @@ func GetLabel(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Label" + var ( label *models.Label err error @@ -88,12 +91,12 @@ func GetLabel(ctx *context.APIContext) { if models.IsErrLabelNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetLabelByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) } return } - ctx.JSON(200, label.APIFormat()) + ctx.JSON(http.StatusOK, label.APIFormat()) } // CreateLabel create a label for a repository @@ -123,6 +126,7 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { // responses: // "201": // "$ref": "#/responses/Label" + label := &models.Label{ Name: form.Name, Color: form.Color, @@ -130,10 +134,10 @@ func CreateLabel(ctx *context.APIContext, form api.CreateLabelOption) { Description: form.Description, } if err := models.NewLabel(label); err != nil { - ctx.Error(500, "NewLabel", err) + ctx.Error(http.StatusInternalServerError, "NewLabel", err) return } - ctx.JSON(201, label.APIFormat()) + ctx.JSON(http.StatusCreated, label.APIFormat()) } // EditLabel modify a label for a repository @@ -169,12 +173,13 @@ func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { // responses: // "200": // "$ref": "#/responses/Label" + label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrLabelNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetLabelByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetLabelByRepoID", err) } return } @@ -192,7 +197,7 @@ func EditLabel(ctx *context.APIContext, form api.EditLabelOption) { ctx.ServerError("UpdateLabel", err) return } - ctx.JSON(200, label.APIFormat()) + ctx.JSON(http.StatusOK, label.APIFormat()) } // DeleteLabel delete a label for a repository @@ -220,10 +225,11 @@ func DeleteLabel(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + if err := models.DeleteLabel(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { - ctx.Error(500, "DeleteLabel", err) + ctx.Error(http.StatusInternalServerError, "DeleteLabel", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index 9bc73852ca..a979e2b69b 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -5,6 +5,7 @@ package repo import ( + "net/http" "time" "code.gitea.io/gitea/models" @@ -38,9 +39,10 @@ func ListMilestones(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/MilestoneList" + milestones, err := models.GetMilestonesByRepoID(ctx.Repo.Repository.ID, api.StateType(ctx.Query("state"))) if err != nil { - ctx.Error(500, "GetMilestonesByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetMilestonesByRepoID", err) return } @@ -48,7 +50,7 @@ func ListMilestones(ctx *context.APIContext) { for i := range milestones { apiMilestones[i] = milestones[i].APIFormat() } - ctx.JSON(200, &apiMilestones) + ctx.JSON(http.StatusOK, &apiMilestones) } // GetMilestone get a milestone for a repository @@ -78,16 +80,17 @@ func GetMilestone(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Milestone" + milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrMilestoneNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetMilestoneByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) } return } - ctx.JSON(200, milestone.APIFormat()) + ctx.JSON(http.StatusOK, milestone.APIFormat()) } // CreateMilestone create a milestone for a repository @@ -117,6 +120,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { // responses: // "201": // "$ref": "#/responses/Milestone" + if form.Deadline == nil { defaultDeadline, _ := time.ParseInLocation("2006-01-02", "9999-12-31", time.Local) form.Deadline = &defaultDeadline @@ -130,10 +134,10 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) { } if err := models.NewMilestone(milestone); err != nil { - ctx.Error(500, "NewMilestone", err) + ctx.Error(http.StatusInternalServerError, "NewMilestone", err) return } - ctx.JSON(201, milestone.APIFormat()) + ctx.JSON(http.StatusCreated, milestone.APIFormat()) } // EditMilestone modify a milestone for a repository @@ -169,12 +173,13 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { // responses: // "200": // "$ref": "#/responses/Milestone" + milestone, err := models.GetMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")) if err != nil { if models.IsErrMilestoneNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetMilestoneByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) } return } @@ -193,7 +198,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) { ctx.ServerError("UpdateMilestone", err) return } - ctx.JSON(200, milestone.APIFormat()) + ctx.JSON(http.StatusOK, milestone.APIFormat()) } // DeleteMilestone delete a milestone for a repository @@ -221,9 +226,10 @@ func DeleteMilestone(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + if err := models.DeleteMilestoneByRepoID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id")); err != nil { - ctx.Error(500, "DeleteMilestoneByRepoID", err) + ctx.Error(http.StatusInternalServerError, "DeleteMilestoneByRepoID", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 1c273b7dc9..0392eb8e8c 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -70,6 +70,7 @@ func ListPullRequests(ctx *context.APIContext, form api.ListPullRequestsOptions) // responses: // "200": // "$ref": "#/responses/PullRequestList" + prs, maxResults, err := models.PullRequests(ctx.Repo.Repository.ID, &models.PullRequestsOptions{ Page: ctx.QueryInt("page"), State: ctx.QueryTrim("state"), @@ -79,33 +80,33 @@ func ListPullRequests(ctx *context.APIContext, form api.ListPullRequestsOptions) }) if err != nil { - ctx.Error(500, "PullRequests", err) + ctx.Error(http.StatusInternalServerError, "PullRequests", err) return } apiPrs := make([]*api.PullRequest, len(prs)) for i := range prs { if err = prs[i].LoadIssue(); err != nil { - ctx.Error(500, "LoadIssue", err) + ctx.Error(http.StatusInternalServerError, "LoadIssue", err) return } if err = prs[i].LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } if err = prs[i].GetBaseRepo(); err != nil { - ctx.Error(500, "GetBaseRepo", err) + ctx.Error(http.StatusInternalServerError, "GetBaseRepo", err) return } if err = prs[i].GetHeadRepo(); err != nil { - ctx.Error(500, "GetHeadRepo", err) + ctx.Error(http.StatusInternalServerError, "GetHeadRepo", err) return } apiPrs[i] = prs[i].APIFormat() } ctx.SetLinkHeader(int(maxResults), models.ItemsPerPage) - ctx.JSON(200, &apiPrs) + ctx.JSON(http.StatusOK, &apiPrs) } // GetPullRequest returns a single PR based on index @@ -135,25 +136,26 @@ func GetPullRequest(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/PullRequest" + pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetPullRequestByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } return } if err = pr.GetBaseRepo(); err != nil { - ctx.Error(500, "GetBaseRepo", err) + ctx.Error(http.StatusInternalServerError, "GetBaseRepo", err) return } if err = pr.GetHeadRepo(); err != nil { - ctx.Error(500, "GetHeadRepo", err) + ctx.Error(http.StatusInternalServerError, "GetHeadRepo", err) return } - ctx.JSON(200, pr.APIFormat()) + ctx.JSON(http.StatusOK, pr.APIFormat()) } // CreatePullRequest does what it says @@ -183,6 +185,11 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption // responses: // "201": // "$ref": "#/responses/PullRequest" + // "409": + // "$ref": "#/responses/error" + // "422": + // "$ref": "#/responses/validationError" + var ( repo = ctx.Repo.Repository labelIDs []int64 @@ -201,7 +208,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption existingPr, err := models.GetUnmergedPullRequest(headRepo.ID, ctx.Repo.Repository.ID, headBranch, baseBranch) if err != nil { if !models.IsErrPullRequestNotExist(err) { - ctx.Error(500, "GetUnmergedPullRequest", err) + ctx.Error(http.StatusInternalServerError, "GetUnmergedPullRequest", err) return } } else { @@ -213,14 +220,14 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption HeadBranch: existingPr.HeadBranch, BaseBranch: existingPr.BaseBranch, } - ctx.Error(409, "GetUnmergedPullRequest", err) + ctx.Error(http.StatusConflict, "GetUnmergedPullRequest", err) return } if len(form.Labels) > 0 { labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(500, "GetLabelsInRepoByIDs", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDs", err) return } @@ -236,7 +243,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption if models.IsErrMilestoneNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetMilestoneByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetMilestoneByRepoID", err) } return } @@ -275,9 +282,9 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption assigneeIDs, err := models.MakeIDsFromAPIAssigneesToAdd(form.Assignee, form.Assignees) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else { - ctx.Error(500, "AddAssigneeByName", err) + ctx.Error(http.StatusInternalServerError, "AddAssigneeByName", err) } return } @@ -285,34 +292,34 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption for _, aID := range assigneeIDs { assignee, err := models.GetUserByID(aID) if err != nil { - ctx.Error(500, "GetUserByID", err) + ctx.Error(http.StatusInternalServerError, "GetUserByID", err) return } valid, err := models.CanBeAssigned(assignee, repo, true) if err != nil { - ctx.Error(500, "canBeAssigned", err) + ctx.Error(http.StatusInternalServerError, "canBeAssigned", err) return } if !valid { - ctx.Error(422, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) + ctx.Error(http.StatusUnprocessableEntity, "canBeAssigned", models.ErrUserDoesNotHaveAccessToRepo{UserID: aID, RepoName: repo.Name}) return } } if err := pull_service.NewPullRequest(repo, prIssue, labelIDs, []string{}, pr, assigneeIDs); err != nil { if models.IsErrUserDoesNotHaveAccessToRepo(err) { - ctx.Error(400, "UserDoesNotHaveAccessToRepo", err) + ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err) return } - ctx.Error(500, "NewPullRequest", err) + ctx.Error(http.StatusInternalServerError, "NewPullRequest", err) return } notification.NotifyNewPullRequest(pr) log.Trace("Pull request created: %d/%d", repo.ID, prIssue.ID) - ctx.JSON(201, pr.APIFormat()) + ctx.JSON(http.StatusCreated, pr.APIFormat()) } // EditPullRequest does what it says @@ -348,12 +355,19 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { // responses: // "201": // "$ref": "#/responses/PullRequest" + // "403": + // "$ref": "#/responses/forbidden" + // "412": + // "$ref": "#/responses/error" + // "422": + // "$ref": "#/responses/validationError" + pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetPullRequestByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } return } @@ -367,7 +381,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { issue.Repo = ctx.Repo.Repository if !issue.IsPoster(ctx.User.ID) && !ctx.Repo.CanWrite(models.UnitTypePullRequests) { - ctx.Status(403) + ctx.Status(http.StatusForbidden) return } @@ -388,7 +402,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { } if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil { - ctx.Error(500, "UpdateIssueDeadline", err) + ctx.Error(http.StatusInternalServerError, "UpdateIssueDeadline", err) return } issue.DeadlineUnix = deadlineUnix @@ -406,9 +420,9 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { err = issue_service.UpdateAssignees(issue, form.Assignee, form.Assignees, ctx.User) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Assignee does not exist: [name: %s]", err)) } else { - ctx.Error(500, "UpdateAssignees", err) + ctx.Error(http.StatusInternalServerError, "UpdateAssignees", err) } return } @@ -419,7 +433,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = form.Milestone if err = issue_service.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil { - ctx.Error(500, "ChangeMilestoneAssign", err) + ctx.Error(http.StatusInternalServerError, "ChangeMilestoneAssign", err) return } } @@ -427,17 +441,17 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { if ctx.Repo.CanWrite(models.UnitTypePullRequests) && form.Labels != nil { labels, err := models.GetLabelsInRepoByIDs(ctx.Repo.Repository.ID, form.Labels) if err != nil { - ctx.Error(500, "GetLabelsInRepoByIDsError", err) + ctx.Error(http.StatusInternalServerError, "GetLabelsInRepoByIDsError", err) return } if err = issue.ReplaceLabels(labels, ctx.User); err != nil { - ctx.Error(500, "ReplaceLabelsError", err) + ctx.Error(http.StatusInternalServerError, "ReplaceLabelsError", err) return } } if err = models.UpdateIssue(issue); err != nil { - ctx.Error(500, "UpdateIssue", err) + ctx.Error(http.StatusInternalServerError, "UpdateIssue", err) return } if form.State != nil { @@ -446,7 +460,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies") return } - ctx.Error(500, "ChangeStatus", err) + ctx.Error(http.StatusInternalServerError, "ChangeStatus", err) return } } @@ -457,13 +471,13 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) { if models.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetPullRequestByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } return } // TODO this should be 200, not 201 - ctx.JSON(201, pr.APIFormat()) + ctx.JSON(http.StatusCreated, pr.APIFormat()) } // IsPullRequestMerged checks if a PR exists given an index @@ -495,18 +509,19 @@ func IsPullRequestMerged(ctx *context.APIContext) { // description: pull request has been merged // "404": // description: pull request has not been merged + pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetPullRequestByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } return } if pr.HasMerged { - ctx.Status(204) + ctx.Status(http.StatusNoContent) } ctx.NotFound() } @@ -544,12 +559,15 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { // "$ref": "#/responses/empty" // "405": // "$ref": "#/responses/empty" + // "409": + // "$ref": "#/responses/error" + pr, err := models.GetPullRequestByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) if err != nil { if models.IsErrPullRequestNotExist(err) { ctx.NotFound("GetPullRequestByIndex", err) } else { - ctx.Error(500, "GetPullRequestByIndex", err) + ctx.Error(http.StatusInternalServerError, "GetPullRequestByIndex", err) } return } @@ -569,7 +587,7 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { if ctx.IsSigned { // Update issue-user. if err = pr.Issue.ReadBy(ctx.User.ID); err != nil { - ctx.Error(500, "ReadBy", err) + ctx.Error(http.StatusInternalServerError, "ReadBy", err) return } } @@ -580,18 +598,18 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { } if !pr.CanAutoMerge() || pr.HasMerged || pr.IsWorkInProgress() { - ctx.Status(405) + ctx.Status(http.StatusMethodNotAllowed) return } isPass, err := pull_service.IsPullCommitStatusPass(pr) if err != nil { - ctx.Error(500, "IsPullCommitStatusPass", err) + ctx.Error(http.StatusInternalServerError, "IsPullCommitStatusPass", err) return } if !isPass && !ctx.IsUserRepoAdmin() { - ctx.Status(405) + ctx.Status(http.StatusMethodNotAllowed) return } @@ -616,7 +634,7 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { if err := pull_service.Merge(pr, ctx.User, ctx.Repo.GitRepo, models.MergeStyle(form.Do), message); err != nil { if models.IsErrInvalidMergeStyle(err) { - ctx.Status(405) + ctx.Status(http.StatusMethodNotAllowed) return } else if models.IsErrMergeConflicts(err) { conflictError := err.(models.ErrMergeConflicts) @@ -628,15 +646,15 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) { conflictError := err.(models.ErrMergeUnrelatedHistories) ctx.JSON(http.StatusConflict, conflictError) } else if models.IsErrMergePushOutOfDate(err) { - ctx.Status(http.StatusConflict) + ctx.Error(http.StatusConflict, "Merge", "merge push out of date") return } - ctx.Error(500, "Merge", err) + ctx.Error(http.StatusInternalServerError, "Merge", err) return } log.Trace("Pull request merged: %d", pr.ID) - ctx.Status(200) + ctx.Status(http.StatusOK) } func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) (*models.User, *models.Repository, *git.Repository, *git.CompareInfo, string, string) { @@ -706,7 +724,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) } else { headGitRepo, err = git.OpenRepository(models.RepoPath(headUser.Name, headRepo.Name)) if err != nil { - ctx.Error(500, "OpenRepository", err) + ctx.Error(http.StatusInternalServerError, "OpenRepository", err) return nil, nil, nil, nil, "", "" } } @@ -759,7 +777,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption) compareInfo, err := headGitRepo.GetCompareInfo(models.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch) if err != nil { headGitRepo.Close() - ctx.Error(500, "GetCompareInfo", err) + ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err) return nil, nil, nil, nil, "", "" } diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 8bcebf6b40..f94d6ba635 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/setting" @@ -39,10 +41,11 @@ func GetRelease(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Release" + id := ctx.ParamsInt64(":id") release, err := models.GetReleaseByID(id) if err != nil { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } if release.RepoID != ctx.Repo.Repository.ID { @@ -50,10 +53,10 @@ func GetRelease(ctx *context.APIContext) { return } if err := release.LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(200, release.APIFormat()) + ctx.JSON(http.StatusOK, release.APIFormat()) } func getPagesInfo(ctx *context.APIContext) (int, int) { @@ -99,24 +102,25 @@ func ListReleases(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/ReleaseList" + page, limit := getPagesInfo(ctx) releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{ IncludeDrafts: ctx.Repo.AccessMode >= models.AccessModeWrite, IncludeTags: false, }, page, limit) if err != nil { - ctx.Error(500, "GetReleasesByRepoID", err) + ctx.Error(http.StatusInternalServerError, "GetReleasesByRepoID", err) return } rels := make([]*api.Release, len(releases)) for i, release := range releases { if err := release.LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } rels[i] = release.APIFormat() } - ctx.JSON(200, rels) + ctx.JSON(http.StatusOK, rels) } // CreateRelease create a release @@ -146,6 +150,9 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { // responses: // "201": // "$ref": "#/responses/Release" + // "409": + // "$ref": "#/responses/error" + rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName) if err != nil { if !models.IsErrReleaseNotExist(err) { @@ -171,15 +178,15 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { } if err := releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil { if models.IsErrReleaseAlreadyExist(err) { - ctx.Status(409) + ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err) } else { - ctx.Error(500, "CreateRelease", err) + ctx.Error(http.StatusInternalServerError, "CreateRelease", err) } return } } else { if !rel.IsTag { - ctx.Status(409) + ctx.Error(http.StatusConflict, "GetRelease", "Release is has no Tag") return } @@ -197,7 +204,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { return } } - ctx.JSON(201, rel.APIFormat()) + ctx.JSON(http.StatusCreated, rel.APIFormat()) } // EditRelease edit a release @@ -233,10 +240,11 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) { // responses: // "200": // "$ref": "#/responses/Release" + id := ctx.ParamsInt64(":id") rel, err := models.GetReleaseByID(id) if err != nil && !models.IsErrReleaseNotExist(err) { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } if err != nil && models.IsErrReleaseNotExist(err) || @@ -264,20 +272,20 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) { rel.IsPrerelease = *form.IsPrerelease } if err := releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil { - ctx.Error(500, "UpdateRelease", err) + ctx.Error(http.StatusInternalServerError, "UpdateRelease", err) return } rel, err = models.GetReleaseByID(id) if err != nil { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } if err := rel.LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(200, rel.APIFormat()) + ctx.JSON(http.StatusOK, rel.APIFormat()) } // DeleteRelease delete a release from a repository @@ -305,10 +313,11 @@ func DeleteRelease(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + id := ctx.ParamsInt64(":id") rel, err := models.GetReleaseByID(id) if err != nil && !models.IsErrReleaseNotExist(err) { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } if err != nil && models.IsErrReleaseNotExist(err) || @@ -317,8 +326,8 @@ func DeleteRelease(ctx *context.APIContext) { return } if err := releaseservice.DeleteReleaseByID(id, ctx.User, false); err != nil { - ctx.Error(500, "DeleteReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index c49e4d3e34..6ba6489e27 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -5,6 +5,7 @@ package repo import ( + "net/http" "strings" "code.gitea.io/gitea/models" @@ -48,11 +49,12 @@ func GetReleaseAttachment(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Attachment" + releaseID := ctx.ParamsInt64(":id") attachID := ctx.ParamsInt64(":asset") attach, err := models.GetAttachmentByID(attachID) if err != nil { - ctx.Error(500, "GetAttachmentByID", err) + ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } if attach.ReleaseID != releaseID { @@ -61,7 +63,7 @@ func GetReleaseAttachment(ctx *context.APIContext) { return } // FIXME Should prove the existence of the given repo, but results in unnecessary database requests - ctx.JSON(200, attach.APIFormat()) + ctx.JSON(http.StatusOK, attach.APIFormat()) } // ListReleaseAttachments lists all attachments of the release @@ -91,10 +93,11 @@ func ListReleaseAttachments(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/AttachmentList" + releaseID := ctx.ParamsInt64(":id") release, err := models.GetReleaseByID(releaseID) if err != nil { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } if release.RepoID != ctx.Repo.Repository.ID { @@ -102,10 +105,10 @@ func ListReleaseAttachments(ctx *context.APIContext) { return } if err := release.LoadAttributes(); err != nil { - ctx.Error(500, "LoadAttributes", err) + ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) return } - ctx.JSON(200, release.APIFormat().Attachments) + ctx.JSON(http.StatusOK, release.APIFormat().Attachments) } // CreateReleaseAttachment creates an attachment and saves the given file @@ -147,6 +150,8 @@ func CreateReleaseAttachment(ctx *context.APIContext) { // responses: // "201": // "$ref": "#/responses/Attachment" + // "400": + // "$ref": "#/responses/error" // Check if attachments are enabled if !setting.AttachmentEnabled { @@ -158,14 +163,14 @@ func CreateReleaseAttachment(ctx *context.APIContext) { releaseID := ctx.ParamsInt64(":id") release, err := models.GetReleaseByID(releaseID) if err != nil { - ctx.Error(500, "GetReleaseByID", err) + ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err) return } // Get uploaded file from request file, header, err := ctx.GetFile("attachment") if err != nil { - ctx.Error(500, "GetFile", err) + ctx.Error(http.StatusInternalServerError, "GetFile", err) return } defer file.Close() @@ -179,7 +184,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { // Check if the filetype is allowed by the settings err = upload.VerifyAllowedContentType(buf, strings.Split(setting.AttachmentAllowedTypes, ",")) if err != nil { - ctx.Error(400, "DetectContentType", err) + ctx.Error(http.StatusBadRequest, "DetectContentType", err) return } @@ -195,11 +200,11 @@ func CreateReleaseAttachment(ctx *context.APIContext) { ReleaseID: release.ID, }, buf, file) if err != nil { - ctx.Error(500, "NewAttachment", err) + ctx.Error(http.StatusInternalServerError, "NewAttachment", err) return } - ctx.JSON(201, attach.APIFormat()) + ctx.JSON(http.StatusCreated, attach.APIFormat()) } // EditReleaseAttachment updates the given attachment @@ -247,7 +252,7 @@ func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptio attachID := ctx.ParamsInt64(":asset") attach, err := models.GetAttachmentByID(attachID) if err != nil { - ctx.Error(500, "GetAttachmentByID", err) + ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } if attach.ReleaseID != releaseID { @@ -261,9 +266,9 @@ func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptio } if err := models.UpdateAttachment(attach); err != nil { - ctx.Error(500, "UpdateAttachment", attach) + ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach) } - ctx.JSON(201, attach.APIFormat()) + ctx.JSON(http.StatusCreated, attach.APIFormat()) } // DeleteReleaseAttachment delete a given attachment @@ -305,7 +310,7 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { attachID := ctx.ParamsInt64(":asset") attach, err := models.GetAttachmentByID(attachID) if err != nil { - ctx.Error(500, "GetAttachmentByID", err) + ctx.Error(http.StatusInternalServerError, "GetAttachmentByID", err) return } if attach.ReleaseID != releaseID { @@ -316,8 +321,8 @@ func DeleteReleaseAttachment(ctx *context.APIContext) { // FIXME Should prove the existence of the given repo, but results in unnecessary database requests if err := models.DeleteAttachment(attach, true); err != nil { - ctx.Error(500, "DeleteAttachment", err) + ctx.Error(http.StatusInternalServerError, "DeleteAttachment", err) return } - ctx.Status(204) + ctx.Status(http.StatusNoContent) } diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index be226c3438..8f34d8cca3 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -124,6 +124,7 @@ func Search(ctx *context.APIContext) { // "$ref": "#/responses/SearchResults" // "422": // "$ref": "#/responses/validationError" + opts := &models.SearchRepoOptions{ Keyword: strings.Trim(ctx.Query("q"), " "), OwnerID: ctx.QueryInt64("uid"), @@ -188,7 +189,7 @@ func Search(ctx *context.APIContext) { var err error repos, count, err := models.SearchRepository(opts) if err != nil { - ctx.JSON(500, api.SearchError{ + ctx.JSON(http.StatusInternalServerError, api.SearchError{ OK: false, Error: err.Error(), }) @@ -198,7 +199,7 @@ func Search(ctx *context.APIContext) { results := make([]*api.Repository, len(repos)) for i, repo := range repos { if err = repo.GetOwner(); err != nil { - ctx.JSON(500, api.SearchError{ + ctx.JSON(http.StatusInternalServerError, api.SearchError{ OK: false, Error: err.Error(), }) @@ -206,7 +207,7 @@ func Search(ctx *context.APIContext) { } accessMode, err := models.AccessLevel(ctx.User, repo) if err != nil { - ctx.JSON(500, api.SearchError{ + ctx.JSON(http.StatusInternalServerError, api.SearchError{ OK: false, Error: err.Error(), }) @@ -216,7 +217,7 @@ func Search(ctx *context.APIContext) { ctx.SetLinkHeader(int(count), setting.API.MaxResponseItems) ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", count)) - ctx.JSON(200, api.SearchResults{ + ctx.JSON(http.StatusOK, api.SearchResults{ OK: true, Data: results, }) @@ -239,17 +240,17 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR }) if err != nil { if models.IsErrRepoAlreadyExist(err) { - ctx.Error(409, "", "The repository with the same name already exists.") + ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") } else if models.IsErrNameReserved(err) || models.IsErrNamePatternNotAllowed(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "CreateRepository", err) + ctx.Error(http.StatusInternalServerError, "CreateRepository", err) } return } - ctx.JSON(201, repo.APIFormat(models.AccessModeOwner)) + ctx.JSON(http.StatusCreated, repo.APIFormat(models.AccessModeOwner)) } // Create one repository of mine @@ -273,9 +274,10 @@ func Create(ctx *context.APIContext, opt api.CreateRepoOption) { // description: The repository with the same name already exists. // "422": // "$ref": "#/responses/validationError" + if ctx.User.IsOrganization() { // Shouldn't reach this condition, but just in case. - ctx.Error(422, "", "not allowed creating repository for organization") + ctx.Error(http.StatusUnprocessableEntity, "", "not allowed creating repository for organization") return } CreateUserRepo(ctx, ctx.User, opt) @@ -307,12 +309,13 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { // "$ref": "#/responses/validationError" // "403": // "$ref": "#/responses/forbidden" + org, err := models.GetOrgByName(ctx.Params(":org")) if err != nil { if models.IsErrOrgNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetOrgByName", err) + ctx.Error(http.StatusInternalServerError, "GetOrgByName", err) } return } @@ -328,7 +331,7 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) { ctx.ServerError("CanCreateOrgRepo", err) return } else if !canCreate { - ctx.Error(403, "", "Given user is not allowed to create repository in organization.") + ctx.Error(http.StatusForbidden, "", "Given user is not allowed to create repository in organization.") return } } @@ -352,6 +355,11 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { // responses: // "201": // "$ref": "#/responses/Repository" + // "403": + // "$ref": "#/responses/forbidden" + // "422": + // "$ref": "#/responses/validationError" + ctxUser := ctx.User // Not equal means context user is an organization, // or is another user/organization if current user is admin. @@ -359,9 +367,9 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { org, err := models.GetUserByID(form.UID) if err != nil { if models.IsErrUserNotExist(err) { - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) } else { - ctx.Error(500, "GetUserByID", err) + ctx.Error(http.StatusInternalServerError, "GetUserByID", err) } return } @@ -369,13 +377,13 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { } if ctx.HasError() { - ctx.Error(422, "", ctx.GetErrMsg()) + ctx.Error(http.StatusUnprocessableEntity, "", ctx.GetErrMsg()) return } if !ctx.User.IsAdmin { if !ctxUser.IsOrganization() && ctx.User.ID != ctxUser.ID { - ctx.Error(403, "", "Given user is not an organization.") + ctx.Error(http.StatusForbidden, "", "Given user is not an organization.") return } @@ -383,10 +391,10 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { // Check ownership of organization. isOwner, err := ctxUser.IsOwnedBy(ctx.User.ID) if err != nil { - ctx.Error(500, "IsOwnedBy", err) + ctx.Error(http.StatusInternalServerError, "IsOwnedBy", err) return } else if !isOwner { - ctx.Error(403, "", "Given user is not owner of organization.") + ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.") return } } @@ -398,16 +406,16 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { addrErr := err.(models.ErrInvalidCloneAddr) switch { case addrErr.IsURLError: - ctx.Error(422, "", err) + ctx.Error(http.StatusUnprocessableEntity, "", err) case addrErr.IsPermissionDenied: - ctx.Error(422, "", "You are not allowed to import local repositories.") + ctx.Error(http.StatusUnprocessableEntity, "", "You are not allowed to import local repositories.") case addrErr.IsInvalidPath: - ctx.Error(422, "", "Invalid local path, it does not exist or not a directory.") + ctx.Error(http.StatusUnprocessableEntity, "", "Invalid local path, it does not exist or not a directory.") default: - ctx.Error(500, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error()) + ctx.Error(http.StatusInternalServerError, "ParseRemoteAddr", "Unknown error type (ErrInvalidCloneAddr): "+err.Error()) } } else { - ctx.Error(500, "ParseRemoteAddr", err) + ctx.Error(http.StatusInternalServerError, "ParseRemoteAddr", err) } return } @@ -488,33 +496,33 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) { } log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName) - ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin)) + ctx.JSON(http.StatusCreated, repo.APIFormat(models.AccessModeAdmin)) } func handleMigrateError(ctx *context.APIContext, repoOwner *models.User, remoteAddr string, err error) { switch { case models.IsErrRepoAlreadyExist(err): - ctx.Error(409, "", "The repository with the same name already exists.") + ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") case migrations.IsRateLimitError(err): - ctx.Error(422, "", "Remote visit addressed rate limitation.") + ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit addressed rate limitation.") case migrations.IsTwoFactorAuthError(err): - ctx.Error(422, "", "Remote visit required two factors authentication.") + ctx.Error(http.StatusUnprocessableEntity, "", "Remote visit required two factors authentication.") case models.IsErrReachLimitOfRepo(err): - ctx.Error(422, "", fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("You have already reached your limit of %d repositories.", repoOwner.MaxCreationLimit())) case models.IsErrNameReserved(err): - ctx.Error(422, "", fmt.Sprintf("The username '%s' is reserved.", err.(models.ErrNameReserved).Name)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The username '%s' is reserved.", err.(models.ErrNameReserved).Name)) case models.IsErrNamePatternNotAllowed(err): - ctx.Error(422, "", fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(models.ErrNamePatternNotAllowed).Pattern)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("The pattern '%s' is not allowed in a username.", err.(models.ErrNamePatternNotAllowed).Pattern)) default: err = util.URLSanitizedError(err, remoteAddr) if strings.Contains(err.Error(), "Authentication failed") || strings.Contains(err.Error(), "Bad credentials") || strings.Contains(err.Error(), "could not read Username") { - ctx.Error(422, "", fmt.Sprintf("Authentication failed: %v.", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Authentication failed: %v.", err)) } else if strings.Contains(err.Error(), "fatal:") { - ctx.Error(422, "", fmt.Sprintf("Migration failed: %v.", err)) + ctx.Error(http.StatusUnprocessableEntity, "", fmt.Sprintf("Migration failed: %v.", err)) } else { - ctx.Error(500, "MigrateRepository", err) + ctx.Error(http.StatusInternalServerError, "MigrateRepository", err) } } } @@ -540,7 +548,8 @@ func Get(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Repository" - ctx.JSON(200, ctx.Repo.Repository.APIFormat(ctx.Repo.AccessMode)) + + ctx.JSON(http.StatusOK, ctx.Repo.Repository.APIFormat(ctx.Repo.AccessMode)) } // GetByID returns a single Repository @@ -560,25 +569,26 @@ func GetByID(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Repository" + repo, err := models.GetRepositoryByID(ctx.ParamsInt64(":id")) if err != nil { if models.IsErrRepoNotExist(err) { ctx.NotFound() } else { - ctx.Error(500, "GetRepositoryByID", err) + ctx.Error(http.StatusInternalServerError, "GetRepositoryByID", err) } return } perm, err := models.GetUserRepoPermission(repo, ctx.User) if err != nil { - ctx.Error(500, "AccessLevel", err) + ctx.Error(http.StatusInternalServerError, "AccessLevel", err) return } else if !perm.HasAccess() { ctx.NotFound() return } - ctx.JSON(200, repo.APIFormat(perm.AccessMode)) + ctx.JSON(http.StatusOK, repo.APIFormat(perm.AccessMode)) } // Edit edit repository properties @@ -612,6 +622,7 @@ func Edit(ctx *context.APIContext, opts api.EditRepoOption) { // "$ref": "#/responses/forbidden" // "422": // "$ref": "#/responses/validationError" + if err := updateBasicProperties(ctx, opts); err != nil { return } @@ -926,25 +937,26 @@ func Delete(ctx *context.APIContext) { // "$ref": "#/responses/empty" // "403": // "$ref": "#/responses/forbidden" + owner := ctx.Repo.Owner repo := ctx.Repo.Repository canDelete, err := repo.CanUserDelete(ctx.User) if err != nil { - ctx.Error(500, "CanUserDelete", err) + ctx.Error(http.StatusInternalServerError, "CanUserDelete", err) return } else if !canDelete { - ctx.Error(403, "", "Given user is not owner of organization.") + ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.") return } if err := repo_service.DeleteRepository(ctx.User, repo); err != nil { - ctx.Error(500, "DeleteRepository", err) + ctx.Error(http.StatusInternalServerError, "DeleteRepository", err) return } log.Trace("Repository deleted: %s/%s", owner.Name, repo.Name) - ctx.Status(204) + ctx.Status(http.StatusNoContent) } // MirrorSync adds a mirrored repository to the sync queue @@ -968,13 +980,16 @@ func MirrorSync(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/empty" + // "403": + // "$ref": "#/responses/forbidden" + repo := ctx.Repo.Repository if !ctx.Repo.CanWrite(models.UnitTypeCode) { - ctx.Error(403, "MirrorSync", "Must have write access") + ctx.Error(http.StatusForbidden, "MirrorSync", "Must have write access") } mirror_service.StartToMirror(repo.ID) - ctx.Status(200) + ctx.Status(http.StatusOK) } diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index 8fe5b17c5f..65a99d442a 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -31,14 +33,15 @@ func ListStargazers(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/UserList" + stargazers, err := ctx.Repo.Repository.GetStargazers(-1) if err != nil { - ctx.Error(500, "GetStargazers", err) + ctx.Error(http.StatusInternalServerError, "GetStargazers", err) return } users := make([]*api.User, len(stargazers)) for i, stargazer := range stargazers { users[i] = convert.ToUser(stargazer, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin) } - ctx.JSON(200, users) + ctx.JSON(http.StatusOK, users) } diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 7d4a2de389..c137b64f5c 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -6,6 +6,7 @@ package repo import ( "fmt" + "net/http" "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" @@ -43,9 +44,12 @@ func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) { // responses: // "201": // "$ref": "#/responses/Status" + // "400": + // "$ref": "#/responses/error" + sha := ctx.Params("sha") if len(sha) == 0 { - ctx.Error(400, "sha not given", nil) + ctx.Error(http.StatusBadRequest, "sha not given", nil) return } status := &models.CommitStatus{ @@ -55,11 +59,11 @@ func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) { Context: form.Context, } if err := repofiles.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil { - ctx.Error(500, "CreateCommitStatus", err) + ctx.Error(http.StatusInternalServerError, "CreateCommitStatus", err) return } - ctx.JSON(201, status.APIFormat()) + ctx.JSON(http.StatusCreated, status.APIFormat()) } // GetCommitStatuses returns all statuses for any given commit hash @@ -105,6 +109,9 @@ func GetCommitStatuses(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/StatusList" + // "400": + // "$ref": "#/responses/error" + getCommitStatuses(ctx, ctx.Params("sha")) } @@ -151,17 +158,19 @@ func GetCommitStatusesByRef(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/StatusList" + // "400": + // "$ref": "#/responses/error" filter := ctx.Params("ref") if len(filter) == 0 { - ctx.Error(400, "ref not given", nil) + ctx.Error(http.StatusBadRequest, "ref not given", nil) return } for _, reftype := range []string{"heads", "tags"} { //Search branches and tags refSHA, lastMethodName, err := searchRefCommitByType(ctx, reftype, filter) if err != nil { - ctx.Error(500, lastMethodName, err) + ctx.Error(http.StatusInternalServerError, lastMethodName, err) return } if refSHA != "" { @@ -187,7 +196,7 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str func getCommitStatuses(ctx *context.APIContext, sha string) { if len(sha) == 0 { - ctx.Error(400, "ref/sha not given", nil) + ctx.Error(http.StatusBadRequest, "ref/sha not given", nil) return } repo := ctx.Repo.Repository @@ -198,7 +207,7 @@ func getCommitStatuses(ctx *context.APIContext, sha string) { State: ctx.QueryTrim("state"), }) if err != nil { - ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, ctx.QueryInt("page"), err)) + ctx.Error(http.StatusInternalServerError, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, ctx.QueryInt("page"), err)) return } @@ -207,7 +216,7 @@ func getCommitStatuses(ctx *context.APIContext, sha string) { apiStatuses = append(apiStatuses, status.APIFormat()) } - ctx.JSON(200, apiStatuses) + ctx.JSON(http.StatusOK, apiStatuses) } type combinedCommitStatus struct { @@ -251,9 +260,12 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/Status" + // "400": + // "$ref": "#/responses/error" + sha := ctx.Params("ref") if len(sha) == 0 { - ctx.Error(400, "ref/sha not given", nil) + ctx.Error(http.StatusBadRequest, "ref/sha not given", nil) return } repo := ctx.Repo.Repository @@ -262,12 +274,12 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { statuses, err := models.GetLatestCommitStatus(repo, sha, page) if err != nil { - ctx.Error(500, "GetLatestCommitStatus", fmt.Errorf("GetLatestCommitStatus[%s, %s, %d]: %v", repo.FullName(), sha, page, err)) + ctx.Error(http.StatusInternalServerError, "GetLatestCommitStatus", fmt.Errorf("GetLatestCommitStatus[%s, %s, %d]: %v", repo.FullName(), sha, page, err)) return } if len(statuses) == 0 { - ctx.Status(200) + ctx.Status(http.StatusOK) return } @@ -286,5 +298,5 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) { } } - ctx.JSON(200, retStatus) + ctx.JSON(http.StatusOK, retStatus) } diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go index 0e576b4ff0..352f842884 100644 --- a/routers/api/v1/repo/subscriber.go +++ b/routers/api/v1/repo/subscriber.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" @@ -31,14 +33,15 @@ func ListSubscribers(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/UserList" + subscribers, err := ctx.Repo.Repository.GetWatchers(0) if err != nil { - ctx.Error(500, "GetWatchers", err) + ctx.Error(http.StatusInternalServerError, "GetWatchers", err) return } users := make([]*api.User, len(subscribers)) for i, subscriber := range subscribers { users[i] = convert.ToUser(subscriber, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin) } - ctx.JSON(200, users) + ctx.JSON(http.StatusOK, users) } diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 0a764113ab..eb99895c64 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -33,9 +33,10 @@ func ListTags(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/TagList" + tags, err := ctx.Repo.GitRepo.GetTagInfos() if err != nil { - ctx.Error(500, "GetTags", err) + ctx.Error(http.StatusInternalServerError, "GetTags", err) return } @@ -44,7 +45,7 @@ func ListTags(ctx *context.APIContext) { apiTags[i] = convert.ToTag(ctx.Repo.Repository, tags[i]) } - ctx.JSON(200, &apiTags) + ctx.JSON(http.StatusOK, &apiTags) } // GetTag get the tag of a repository. @@ -73,6 +74,8 @@ func GetTag(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/AnnotatedTag" + // "400": + // "$ref": "#/responses/error" sha := ctx.Params("sha") if len(sha) == 0 { diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index 1656fd1b16..0c56f2a769 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -42,9 +42,7 @@ func ListTopics(ctx *context.APIContext) { }) if err != nil { log.Error("ListTopics failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "ListTopics failed.", - }) + ctx.InternalServerError(err) return } @@ -82,6 +80,8 @@ func UpdateTopics(ctx *context.APIContext, form api.RepoTopicOptions) { // responses: // "204": // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/invalidTopicsError" topicNames := form.Topics validTopics, invalidTopics := models.SanitizeAndValidateTopics(topicNames) @@ -105,9 +105,7 @@ func UpdateTopics(ctx *context.APIContext, form api.RepoTopicOptions) { err := models.SaveTopics(ctx.Repo.Repository.ID, validTopics...) if err != nil { log.Error("SaveTopics failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "Save topics failed.", - }) + ctx.InternalServerError(err) return } @@ -140,11 +138,16 @@ func AddTopic(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/invalidTopicsError" topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !models.ValidateTopic(topicName) { - ctx.Error(http.StatusUnprocessableEntity, "", "Topic name is invalid") + ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + "invalidTopics": topicName, + "message": "Topic name is invalid", + }) return } @@ -154,9 +157,7 @@ func AddTopic(ctx *context.APIContext) { }) if err != nil { log.Error("AddTopic failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "ListTopics failed.", - }) + ctx.InternalServerError(err) return } if len(topics) >= 25 { @@ -169,9 +170,7 @@ func AddTopic(ctx *context.APIContext) { _, err = models.AddTopic(ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("AddTopic failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "AddTopic failed.", - }) + ctx.InternalServerError(err) return } @@ -204,19 +203,23 @@ func DeleteTopic(ctx *context.APIContext) { // responses: // "204": // "$ref": "#/responses/empty" + // "422": + // "$ref": "#/responses/invalidTopicsError" + topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic"))) if !models.ValidateTopic(topicName) { - ctx.Error(http.StatusUnprocessableEntity, "", "Topic name is invalid") + ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{ + "invalidTopics": topicName, + "message": "Topic name is invalid", + }) return } topic, err := models.DeleteTopic(ctx.Repo.Repository.ID, topicName) if err != nil { log.Error("DeleteTopic failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "DeleteTopic failed.", - }) + ctx.InternalServerError(err) return } @@ -243,10 +246,11 @@ func TopicSearch(ctx *context.Context) { // responses: // "200": // "$ref": "#/responses/TopicListResponse" + // "403": + // "$ref": "#/responses/forbidden" + if ctx.User == nil { - ctx.JSON(http.StatusForbidden, map[string]interface{}{ - "message": "Only owners could change the topics.", - }) + ctx.Error(http.StatusForbidden, "UserIsNil", "Only owners could change the topics.") return } @@ -258,9 +262,7 @@ func TopicSearch(ctx *context.Context) { }) if err != nil { log.Error("SearchTopics failed: %v", err) - ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ - "message": "Search topics failed.", - }) + ctx.InternalServerError(err) return } diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index 066ca662f8..987f2fb808 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -5,6 +5,8 @@ package repo import ( + "net/http" + "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/repofiles" ) @@ -50,15 +52,17 @@ func GetTree(ctx *context.APIContext) { // responses: // "200": // "$ref": "#/responses/GitTreeResponse" + // "400": + // "$ref": "#/responses/error" sha := ctx.Params(":sha") if len(sha) == 0 { - ctx.Error(400, "", "sha not provided") + ctx.Error(http.StatusBadRequest, "", "sha not provided") return } if tree, err := repofiles.GetTreeBySHA(ctx.Repo.Repository, sha, ctx.QueryInt("page"), ctx.QueryInt("per_page"), ctx.QueryBool("recursive")); err != nil { - ctx.Error(400, "", err.Error()) + ctx.Error(http.StatusBadRequest, "", err.Error()) } else { - ctx.JSON(200, tree) + ctx.JSON(http.StatusOK, tree) } } |