Backport #30962 by @KN4CK3R Fixes #30959 Adds an API test for protected tags. Fix existing tag in combination with fixtures. Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
This commit is contained in:
parent
c1337e7316
commit
8393ff78fc
24
models/fixtures/protected_tag.yml
Normal file
24
models/fixtures/protected_tag.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
-
|
||||||
|
id: 1
|
||||||
|
repo_id: 4
|
||||||
|
name_pattern: /v.+/
|
||||||
|
allowlist_user_i_ds: []
|
||||||
|
allowlist_team_i_ds: []
|
||||||
|
created_unix: 1715596037
|
||||||
|
updated_unix: 1715596037
|
||||||
|
-
|
||||||
|
id: 2
|
||||||
|
repo_id: 1
|
||||||
|
name_pattern: v-*
|
||||||
|
allowlist_user_i_ds: []
|
||||||
|
allowlist_team_i_ds: []
|
||||||
|
created_unix: 1715596037
|
||||||
|
updated_unix: 1715596037
|
||||||
|
-
|
||||||
|
id: 3
|
||||||
|
repo_id: 1
|
||||||
|
name_pattern: v-1.1
|
||||||
|
allowlist_user_i_ds: [2]
|
||||||
|
allowlist_team_i_ds: []
|
||||||
|
created_unix: 1715596037
|
||||||
|
updated_unix: 1715596037
|
|
@ -215,6 +215,9 @@ func CreateRelease(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "409":
|
// "409":
|
||||||
// "$ref": "#/responses/error"
|
// "$ref": "#/responses/error"
|
||||||
|
// "422":
|
||||||
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
form := web.GetForm(ctx).(*api.CreateReleaseOption)
|
form := web.GetForm(ctx).(*api.CreateReleaseOption)
|
||||||
if ctx.Repo.Repository.IsEmpty {
|
if ctx.Repo.Repository.IsEmpty {
|
||||||
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
|
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
|
||||||
|
@ -246,6 +249,8 @@ func CreateRelease(ctx *context.APIContext) {
|
||||||
if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil {
|
if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil {
|
||||||
if repo_model.IsErrReleaseAlreadyExist(err) {
|
if repo_model.IsErrReleaseAlreadyExist(err) {
|
||||||
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
|
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
|
||||||
|
} else if models.IsErrProtectedTagName(err) {
|
||||||
|
ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err)
|
||||||
} else {
|
} else {
|
||||||
ctx.Error(http.StatusInternalServerError, "CreateRelease", err)
|
ctx.Error(http.StatusInternalServerError, "CreateRelease", err)
|
||||||
}
|
}
|
||||||
|
@ -386,8 +391,8 @@ func DeleteRelease(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "405":
|
// "422":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
id := ctx.ParamsInt64(":id")
|
id := ctx.ParamsInt64(":id")
|
||||||
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
rel, err := repo_model.GetReleaseForRepoByID(ctx, ctx.Repo.Repository.ID, id)
|
||||||
|
@ -401,7 +406,7 @@ func DeleteRelease(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil {
|
if err := release_service.DeleteReleaseByID(ctx, ctx.Repo.Repository, rel, ctx.Doer, false); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
||||||
|
|
|
@ -92,8 +92,8 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
// "405":
|
// "422":
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/validationError"
|
||||||
|
|
||||||
tag := ctx.Params(":tag")
|
tag := ctx.Params(":tag")
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
|
||||||
|
|
||||||
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil {
|
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, release, ctx.Doer, false); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
||||||
|
|
|
@ -184,6 +184,8 @@ func CreateTag(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "409":
|
// "409":
|
||||||
// "$ref": "#/responses/conflict"
|
// "$ref": "#/responses/conflict"
|
||||||
|
// "422":
|
||||||
|
// "$ref": "#/responses/validationError"
|
||||||
// "423":
|
// "423":
|
||||||
// "$ref": "#/responses/repoArchivedError"
|
// "$ref": "#/responses/repoArchivedError"
|
||||||
form := web.GetForm(ctx).(*api.CreateTagOption)
|
form := web.GetForm(ctx).(*api.CreateTagOption)
|
||||||
|
@ -205,7 +207,7 @@ func CreateTag(ctx *context.APIContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "CreateNewTag", "user not allowed to create protected tag")
|
ctx.Error(http.StatusUnprocessableEntity, "CreateNewTag", "user not allowed to create protected tag")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,6 +255,8 @@ func DeleteTag(ctx *context.APIContext) {
|
||||||
// "$ref": "#/responses/empty"
|
// "$ref": "#/responses/empty"
|
||||||
// "409":
|
// "409":
|
||||||
// "$ref": "#/responses/conflict"
|
// "$ref": "#/responses/conflict"
|
||||||
|
// "422":
|
||||||
|
// "$ref": "#/responses/validationError"
|
||||||
// "423":
|
// "423":
|
||||||
// "$ref": "#/responses/repoArchivedError"
|
// "$ref": "#/responses/repoArchivedError"
|
||||||
tagName := ctx.Params("*")
|
tagName := ctx.Params("*")
|
||||||
|
@ -274,7 +278,7 @@ func DeleteTag(ctx *context.APIContext) {
|
||||||
|
|
||||||
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil {
|
if err = releaseservice.DeleteReleaseByID(ctx, ctx.Repo.Repository, tag, ctx.Doer, true); err != nil {
|
||||||
if models.IsErrProtectedTagName(err) {
|
if models.IsErrProtectedTagName(err) {
|
||||||
ctx.Error(http.StatusMethodNotAllowed, "delTag", "user not allowed to delete protected tag")
|
ctx.Error(http.StatusUnprocessableEntity, "delTag", "user not allowed to delete protected tag")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
|
||||||
|
|
17
templates/swagger/v1_json.tmpl
generated
17
templates/swagger/v1_json.tmpl
generated
|
@ -12771,6 +12771,9 @@
|
||||||
},
|
},
|
||||||
"409": {
|
"409": {
|
||||||
"$ref": "#/responses/error"
|
"$ref": "#/responses/error"
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#/responses/validationError"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12889,8 +12892,8 @@
|
||||||
"404": {
|
"404": {
|
||||||
"$ref": "#/responses/notFound"
|
"$ref": "#/responses/notFound"
|
||||||
},
|
},
|
||||||
"405": {
|
"422": {
|
||||||
"$ref": "#/responses/empty"
|
"$ref": "#/responses/validationError"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12975,8 +12978,8 @@
|
||||||
"404": {
|
"404": {
|
||||||
"$ref": "#/responses/notFound"
|
"$ref": "#/responses/notFound"
|
||||||
},
|
},
|
||||||
"405": {
|
"422": {
|
||||||
"$ref": "#/responses/empty"
|
"$ref": "#/responses/validationError"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -13826,6 +13829,9 @@
|
||||||
"409": {
|
"409": {
|
||||||
"$ref": "#/responses/conflict"
|
"$ref": "#/responses/conflict"
|
||||||
},
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#/responses/validationError"
|
||||||
|
},
|
||||||
"423": {
|
"423": {
|
||||||
"$ref": "#/responses/repoArchivedError"
|
"$ref": "#/responses/repoArchivedError"
|
||||||
}
|
}
|
||||||
|
@ -13919,6 +13925,9 @@
|
||||||
"409": {
|
"409": {
|
||||||
"$ref": "#/responses/conflict"
|
"$ref": "#/responses/conflict"
|
||||||
},
|
},
|
||||||
|
"422": {
|
||||||
|
"$ref": "#/responses/validationError"
|
||||||
|
},
|
||||||
"423": {
|
"423": {
|
||||||
"$ref": "#/responses/repoArchivedError"
|
"$ref": "#/responses/repoArchivedError"
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,31 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
|
||||||
assert.EqualValues(t, rel.Note, newRelease.Note)
|
assert.EqualValues(t, rel.Note, newRelease.Note)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAPICreateProtectedTagRelease(t *testing.T) {
|
||||||
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
|
||||||
|
writer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
|
||||||
|
session := loginUser(t, writer.LowerName)
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||||
|
|
||||||
|
gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
defer gitRepo.Close()
|
||||||
|
|
||||||
|
commit, err := gitRepo.GetBranchCommit("master")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/releases", repo.OwnerName, repo.Name), &api.CreateReleaseOption{
|
||||||
|
TagName: "v0.0.1",
|
||||||
|
Title: "v0.0.1",
|
||||||
|
IsDraft: false,
|
||||||
|
IsPrerelease: false,
|
||||||
|
Target: commit.ID.String(),
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPICreateReleaseToDefaultBranch(t *testing.T) {
|
func TestAPICreateReleaseToDefaultBranch(t *testing.T) {
|
||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
|
|
|
@ -26,22 +26,10 @@ func TestCreateNewTagProtected(t *testing.T) {
|
||||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||||
|
|
||||||
t.Run("API", func(t *testing.T) {
|
t.Run("Code", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|
||||||
err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "first tag")
|
err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "t-first", "first tag")
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{
|
|
||||||
RepoID: repo.ID,
|
|
||||||
NamePattern: "v-*",
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
err = git_model.InsertProtectedTag(db.DefaultContext, &git_model.ProtectedTag{
|
|
||||||
RepoID: repo.ID,
|
|
||||||
NamePattern: "v-1.1",
|
|
||||||
AllowlistUserIDs: []int64{repo.OwnerID},
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag")
|
err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag")
|
||||||
|
@ -54,13 +42,12 @@ func TestCreateNewTagProtected(t *testing.T) {
|
||||||
|
|
||||||
t.Run("Git", func(t *testing.T) {
|
t.Run("Git", func(t *testing.T) {
|
||||||
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
||||||
username := "user2"
|
httpContext := NewAPITestContext(t, owner.Name, repo.Name)
|
||||||
httpContext := NewAPITestContext(t, username, "repo1")
|
|
||||||
|
|
||||||
dstPath := t.TempDir()
|
dstPath := t.TempDir()
|
||||||
|
|
||||||
u.Path = httpContext.GitPath()
|
u.Path = httpContext.GitPath()
|
||||||
u.User = url.UserPassword(username, userPassword)
|
u.User = url.UserPassword(owner.Name, userPassword)
|
||||||
|
|
||||||
doGitClone(dstPath, u)(t)
|
doGitClone(dstPath, u)(t)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user