forked from forgejo/forgejo
Merge branch 'rebase-forgejo-dependency' into wip-forgejo
This commit is contained in:
commit
094c84ed6d
292 changed files with 8842 additions and 1269 deletions
|
@ -6,7 +6,7 @@
|
|||
//
|
||||
// This documentation describes the Gitea API.
|
||||
//
|
||||
// Schemes: http, https
|
||||
// Schemes: https, http
|
||||
// BasePath: /api/v1
|
||||
// Version: {{AppVer | JSEscape | Safe}}
|
||||
// License: MIT http://opensource.org/licenses/MIT
|
||||
|
@ -73,6 +73,7 @@ import (
|
|||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/organization"
|
||||
"code.gitea.io/gitea/models/perm"
|
||||
access_model "code.gitea.io/gitea/models/perm/access"
|
||||
|
@ -230,6 +231,39 @@ func repoAssignment() func(ctx *context.APIContext) {
|
|||
}
|
||||
}
|
||||
|
||||
// must be used within a group with a call to repoAssignment() to set ctx.Repo
|
||||
func commentAssignment(idParam string) func(ctx *context.APIContext) {
|
||||
return func(ctx *context.APIContext) {
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(idParam))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.InternalServerError(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err = comment.LoadIssue(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
if comment.Issue == nil || comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
comment.Issue.Repo = ctx.Repo.Repository
|
||||
|
||||
ctx.Comment = comment
|
||||
}
|
||||
}
|
||||
|
||||
func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext) {
|
||||
return func(ctx *context.APIContext) {
|
||||
if ctx.Package.AccessMode < accessMode && !ctx.IsUserSiteAdmin() {
|
||||
|
@ -1104,6 +1138,18 @@ func Routes() *web.Route {
|
|||
m.Get("/permission", repo.GetRepoPermissions)
|
||||
})
|
||||
}, reqToken())
|
||||
if setting.Repository.EnableFlags {
|
||||
m.Group("/flags", func() {
|
||||
m.Combo("").Get(repo.ListFlags).
|
||||
Put(bind(api.ReplaceFlagsOption{}), repo.ReplaceAllFlags).
|
||||
Delete(repo.DeleteAllFlags)
|
||||
m.Group("/{flag}", func() {
|
||||
m.Combo("").Get(repo.HasFlag).
|
||||
Put(repo.AddFlag).
|
||||
Delete(repo.DeleteFlag)
|
||||
})
|
||||
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryAdmin), reqToken(), reqSiteAdmin())
|
||||
}
|
||||
m.Get("/assignees", reqToken(), reqAnyRepoReader(), repo.GetAssignees)
|
||||
m.Get("/reviewers", reqToken(), reqAnyRepoReader(), repo.GetReviewers)
|
||||
m.Group("/teams", func() {
|
||||
|
@ -1223,8 +1269,16 @@ func Routes() *web.Route {
|
|||
Get(repo.GetPullReview).
|
||||
Delete(reqToken(), repo.DeletePullReview).
|
||||
Post(reqToken(), bind(api.SubmitPullReviewOptions{}), repo.SubmitPullReview)
|
||||
m.Combo("/comments").
|
||||
Get(repo.GetPullReviewComments)
|
||||
m.Group("/comments", func() {
|
||||
m.Combo("").
|
||||
Get(repo.GetPullReviewComments).
|
||||
Post(reqToken(), bind(api.CreatePullReviewCommentOptions{}), repo.CreatePullReviewComment)
|
||||
m.Group("/{comment}", func() {
|
||||
m.Combo("").
|
||||
Get(repo.GetPullReviewComment).
|
||||
Delete(reqToken(), repo.DeletePullReviewComment)
|
||||
}, commentAssignment("comment"))
|
||||
})
|
||||
m.Post("/dismissals", reqToken(), bind(api.DismissPullReviewOptions{}), repo.DismissPullReview)
|
||||
m.Post("/undismissals", reqToken(), repo.UnDismissPullReview)
|
||||
})
|
||||
|
@ -1328,7 +1382,7 @@ func Routes() *web.Route {
|
|||
Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment).
|
||||
Delete(reqToken(), mustNotBeArchived, repo.DeleteIssueCommentAttachment)
|
||||
}, mustEnableAttachments)
|
||||
})
|
||||
}, commentAssignment(":id"))
|
||||
})
|
||||
m.Group("/{index}", func() {
|
||||
m.Combo("").Get(repo.GetIssue).
|
||||
|
|
|
@ -262,7 +262,9 @@ func GetArchive(ctx *context.APIContext) {
|
|||
// ---
|
||||
// summary: Get an archive of a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// - application/octet-stream
|
||||
// - application/zip
|
||||
// - application/gzip
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
|
@ -342,7 +344,17 @@ func download(ctx *context.APIContext, archiveName string, archiver *repo_model.
|
|||
}
|
||||
defer fr.Close()
|
||||
|
||||
contentType := ""
|
||||
switch archiver.Type {
|
||||
case git.ZIP:
|
||||
contentType = "application/zip"
|
||||
case git.TARGZ:
|
||||
// Per RFC6713.
|
||||
contentType = "application/gzip"
|
||||
}
|
||||
|
||||
ctx.ServeContent(fr, &context.ServeHeaderOptions{
|
||||
ContentType: contentType,
|
||||
Filename: downloadName,
|
||||
LastModified: archiver.CreatedUnix.AsLocalTime(),
|
||||
})
|
||||
|
|
245
routers/api/v1/repo/flags.go
Normal file
245
routers/api/v1/repo/flags.go
Normal file
|
@ -0,0 +1,245 @@
|
|||
// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
)
|
||||
|
||||
func ListFlags(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/flags repository repoListFlags
|
||||
// ---
|
||||
// summary: List a repository's flags
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/StringSlice"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
repoFlags, err := ctx.Repo.Repository.ListFlags(ctx)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
flags := make([]string, len(repoFlags))
|
||||
for i := range repoFlags {
|
||||
flags[i] = repoFlags[i].Name
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(int64(len(repoFlags)))
|
||||
ctx.JSON(http.StatusOK, flags)
|
||||
}
|
||||
|
||||
func ReplaceAllFlags(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /repos/{owner}/{repo}/flags repository repoReplaceAllFlags
|
||||
// ---
|
||||
// summary: Replace all flags of a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ReplaceFlagsOption"
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
flagsForm := web.GetForm(ctx).(*api.ReplaceFlagsOption)
|
||||
|
||||
if err := ctx.Repo.Repository.ReplaceAllFlags(ctx, flagsForm.Flags); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func DeleteAllFlags(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/flags repository repoDeleteAllFlags
|
||||
// ---
|
||||
// summary: Remove all flags from a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
if err := ctx.Repo.Repository.ReplaceAllFlags(ctx, nil); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func HasFlag(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/flags/{flag} repository repoCheckFlag
|
||||
// ---
|
||||
// summary: Check if a repository has a given flag
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: flag
|
||||
// in: path
|
||||
// description: name of the flag
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
hasFlag := ctx.Repo.Repository.HasFlag(ctx, ctx.Params(":flag"))
|
||||
if hasFlag {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
} else {
|
||||
ctx.NotFound()
|
||||
}
|
||||
}
|
||||
|
||||
func AddFlag(ctx *context.APIContext) {
|
||||
// swagger:operation PUT /repos/{owner}/{repo}/flags/{flag} repository repoAddFlag
|
||||
// ---
|
||||
// summary: Add a flag to a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: flag
|
||||
// in: path
|
||||
// description: name of the flag
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
flag := ctx.Params(":flag")
|
||||
|
||||
if ctx.Repo.Repository.HasFlag(ctx, flag) {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctx.Repo.Repository.AddFlag(ctx, flag); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func DeleteFlag(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/flags/{flag} repository repoDeleteFlag
|
||||
// ---
|
||||
// summary: Remove a flag from a repository
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: flag
|
||||
// in: path
|
||||
// description: name of the flag
|
||||
// type: string
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
flag := ctx.Params(":flag")
|
||||
|
||||
if _, err := ctx.Repo.Repository.DeleteFlag(ctx, flag); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
|
@ -454,29 +454,7 @@ func GetIssueComment(ctx *context.APIContext) {
|
|||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err = comment.LoadIssue(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
if comment.Type != issues_model.CommentTypeComment {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
|
@ -587,25 +565,7 @@ func EditIssueCommentDeprecated(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption) {
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := comment.LoadIssue(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
||||
ctx.Status(http.StatusForbidden)
|
||||
|
@ -617,7 +577,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
|
|||
return
|
||||
}
|
||||
|
||||
err = comment.LoadIssue(ctx)
|
||||
err := comment.LoadIssue(ctx)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
||||
return
|
||||
|
@ -668,7 +628,7 @@ func DeleteIssueComment(ctx *context.APIContext) {
|
|||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
deleteIssueComment(ctx)
|
||||
deleteIssueComment(ctx, issues_model.CommentTypeComment)
|
||||
}
|
||||
|
||||
// DeleteIssueCommentDeprecated delete a comment from an issue
|
||||
|
@ -707,39 +667,21 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) {
|
|||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
deleteIssueComment(ctx)
|
||||
deleteIssueComment(ctx, issues_model.CommentTypeComment)
|
||||
}
|
||||
|
||||
func deleteIssueComment(ctx *context.APIContext) {
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := comment.LoadIssue(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
func deleteIssueComment(ctx *context.APIContext, commentType issues_model.CommentType) {
|
||||
comment := ctx.Comment
|
||||
|
||||
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
|
||||
ctx.Status(http.StatusForbidden)
|
||||
return
|
||||
} else if comment.Type != issues_model.CommentTypeComment {
|
||||
} else if comment.Type != commentType {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
if err = issue_service.DeleteComment(ctx, ctx.Doer, comment); err != nil {
|
||||
if err := issue_service.DeleteComment(ctx, ctx.Doer, comment); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteCommentByID", err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -55,11 +55,8 @@ func GetIssueCommentAttachment(ctx *context.APIContext) {
|
|||
// "404":
|
||||
// "$ref": "#/responses/error"
|
||||
|
||||
comment := getIssueCommentSafe(ctx)
|
||||
if comment == nil {
|
||||
return
|
||||
}
|
||||
attachment := getIssueCommentAttachmentSafeRead(ctx, comment)
|
||||
comment := ctx.Comment
|
||||
attachment := getIssueCommentAttachmentSafeRead(ctx)
|
||||
if attachment == nil {
|
||||
return
|
||||
}
|
||||
|
@ -101,10 +98,7 @@ func ListIssueCommentAttachments(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/AttachmentList"
|
||||
// "404":
|
||||
// "$ref": "#/responses/error"
|
||||
comment := getIssueCommentSafe(ctx)
|
||||
if comment == nil {
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
if err := comment.LoadAttachments(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "LoadAttachments", err)
|
||||
|
@ -166,14 +160,12 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
|
|||
// "$ref": "#/responses/repoArchivedError"
|
||||
|
||||
// Check if comment exists and load comment
|
||||
comment := getIssueCommentSafe(ctx)
|
||||
if comment == nil {
|
||||
|
||||
if !canUserWriteIssueCommentAttachment(ctx) {
|
||||
return
|
||||
}
|
||||
|
||||
if !canUserWriteIssueCommentAttachment(ctx, comment) {
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
updatedAt := ctx.Req.FormValue("updated_at")
|
||||
if len(updatedAt) != 0 {
|
||||
|
@ -341,42 +333,17 @@ func DeleteIssueCommentAttachment(ctx *context.APIContext) {
|
|||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment {
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64("id"))
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("GetCommentByID", issues_model.IsErrCommentNotExist, err)
|
||||
return nil
|
||||
}
|
||||
if err := comment.LoadIssue(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err)
|
||||
return nil
|
||||
}
|
||||
if comment.Issue == nil || comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.Error(http.StatusNotFound, "", "no matching issue comment found")
|
||||
return nil
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||
return nil
|
||||
}
|
||||
|
||||
comment.Issue.Repo = ctx.Repo.Repository
|
||||
|
||||
return comment
|
||||
}
|
||||
|
||||
func getIssueCommentAttachmentSafeWrite(ctx *context.APIContext) *repo_model.Attachment {
|
||||
comment := getIssueCommentSafe(ctx)
|
||||
if comment == nil {
|
||||
if !canUserWriteIssueCommentAttachment(ctx) {
|
||||
return nil
|
||||
}
|
||||
if !canUserWriteIssueCommentAttachment(ctx, comment) {
|
||||
return nil
|
||||
}
|
||||
return getIssueCommentAttachmentSafeRead(ctx, comment)
|
||||
return getIssueCommentAttachmentSafeRead(ctx)
|
||||
}
|
||||
|
||||
func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues_model.Comment) bool {
|
||||
func canUserWriteIssueCommentAttachment(ctx *context.APIContext) bool {
|
||||
// ctx.Comment is assumed to be set in a safe way via a middleware
|
||||
comment := ctx.Comment
|
||||
|
||||
canEditComment := ctx.IsSigned && (ctx.Doer.ID == comment.PosterID || ctx.IsUserRepoAdmin() || ctx.IsUserSiteAdmin()) && ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)
|
||||
if !canEditComment {
|
||||
ctx.Error(http.StatusForbidden, "", "user should have permission to edit comment")
|
||||
|
@ -386,7 +353,10 @@ func canUserWriteIssueCommentAttachment(ctx *context.APIContext, comment *issues
|
|||
return true
|
||||
}
|
||||
|
||||
func getIssueCommentAttachmentSafeRead(ctx *context.APIContext, comment *issues_model.Comment) *repo_model.Attachment {
|
||||
func getIssueCommentAttachmentSafeRead(ctx *context.APIContext) *repo_model.Attachment {
|
||||
// ctx.Comment is assumed to be set in a safe way via a middleware
|
||||
comment := ctx.Comment
|
||||
|
||||
attachment, err := repo_model.GetAttachmentByID(ctx, ctx.ParamsInt64("attachment_id"))
|
||||
if err != nil {
|
||||
ctx.NotFoundOrServerError("GetAttachmentByID", repo_model.IsErrAttachmentNotExist, err)
|
||||
|
|
|
@ -51,30 +51,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
|
|||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := comment.LoadIssue(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue", err)
|
||||
return
|
||||
}
|
||||
|
||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||
ctx.Error(http.StatusForbidden, "GetIssueCommentReactions", errors.New("no permission to get reactions"))
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
reactions, _, err := issues_model.FindCommentReactions(ctx, comment.IssueID, comment.ID)
|
||||
if err != nil {
|
||||
|
@ -188,30 +165,7 @@ func DeleteIssueCommentReaction(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOption, isCreateType bool) {
|
||||
comment, err := issues_model.GetCommentByID(ctx, ctx.ParamsInt64(":id"))
|
||||
if err != nil {
|
||||
if issues_model.IsErrCommentNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "GetCommentByID", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err = comment.LoadIssue(ctx); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "comment.LoadIssue() failed", err)
|
||||
return
|
||||
}
|
||||
|
||||
if comment.Issue.RepoID != ctx.Repo.Repository.ID {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
|
||||
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
|
||||
ctx.NotFound()
|
||||
return
|
||||
}
|
||||
comment := ctx.Comment
|
||||
|
||||
if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) {
|
||||
ctx.Error(http.StatusForbidden, "ChangeIssueCommentReaction", errors.New("no permission to change reaction"))
|
||||
|
@ -243,7 +197,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
|
|||
})
|
||||
} else {
|
||||
// DeleteIssueCommentReaction part
|
||||
err = issues_model.DeleteCommentReaction(ctx, ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction)
|
||||
err := issues_model.DeleteCommentReaction(ctx, ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "DeleteCommentReaction", err)
|
||||
return
|
||||
|
|
|
@ -208,6 +208,152 @@ func GetPullReviewComments(ctx *context.APIContext) {
|
|||
ctx.JSON(http.StatusOK, apiComments)
|
||||
}
|
||||
|
||||
// GetPullReviewComment get a pull review comment
|
||||
func GetPullReviewComment(ctx *context.APIContext) {
|
||||
// swagger:operation GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment} repository repoGetPullReviewComment
|
||||
// ---
|
||||
// summary: Get a pull review comment
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: index
|
||||
// in: path
|
||||
// description: index of the pull request
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: id
|
||||
// in: path
|
||||
// description: id of the review
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: comment
|
||||
// in: path
|
||||
// description: id of the comment
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/PullReviewComment"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
review, _, statusSet := prepareSingleReview(ctx)
|
||||
if statusSet {
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctx.Comment.LoadPoster(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
apiComment, err := convert.ToPullReviewComment(ctx, review, ctx.Comment, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, apiComment)
|
||||
}
|
||||
|
||||
// CreatePullReviewComments add a new comment to a pull request review
|
||||
func CreatePullReviewComment(ctx *context.APIContext) {
|
||||
// swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments repository repoCreatePullReviewComment
|
||||
// ---
|
||||
// summary: Add a new comment to a pull request review
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: index
|
||||
// in: path
|
||||
// description: index of the pull request
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: id
|
||||
// in: path
|
||||
// description: id of the review
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: body
|
||||
// in: body
|
||||
// required: true
|
||||
// schema:
|
||||
// "$ref": "#/definitions/CreatePullReviewCommentOptions"
|
||||
// responses:
|
||||
// "200":
|
||||
// "$ref": "#/responses/PullReviewComment"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
// "422":
|
||||
// "$ref": "#/responses/validationError"
|
||||
|
||||
opts := web.GetForm(ctx).(*api.CreatePullReviewCommentOptions)
|
||||
|
||||
review, pr, statusSet := prepareSingleReview(ctx)
|
||||
if statusSet {
|
||||
return
|
||||
}
|
||||
|
||||
if err := pr.Issue.LoadRepo(ctx); err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
line := opts.NewLineNum
|
||||
if opts.OldLineNum > 0 {
|
||||
line = opts.OldLineNum * -1
|
||||
}
|
||||
|
||||
comment, err := pull_service.CreateCodeCommentKnownReviewID(ctx,
|
||||
ctx.Doer,
|
||||
pr.Issue.Repo,
|
||||
pr.Issue,
|
||||
opts.Body,
|
||||
opts.Path,
|
||||
line,
|
||||
review.ID,
|
||||
)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
apiComment, err := convert.ToPullReviewComment(ctx, review, comment, ctx.Doer)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(http.StatusOK, apiComment)
|
||||
}
|
||||
|
||||
// DeletePullReview delete a specific review from a pull request
|
||||
func DeletePullReview(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id} repository repoDeletePullReview
|
||||
|
@ -868,6 +1014,53 @@ func UnDismissPullReview(ctx *context.APIContext) {
|
|||
dismissReview(ctx, "", false, false)
|
||||
}
|
||||
|
||||
// DeletePullReviewComment delete a pull review comment
|
||||
func DeletePullReviewComment(ctx *context.APIContext) {
|
||||
// swagger:operation DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment} repository repoDeletePullReviewComment
|
||||
// ---
|
||||
// summary: Delete a pull review comment
|
||||
// produces:
|
||||
// - application/json
|
||||
// parameters:
|
||||
// - name: owner
|
||||
// in: path
|
||||
// description: owner of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: repo
|
||||
// in: path
|
||||
// description: name of the repo
|
||||
// type: string
|
||||
// required: true
|
||||
// - name: index
|
||||
// in: path
|
||||
// description: index of the pull request
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: id
|
||||
// in: path
|
||||
// description: id of the review
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// - name: comment
|
||||
// in: path
|
||||
// description: id of the comment
|
||||
// type: integer
|
||||
// format: int64
|
||||
// required: true
|
||||
// responses:
|
||||
// "204":
|
||||
// "$ref": "#/responses/empty"
|
||||
// "403":
|
||||
// "$ref": "#/responses/forbidden"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
||||
deleteIssueComment(ctx, issues_model.CommentTypeCode)
|
||||
}
|
||||
|
||||
func dismissReview(ctx *context.APIContext, msg string, isDismiss, dismissPriors bool) {
|
||||
if !ctx.Repo.IsAdmin() {
|
||||
ctx.Error(http.StatusForbidden, "", "Must be repo admin")
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
"code.gitea.io/gitea/services/convert"
|
||||
"code.gitea.io/gitea/services/issue"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
wiki_service "code.gitea.io/gitea/services/wiki"
|
||||
)
|
||||
|
||||
// Search repositories via options
|
||||
|
@ -740,6 +741,18 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
|
|||
repo.DefaultBranch = *opts.DefaultBranch
|
||||
}
|
||||
|
||||
// Wiki branch is updated if changed
|
||||
if opts.WikiBranch != nil && repo.WikiBranch != *opts.WikiBranch {
|
||||
if err := wiki_service.NormalizeWikiBranch(ctx, repo, *opts.WikiBranch); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "NormalizeWikiBranch", err)
|
||||
return err
|
||||
}
|
||||
// While NormalizeWikiBranch updates the db, we need to update *this*
|
||||
// instance of `repo`, so that the `UpdateRepository` below will not
|
||||
// reset the branch back.
|
||||
repo.WikiBranch = *opts.WikiBranch
|
||||
}
|
||||
|
||||
if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateRepository", err)
|
||||
return err
|
||||
|
@ -984,7 +997,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
|
|||
}
|
||||
|
||||
if len(units)+len(deleteUnitTypes) > 0 {
|
||||
if err := repo_service.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
|
||||
if err := repo_model.UpdateRepositoryUnits(ctx, repo, units, deleteUnitTypes); err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "UpdateRepositoryUnits", err)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ func CreateTag(ctx *context.APIContext) {
|
|||
// schema:
|
||||
// "$ref": "#/definitions/CreateTagOption"
|
||||
// responses:
|
||||
// "200":
|
||||
// "201":
|
||||
// "$ref": "#/responses/Tag"
|
||||
// "404":
|
||||
// "$ref": "#/responses/notFound"
|
||||
|
|
|
@ -203,7 +203,7 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi
|
|||
}
|
||||
|
||||
return &api.WikiPage{
|
||||
WikiPageMetaData: wiki_service.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
|
||||
WikiPageMetaData: convert.ToWikiPageMetaData(wikiName, lastCommit, ctx.Repo.Repository),
|
||||
ContentBase64: content,
|
||||
CommitCount: commitsCount,
|
||||
Sidebar: sidebarContent,
|
||||
|
@ -333,7 +333,7 @@ func ListWikiPages(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusInternalServerError, "WikiFilenameToName", err)
|
||||
return
|
||||
}
|
||||
pages = append(pages, wiki_service.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository))
|
||||
pages = append(pages, convert.ToWikiPageMetaData(wikiName, c, ctx.Repo.Repository))
|
||||
}
|
||||
|
||||
ctx.SetTotalCountHeader(int64(len(entries)))
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// RegistrationToken is response related to registeration token
|
||||
// RegistrationToken is a string used to register a runner with a server
|
||||
// swagger:response RegistrationToken
|
||||
type RegistrationToken struct {
|
||||
Token string `json:"token"`
|
||||
|
|
|
@ -17,6 +17,9 @@ type swaggerParameterBodies struct {
|
|||
// in:body
|
||||
AddCollaboratorOption api.AddCollaboratorOption
|
||||
|
||||
// in:body
|
||||
ReplaceFlagsOption api.ReplaceFlagsOption
|
||||
|
||||
// in:body
|
||||
CreateEmailOption api.CreateEmailOption
|
||||
// in:body
|
||||
|
@ -158,6 +161,9 @@ type swaggerParameterBodies struct {
|
|||
// in:body
|
||||
CreatePullReviewComment api.CreatePullReviewComment
|
||||
|
||||
// in:body
|
||||
CreatePullReviewCommentOptions api.CreatePullReviewCommentOptions
|
||||
|
||||
// in:body
|
||||
SubmitPullReviewOptions api.SubmitPullReviewOptions
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ func CreateOauth2Application(ctx *context.APIContext) {
|
|||
|
||||
// ListOauth2Applications list all the Oauth2 application
|
||||
func ListOauth2Applications(ctx *context.APIContext) {
|
||||
// swagger:operation GET /user/applications/oauth2 user userGetOauth2Application
|
||||
// swagger:operation GET /user/applications/oauth2 user userGetOAuth2Applications
|
||||
// ---
|
||||
// summary: List the authenticated user's oauth2 applications
|
||||
// produces:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue