Merge branch 'main' into allow-force-push-protected-branches

This commit is contained in:
Henry Goodman
2023-12-14 23:05:31 +11:00
committed by GitHub
318 changed files with 2861 additions and 2324 deletions
+8 -2
View File
@@ -520,7 +520,10 @@ func CommonRoutes() *web.Route {
r.Get("", rpm.DownloadPackageFile)
r.Delete("", reqPackageAccess(perm.AccessModeWrite), rpm.DeletePackageFile)
})
r.Get("/repodata/{filename}", rpm.GetRepositoryFile)
r.Group("/repodata/{filename}", func() {
r.Head("", rpm.CheckRepositoryFileExistence)
r.Get("", rpm.GetRepositoryFile)
})
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/rubygems", func() {
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
@@ -600,7 +603,10 @@ func ContainerRoutes() *web.Route {
})
r.Get("", container.ReqContainerAccess, container.DetermineSupport)
r.Get("/token", container.Authenticate)
r.Group("/token", func() {
r.Get("", container.Authenticate)
r.Post("", container.AuthenticateNotImplemented)
})
r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList)
r.Group("/{username}", func() {
r.Group("/{image}", func() {
@@ -156,6 +156,17 @@ func Authenticate(ctx *context.Context) {
})
}
// https://distribution.github.io/distribution/spec/auth/oauth/
func AuthenticateNotImplemented(ctx *context.Context) {
// This optional endpoint can be used to authenticate a client.
// It must implement the specification described in:
// https://datatracker.ietf.org/doc/html/rfc6749
// https://distribution.github.io/distribution/spec/auth/oauth/
// Purpose of this stub is to respond with 404 Not Found instead of 405 Method Not Allowed.
ctx.Status(http.StatusNotFound)
}
// https://docs.docker.com/registry/spec/api/#listing-repositories
func GetRepositoryList(ctx *context.Context) {
n := ctx.FormInt("n")
+24
View File
@@ -57,6 +57,30 @@ func GetRepositoryKey(ctx *context.Context) {
})
}
func CheckRepositoryFileExistence(ctx *context.Context) {
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.Status(http.StatusNotFound)
} else {
apiError(ctx, http.StatusInternalServerError, err)
}
return
}
ctx.SetServeHeaders(&context.ServeHeaderOptions{
Filename: pf.Name,
LastModified: pf.CreatedUnix.AsLocalTime(),
})
ctx.Status(http.StatusOK)
}
// Gets a pre-generated repository metadata file
func GetRepositoryFile(ctx *context.Context) {
pv, err := rpm_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
+32 -3
View File
@@ -35,10 +35,12 @@
// type: apiKey
// name: token
// in: query
// description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.
// AccessToken:
// type: apiKey
// name: access_token
// in: query
// description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.
// AuthorizationHeaderToken:
// type: apiKey
// name: Authorization
@@ -788,6 +790,31 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC
}
}
func individualPermsChecker(ctx *context.APIContext) {
// org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked.
if ctx.ContextUser.IsIndividual() {
switch {
case ctx.ContextUser.Visibility == api.VisibleTypePrivate:
if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) {
ctx.NotFound("Visit Project", nil)
return
}
case ctx.ContextUser.Visibility == api.VisibleTypeLimited:
if ctx.Doer == nil {
ctx.NotFound("Visit Project", nil)
return
}
}
}
}
// check for and warn against deprecated authentication options
func checkDeprecatedAuthMethods(ctx *context.APIContext) {
if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" {
ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.")
}
}
// Routes registers all v1 APIs routes to web application.
func Routes() *web.Route {
m := web.NewRoute()
@@ -806,6 +833,8 @@ func Routes() *web.Route {
}
m.Use(context.APIContexter())
m.Use(checkDeprecatedAuthMethods)
// Get user from session if logged in.
m.Use(apiAuth(buildAuthGroup()))
@@ -888,7 +917,7 @@ func Routes() *web.Route {
}, reqSelfOrAdmin(), reqBasicOrRevProxyAuth())
m.Get("/activities/feeds", user.ListUserActivityFeeds)
}, context_service.UserAssignmentAPI())
}, context_service.UserAssignmentAPI(), individualPermsChecker)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser))
// Users (requires user scope)
@@ -1259,8 +1288,8 @@ func Routes() *web.Route {
m.Group("/{username}/{reponame}", func() {
m.Group("/issues", func() {
m.Combo("").Get(repo.ListIssues).
Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), repo.CreateIssue)
m.Get("/pinned", repo.ListPinnedIssues)
Post(reqToken(), mustNotBeArchived, bind(api.CreateIssueOption{}), reqRepoReader(unit.TypeIssues), repo.CreateIssue)
m.Get("/pinned", reqRepoReader(unit.TypeIssues), repo.ListPinnedIssues)
m.Group("/comments", func() {
m.Get("", repo.ListRepoIssueComments)
m.Group("/{id}", func() {
+6 -6
View File
@@ -10,6 +10,7 @@ import (
"net/http"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/organization"
user_model "code.gitea.io/gitea/models/user"
@@ -137,7 +138,7 @@ func DeleteBranch(ctx *context.APIContext) {
}
// check whether branches of this repository has been synced
totalNumOfBranches, err := git_model.CountBranches(ctx, git_model.FindBranchOptions{
totalNumOfBranches, err := db.Count[git_model.Branch](ctx, git_model.FindBranchOptions{
RepoID: ctx.Repo.Repository.ID,
IsDeletedBranch: util.OptionalBoolFalse,
})
@@ -251,12 +252,11 @@ func CreateBranch(ctx *context.APIContext) {
}
}
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, oldCommit.ID.String(), opt.BranchName)
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, oldCommit.ID.String(), opt.BranchName)
if err != nil {
if git_model.IsErrBranchNotExist(err) {
ctx.Error(http.StatusNotFound, "", "The old branch does not exist")
}
if models.IsErrTagAlreadyExists(err) {
} else if models.IsErrTagAlreadyExists(err) {
ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.")
} else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
ctx.Error(http.StatusConflict, "", "The branch already exists.")
@@ -342,7 +342,7 @@ func ListBranches(ctx *context.APIContext) {
IsDeletedBranch: util.OptionalBoolFalse,
}
var err error
totalNumOfBranches, err = git_model.CountBranches(ctx, branchOpts)
totalNumOfBranches, err = db.Count[git_model.Branch](ctx, branchOpts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CountBranches", err)
return
@@ -361,7 +361,7 @@ func ListBranches(ctx *context.APIContext) {
return
}
branches, err := git_model.FindBranches(ctx, branchOpts)
branches, err := db.Find[git_model.Branch](ctx, branchOpts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
return
+22
View File
@@ -462,6 +462,24 @@ func ListIssues(ctx *context.APIContext) {
isPull = util.OptionalBoolNone
}
if isPull != util.OptionalBoolNone && !ctx.Repo.CanReadIssuesOrPulls(isPull.IsTrue()) {
ctx.NotFound()
return
}
if isPull == util.OptionalBoolNone {
canReadIssues := ctx.Repo.CanRead(unit.TypeIssues)
canReadPulls := ctx.Repo.CanRead(unit.TypePullRequests)
if !canReadIssues && !canReadPulls {
ctx.NotFound()
return
} else if !canReadIssues {
isPull = util.OptionalBoolTrue
} else if !canReadPulls {
isPull = util.OptionalBoolFalse
}
}
// FIXME: we should be more efficient here
createdByID := getUserIDForFilter(ctx, "created_by")
if ctx.Written() {
@@ -593,6 +611,10 @@ func GetIssue(ctx *context.APIContext) {
}
return
}
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
ctx.NotFound()
return
}
ctx.JSON(http.StatusOK, convert.ToAPIIssue(ctx, issue))
}
+54 -2
View File
@@ -12,9 +12,11 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
access_model "code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/convert"
@@ -71,6 +73,11 @@ func ListIssueComments(ctx *context.APIContext) {
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
return
}
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
ctx.NotFound()
return
}
issue.Repo = ctx.Repo.Repository
opts := &issues_model.FindCommentsOptions{
@@ -271,12 +278,27 @@ func ListRepoIssueComments(ctx *context.APIContext) {
return
}
var isPull util.OptionalBool
canReadIssue := ctx.Repo.CanRead(unit.TypeIssues)
canReadPull := ctx.Repo.CanRead(unit.TypePullRequests)
if canReadIssue && canReadPull {
isPull = util.OptionalBoolNone
} else if canReadIssue {
isPull = util.OptionalBoolFalse
} else if canReadPull {
isPull = util.OptionalBoolTrue
} else {
ctx.NotFound()
return
}
opts := &issues_model.FindCommentsOptions{
ListOptions: utils.GetListOptions(ctx),
RepoID: ctx.Repo.Repository.ID,
Type: issues_model.CommentTypeComment,
Since: since,
Before: before,
IsPull: isPull,
}
comments, err := issues_model.FindComments(ctx, opts)
@@ -367,6 +389,11 @@ func CreateIssueComment(ctx *context.APIContext) {
return
}
if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
ctx.NotFound()
return
}
if issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) && !ctx.Doer.IsAdmin {
ctx.Error(http.StatusForbidden, "CreateIssueComment", errors.New(ctx.Tr("repo.issues.comment_on_locked")))
return
@@ -436,6 +463,11 @@ func GetIssueComment(ctx *context.APIContext) {
return
}
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
ctx.NotFound()
return
}
if comment.Type != issues_model.CommentTypeComment {
ctx.Status(http.StatusNoContent)
return
@@ -555,7 +587,17 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
return
}
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
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
}
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull)) {
ctx.Status(http.StatusForbidden)
return
}
@@ -658,7 +700,17 @@ func deleteIssueComment(ctx *context.APIContext) {
return
}
if !ctx.IsSigned || (ctx.Doer.ID != comment.PosterID && !ctx.Repo.IsAdmin()) {
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
}
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 {
@@ -329,6 +329,10 @@ func getIssueCommentSafe(ctx *context.APIContext) *issues_model.Comment {
return nil
}
if !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull) {
return nil
}
comment.Issue.Repo = ctx.Repo.Repository
return comment
+18 -2
View File
@@ -61,6 +61,12 @@ func GetIssueCommentReactions(ctx *context.APIContext) {
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) {
@@ -190,9 +196,19 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp
return
}
err = comment.LoadIssue(ctx)
if err != nil {
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
}
if comment.Issue.IsLocked && !ctx.Repo.CanWriteIssuesOrPulls(comment.Issue.IsPull) {
+6
View File
@@ -153,6 +153,12 @@ func GetDeployKey(ctx *context.APIContext) {
return
}
// this check make it more consistent
if key.RepoID != ctx.Repo.Repository.ID {
ctx.NotFound()
return
}
if err = key.GetContent(ctx); err != nil {
ctx.Error(http.StatusInternalServerError, "GetContent", err)
return
+12 -3
View File
@@ -9,10 +9,12 @@ import (
"strconv"
"time"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/convert"
@@ -58,14 +60,21 @@ func ListMilestones(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
milestones, total, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{
state := api.StateType(ctx.FormString("state"))
var isClosed util.OptionalBool
switch state {
case api.StateClosed, api.StateOpen:
isClosed = util.OptionalBoolOf(state == api.StateClosed)
}
milestones, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{
ListOptions: utils.GetListOptions(ctx),
RepoID: ctx.Repo.Repository.ID,
State: api.StateType(ctx.FormString("state")),
IsClosed: isClosed,
Name: ctx.FormString("name"),
})
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetMilestones", err)
ctx.Error(http.StatusInternalServerError, "db.FindAndCount[issues_model.Milestone]", err)
return
}
+2 -2
View File
@@ -66,7 +66,7 @@ func getNote(ctx *context.APIContext, identifier string) {
return
}
commitSHA, err := ctx.Repo.GitRepo.ConvertToSHA1(identifier)
commitID, err := ctx.Repo.GitRepo.ConvertToGitID(identifier)
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(err)
@@ -77,7 +77,7 @@ func getNote(ctx *context.APIContext, identifier string) {
}
var note git.Note
if err := git.GetNote(ctx, ctx.Repo.GitRepo, commitSHA.String(), &note); err != nil {
if err := git.GetNote(ctx, ctx.Repo.GitRepo, commitID.String(), &note); err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(identifier)
return
+10 -21
View File
@@ -49,13 +49,12 @@ func GetRelease(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
id := ctx.ParamsInt64(":id")
release, err := repo_model.GetReleaseByID(ctx, id)
release, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
return
}
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
release.IsTag || release.RepoID != ctx.Repo.Repository.ID {
if err != nil && repo_model.IsErrReleaseNotExist(err) || release.IsTag {
ctx.NotFound()
return
}
@@ -134,11 +133,6 @@ func ListReleases(ctx *context.APIContext) {
// in: query
// description: filter (exclude / include) pre-releases
// type: boolean
// - name: per_page
// in: query
// description: page size of results, deprecated - use limit
// type: integer
// deprecated: true
// - name: page
// in: query
// description: page number of results to return (1-based)
@@ -153,9 +147,6 @@ func ListReleases(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
listOptions := utils.GetListOptions(ctx)
if listOptions.PageSize == 0 && ctx.FormInt("per_page") != 0 {
listOptions.PageSize = ctx.FormInt("per_page")
}
opts := repo_model.FindReleasesOptions{
ListOptions: listOptions,
@@ -315,13 +306,12 @@ func EditRelease(ctx *context.APIContext) {
form := web.GetForm(ctx).(*api.EditReleaseOption)
id := ctx.ParamsInt64(":id")
rel, err := repo_model.GetReleaseByID(ctx, id)
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
return
}
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag {
ctx.NotFound()
return
}
@@ -393,17 +383,16 @@ func DeleteRelease(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
id := ctx.ParamsInt64(":id")
rel, err := repo_model.GetReleaseByID(ctx, id)
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
if err != nil && !repo_model.IsErrReleaseNotExist(err) {
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
ctx.Error(http.StatusInternalServerError, "GetReleaseForRepoByID", err)
return
}
if err != nil && repo_model.IsErrReleaseNotExist(err) ||
rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
if err != nil && repo_model.IsErrReleaseNotExist(err) || rel.IsTag {
ctx.NotFound()
return
}
if err := release_service.DeleteReleaseByID(ctx, id, ctx.Doer, false); err != nil {
if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
+31 -8
View File
@@ -17,6 +17,23 @@ import (
"code.gitea.io/gitea/services/convert"
)
func checkReleaseMatchRepo(ctx *context.APIContext, releaseID int64) bool {
release, err := repo_model.GetReleaseByID(ctx, releaseID)
if err != nil {
if repo_model.IsErrReleaseNotExist(err) {
ctx.NotFound()
return false
}
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
return false
}
if release.RepoID != ctx.Repo.Repository.ID {
ctx.NotFound()
return false
}
return true
}
// GetReleaseAttachment gets a single attachment of the release
func GetReleaseAttachment(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/releases/{id}/assets/{attachment_id} repository repoGetReleaseAttachment
@@ -54,6 +71,10 @@ func GetReleaseAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
releaseID := ctx.ParamsInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
@@ -176,13 +197,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release
releaseID := ctx.ParamsInt64(":id")
release, err := repo_model.GetReleaseByID(ctx, releaseID)
if err != nil {
if repo_model.IsErrReleaseNotExist(err) {
ctx.NotFound()
return
}
ctx.Error(http.StatusInternalServerError, "GetReleaseByID", err)
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
@@ -203,7 +218,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
attach, err := attachment.UploadAttachment(ctx, file, setting.Repository.Release.AllowedTypes, header.Size, &repo_model.Attachment{
Name: filename,
UploaderID: ctx.Doer.ID,
RepoID: release.RepoID,
RepoID: ctx.Repo.Repository.ID,
ReleaseID: releaseID,
})
if err != nil {
@@ -264,6 +279,10 @@ func EditReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release
releaseID := ctx.ParamsInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
@@ -328,6 +347,10 @@ func DeleteReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release
releaseID := ctx.ParamsInt64(":id")
if !checkReleaseMatchRepo(ctx, releaseID) {
return
}
attachID := ctx.ParamsInt64(":attachment_id")
attach, err := repo_model.GetAttachmentByID(ctx, attachID)
if err != nil {
+1 -1
View File
@@ -112,7 +112,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
return
}
if err = releaseservice.DeleteReleaseByID(ctx, release.ID, ctx.Doer, false); err != nil {
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
+1
View File
@@ -253,6 +253,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
DefaultBranch: opt.DefaultBranch,
TrustModel: repo_model.ToTrustModel(opt.TrustModel),
IsTemplate: opt.Template,
ObjectFormat: git.ObjectFormatFromID(git.Sha1),
})
if err != nil {
if repo_model.IsErrRepoAlreadyExist(err) {
+1 -1
View File
@@ -272,7 +272,7 @@ func DeleteTag(ctx *context.APIContext) {
return
}
if err = releaseservice.DeleteReleaseByID(ctx, tag.ID, ctx.Doer, true); err != nil {
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
+4
View File
@@ -342,6 +342,10 @@ func GetOauth2Application(ctx *context.APIContext) {
}
return
}
if app.UID != ctx.Doer.ID {
ctx.NotFound()
return
}
app.ClientSecret = ""
+1 -1
View File
@@ -112,7 +112,7 @@ func GetGPGKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
key, err := asymkey_model.GetGPGKeyByID(ctx, ctx.ParamsInt64(":id"))
key, err := asymkey_model.GetGPGKeyForUserByID(ctx, ctx.Doer.ID, ctx.ParamsInt64(":id"))
if err != nil {
if asymkey_model.IsErrGPGKeyNotExist(err) {
ctx.NotFound()
+5
View File
@@ -62,6 +62,11 @@ func GetHook(ctx *context.APIContext) {
return
}
if !ctx.Doer.IsAdmin && hook.OwnerID != ctx.Doer.ID {
ctx.NotFound()
return
}
apiHook, err := webhook_service.ToHook(ctx.Doer.HomeLink(), hook)
if err != nil {
ctx.InternalServerError(err)
+9 -8
View File
@@ -69,27 +69,28 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str
return "", "", nil
}
// ConvertToSHA1 returns a full-length SHA1 from a potential ID string
func ConvertToSHA1(ctx gocontext.Context, repo *context.Repository, commitID string) (git.SHA1, error) {
if len(commitID) == git.SHAFullLength && git.IsValidSHAPattern(commitID) {
sha1, err := git.NewIDFromString(commitID)
// ConvertToObjectID returns a full-length SHA1 from a potential ID string
func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) {
objectFormat, _ := repo.GitRepo.GetObjectFormat()
if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
sha, err := objectFormat.NewIDFromString(commitID)
if err == nil {
return sha1, nil
return sha, nil
}
}
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.Repository.RepoPath())
if err != nil {
return git.SHA1{}, fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
return objectFormat.Empty(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err)
}
defer closer.Close()
return gitRepo.ConvertToSHA1(commitID)
return gitRepo.ConvertToGitID(commitID)
}
// MustConvertToSHA1 returns a full-length SHA1 string from a potential ID string, or returns origin input if it can't convert to SHA1
func MustConvertToSHA1(ctx gocontext.Context, repo *context.Repository, commitID string) string {
sha, err := ConvertToSHA1(ctx, repo, commitID)
sha, err := ConvertToObjectID(ctx, repo, commitID)
if err != nil {
return commitID
}