mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Protected tag is no internal server error (#30962)
Fixes #30959 Adds an API test for protected tags. Fix existing tag in combination with fixtures.
This commit is contained in:
		
							
								
								
									
										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"
 | 
			
		||||
	//   "409":
 | 
			
		||||
	//     "$ref": "#/responses/error"
 | 
			
		||||
	//   "422":
 | 
			
		||||
	//     "$ref": "#/responses/validationError"
 | 
			
		||||
 | 
			
		||||
	form := web.GetForm(ctx).(*api.CreateReleaseOption)
 | 
			
		||||
	if ctx.Repo.Repository.IsEmpty {
 | 
			
		||||
		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 repo_model.IsErrReleaseAlreadyExist(err) {
 | 
			
		||||
				ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
 | 
			
		||||
			} else if models.IsErrProtectedTagName(err) {
 | 
			
		||||
				ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err)
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.Error(http.StatusInternalServerError, "CreateRelease", err)
 | 
			
		||||
			}
 | 
			
		||||
@@ -386,8 +391,8 @@ func DeleteRelease(ctx *context.APIContext) {
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "404":
 | 
			
		||||
	//     "$ref": "#/responses/notFound"
 | 
			
		||||
	//   "405":
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "422":
 | 
			
		||||
	//     "$ref": "#/responses/validationError"
 | 
			
		||||
 | 
			
		||||
	id := ctx.ParamsInt64(":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 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
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -92,8 +92,8 @@ func DeleteReleaseByTag(ctx *context.APIContext) {
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "404":
 | 
			
		||||
	//     "$ref": "#/responses/notFound"
 | 
			
		||||
	//   "405":
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "422":
 | 
			
		||||
	//     "$ref": "#/responses/validationError"
 | 
			
		||||
 | 
			
		||||
	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 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
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
 | 
			
		||||
 
 | 
			
		||||
@@ -184,6 +184,8 @@ func CreateTag(ctx *context.APIContext) {
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "409":
 | 
			
		||||
	//     "$ref": "#/responses/conflict"
 | 
			
		||||
	//   "422":
 | 
			
		||||
	//     "$ref": "#/responses/validationError"
 | 
			
		||||
	//   "423":
 | 
			
		||||
	//     "$ref": "#/responses/repoArchivedError"
 | 
			
		||||
	form := web.GetForm(ctx).(*api.CreateTagOption)
 | 
			
		||||
@@ -205,7 +207,7 @@ func CreateTag(ctx *context.APIContext) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		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
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -253,6 +255,8 @@ func DeleteTag(ctx *context.APIContext) {
 | 
			
		||||
	//     "$ref": "#/responses/empty"
 | 
			
		||||
	//   "409":
 | 
			
		||||
	//     "$ref": "#/responses/conflict"
 | 
			
		||||
	//   "422":
 | 
			
		||||
	//     "$ref": "#/responses/validationError"
 | 
			
		||||
	//   "423":
 | 
			
		||||
	//     "$ref": "#/responses/repoArchivedError"
 | 
			
		||||
	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 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
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Error(http.StatusInternalServerError, "DeleteReleaseByID", err)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										17
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							@@ -12831,6 +12831,9 @@
 | 
			
		||||
          },
 | 
			
		||||
          "409": {
 | 
			
		||||
            "$ref": "#/responses/error"
 | 
			
		||||
          },
 | 
			
		||||
          "422": {
 | 
			
		||||
            "$ref": "#/responses/validationError"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -12949,8 +12952,8 @@
 | 
			
		||||
          "404": {
 | 
			
		||||
            "$ref": "#/responses/notFound"
 | 
			
		||||
          },
 | 
			
		||||
          "405": {
 | 
			
		||||
            "$ref": "#/responses/empty"
 | 
			
		||||
          "422": {
 | 
			
		||||
            "$ref": "#/responses/validationError"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@@ -13035,8 +13038,8 @@
 | 
			
		||||
          "404": {
 | 
			
		||||
            "$ref": "#/responses/notFound"
 | 
			
		||||
          },
 | 
			
		||||
          "405": {
 | 
			
		||||
            "$ref": "#/responses/empty"
 | 
			
		||||
          "422": {
 | 
			
		||||
            "$ref": "#/responses/validationError"
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
@@ -13886,6 +13889,9 @@
 | 
			
		||||
          "409": {
 | 
			
		||||
            "$ref": "#/responses/conflict"
 | 
			
		||||
          },
 | 
			
		||||
          "422": {
 | 
			
		||||
            "$ref": "#/responses/validationError"
 | 
			
		||||
          },
 | 
			
		||||
          "423": {
 | 
			
		||||
            "$ref": "#/responses/repoArchivedError"
 | 
			
		||||
          }
 | 
			
		||||
@@ -13979,6 +13985,9 @@
 | 
			
		||||
          "409": {
 | 
			
		||||
            "$ref": "#/responses/conflict"
 | 
			
		||||
          },
 | 
			
		||||
          "422": {
 | 
			
		||||
            "$ref": "#/responses/validationError"
 | 
			
		||||
          },
 | 
			
		||||
          "423": {
 | 
			
		||||
            "$ref": "#/responses/repoArchivedError"
 | 
			
		||||
          }
 | 
			
		||||
 
 | 
			
		||||
@@ -154,6 +154,31 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
 | 
			
		||||
	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) {
 | 
			
		||||
	defer tests.PrepareTestEnv(t)()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,22 +26,10 @@ func TestCreateNewTagProtected(t *testing.T) {
 | 
			
		||||
	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 | 
			
		||||
	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)()
 | 
			
		||||
 | 
			
		||||
		err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "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},
 | 
			
		||||
		})
 | 
			
		||||
		err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "t-first", "first tag")
 | 
			
		||||
		assert.NoError(t, err)
 | 
			
		||||
 | 
			
		||||
		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) {
 | 
			
		||||
		onGiteaRun(t, func(t *testing.T, u *url.URL) {
 | 
			
		||||
			username := "user2"
 | 
			
		||||
			httpContext := NewAPITestContext(t, username, "repo1")
 | 
			
		||||
			httpContext := NewAPITestContext(t, owner.Name, repo.Name)
 | 
			
		||||
 | 
			
		||||
			dstPath := t.TempDir()
 | 
			
		||||
 | 
			
		||||
			u.Path = httpContext.GitPath()
 | 
			
		||||
			u.User = url.UserPassword(username, userPassword)
 | 
			
		||||
			u.User = url.UserPassword(owner.Name, userPassword)
 | 
			
		||||
 | 
			
		||||
			doGitClone(dstPath, u)(t)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user