fix permission check for delete tag (#19985)

fix #19970

by the way, fix some error response about protected tags.

Signed-off-by: a1012112796 <1012112796@qq.com>
This commit is contained in:
a1012112796 2022-06-17 04:03:03 +08:00 committed by GitHub
parent 89b0aac374
commit e3e06d13af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 1 deletions

View file

@ -345,6 +345,8 @@ func DeleteRelease(ctx *context.APIContext) {
// "$ref": "#/responses/empty" // "$ref": "#/responses/empty"
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
// "405":
// "$ref": "#/responses/empty"
id := ctx.ParamsInt64(":id") id := ctx.ParamsInt64(":id")
rel, err := models.GetReleaseByID(ctx, id) rel, err := models.GetReleaseByID(ctx, id)
@ -358,6 +360,10 @@ func DeleteRelease(ctx *context.APIContext) {
return return
} }
if err := release_service.DeleteReleaseByID(ctx, id, ctx.Doer, false); err != nil { if err := release_service.DeleteReleaseByID(ctx, id, ctx.Doer, false); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
}
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
return return
} }

View file

@ -92,6 +92,8 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
// "$ref": "#/responses/empty" // "$ref": "#/responses/empty"
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
// "405":
// "$ref": "#/responses/empty"
tag := ctx.Params(":tag") tag := ctx.Params(":tag")
@ -111,7 +113,12 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
} }
if err = releaseservice.DeleteReleaseByID(ctx, release.ID, ctx.Doer, false); err != nil { if err = releaseservice.DeleteReleaseByID(ctx, release.ID, ctx.Doer, false); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
}
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
return
} }
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)

View file

@ -176,6 +176,8 @@ func CreateTag(ctx *context.APIContext) {
// "$ref": "#/responses/Tag" // "$ref": "#/responses/Tag"
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
// "405":
// "$ref": "#/responses/empty"
// "409": // "409":
// "$ref": "#/responses/conflict" // "$ref": "#/responses/conflict"
form := web.GetForm(ctx).(*api.CreateTagOption) form := web.GetForm(ctx).(*api.CreateTagOption)
@ -196,6 +198,11 @@ func CreateTag(ctx *context.APIContext) {
ctx.Error(http.StatusConflict, "tag exist", err) ctx.Error(http.StatusConflict, "tag exist", err)
return return
} }
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "CreateNewTag", "user not allowed to create protected tag")
return
}
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
} }
@ -236,6 +243,8 @@ func DeleteTag(ctx *context.APIContext) {
// "$ref": "#/responses/empty" // "$ref": "#/responses/empty"
// "404": // "404":
// "$ref": "#/responses/notFound" // "$ref": "#/responses/notFound"
// "405":
// "$ref": "#/responses/empty"
// "409": // "409":
// "$ref": "#/responses/conflict" // "$ref": "#/responses/conflict"
tagName := ctx.Params("*") tagName := ctx.Params("*")
@ -256,7 +265,12 @@ func DeleteTag(ctx *context.APIContext) {
} }
if err = releaseservice.DeleteReleaseByID(ctx, tag.ID, ctx.Doer, true); err != nil { if err = releaseservice.DeleteReleaseByID(ctx, tag.ID, ctx.Doer, true); err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
return
}
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err) ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
return
} }
ctx.Status(http.StatusNoContent) ctx.Status(http.StatusNoContent)

View file

@ -373,6 +373,12 @@ func CreateBranch(ctx *context.Context) {
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName) err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName)
} }
if err != nil { if err != nil {
if models.IsErrProtectedTagName(err) {
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
return
}
if models.IsErrTagAlreadyExists(err) { if models.IsErrTagAlreadyExists(err) {
e := err.(models.ErrTagAlreadyExists) e := err.(models.ErrTagAlreadyExists)
ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName)) ctx.Flash.Error(ctx.Tr("repo.branch.tag_collision", e.TagName))

View file

@ -519,7 +519,11 @@ func DeleteTag(ctx *context.Context) {
func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) { func deleteReleaseOrTag(ctx *context.Context, isDelTag bool) {
if err := releaseservice.DeleteReleaseByID(ctx, ctx.FormInt64("id"), ctx.Doer, isDelTag); err != nil { if err := releaseservice.DeleteReleaseByID(ctx, ctx.FormInt64("id"), ctx.Doer, isDelTag); err != nil {
ctx.Flash.Error("DeleteReleaseByID: " + err.Error()) if models.IsErrProtectedTagName(err) {
ctx.Flash.Error(ctx.Tr("repo.release.tag_name_protected"))
} else {
ctx.Flash.Error("DeleteReleaseByID: " + err.Error())
}
} else { } else {
if isDelTag { if isDelTag {
ctx.Flash.Success(ctx.Tr("repo.release.deletion_tag_success")) ctx.Flash.Success(ctx.Tr("repo.release.deletion_tag_success"))

View file

@ -294,6 +294,20 @@ func DeleteReleaseByID(ctx context.Context, id int64, doer *user_model.User, del
} }
if delTag { if delTag {
protectedTags, err := git_model.GetProtectedTags(rel.RepoID)
if err != nil {
return fmt.Errorf("GetProtectedTags: %v", err)
}
isAllowed, err := git_model.IsUserAllowedToControlTag(protectedTags, rel.TagName, rel.PublisherID)
if err != nil {
return err
}
if !isAllowed {
return models.ErrProtectedTagName{
TagName: rel.TagName,
}
}
if stdout, _, err := git.NewCommand(ctx, "tag", "-d", rel.TagName). if stdout, _, err := git.NewCommand(ctx, "tag", "-d", rel.TagName).
SetDescription(fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID)). SetDescription(fmt.Sprintf("DeleteReleaseByID (git tag -d): %d", rel.ID)).
RunStdString(&git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") { RunStdString(&git.RunOpts{Dir: repo.RepoPath()}); err != nil && !strings.Contains(err.Error(), "not found") {

View file

@ -8960,6 +8960,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"405": {
"$ref": "#/responses/empty"
} }
} }
} }
@ -9043,6 +9046,9 @@
}, },
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
},
"405": {
"$ref": "#/responses/empty"
} }
} }
}, },
@ -9811,6 +9817,9 @@
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
}, },
"405": {
"$ref": "#/responses/empty"
},
"409": { "409": {
"$ref": "#/responses/conflict" "$ref": "#/responses/conflict"
} }
@ -9898,6 +9907,9 @@
"404": { "404": {
"$ref": "#/responses/notFound" "$ref": "#/responses/notFound"
}, },
"405": {
"$ref": "#/responses/empty"
},
"409": { "409": {
"$ref": "#/responses/conflict" "$ref": "#/responses/conflict"
} }