From 5b6258a0b94737ec3db1ce418d0c933512a71f78 Mon Sep 17 00:00:00 2001 From: Nanguan Lin <70063547+lng2020@users.noreply.github.com> Date: Tue, 10 Oct 2023 21:39:58 +0800 Subject: [PATCH] Fix the wrong HTTP response status code for duplicate packages (#27480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #27470 (hope there is nothing missing 😢 ) --------- Co-authored-by: KN4CK3R --- docs/content/usage/packages/alpine.en-us.md | 1 + docs/content/usage/packages/composer.en-us.md | 4 +++- docs/content/usage/packages/conan.en-us.md | 2 ++ docs/content/usage/packages/conda.en-us.md | 10 ++++++++++ docs/content/usage/packages/cran.en-us.md | 10 ++++++++++ docs/content/usage/packages/debian.en-us.md | 5 +++-- docs/content/usage/packages/go.en-us.md | 2 ++ docs/content/usage/packages/swift.en-us.md | 8 ++++++++ docs/content/usage/packages/vagrant.en-us.md | 10 ++++++++++ routers/api/packages/alpine/alpine.go | 2 +- routers/api/packages/chef/chef.go | 2 +- routers/api/packages/composer/composer.go | 2 +- routers/api/packages/conan/conan.go | 2 +- routers/api/packages/debian/debian.go | 2 +- routers/api/packages/maven/maven.go | 2 +- routers/api/packages/npm/npm.go | 2 +- routers/api/packages/pub/pub.go | 2 +- routers/api/packages/pypi/pypi.go | 2 +- routers/api/packages/rubygems/rubygems.go | 2 +- tests/integration/api_packages_chef_test.go | 2 +- tests/integration/api_packages_composer_test.go | 2 +- tests/integration/api_packages_debian_test.go | 2 +- tests/integration/api_packages_maven_test.go | 4 ++-- tests/integration/api_packages_npm_test.go | 2 +- tests/integration/api_packages_pub_test.go | 2 +- tests/integration/api_packages_pypi_test.go | 4 ++-- tests/integration/api_packages_rubygems_test.go | 2 +- 27 files changed, 69 insertions(+), 23 deletions(-) diff --git a/docs/content/usage/packages/alpine.en-us.md b/docs/content/usage/packages/alpine.en-us.md index 1fcbe8485..00331f3bb 100644 --- a/docs/content/usage/packages/alpine.en-us.md +++ b/docs/content/usage/packages/alpine.en-us.md @@ -77,6 +77,7 @@ curl --user your_username:your_password_or_token \ ``` If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. + You cannot publish a file with the same name twice to a package. You must delete the existing package file first. The server responds with the following HTTP Status codes. diff --git a/docs/content/usage/packages/composer.en-us.md b/docs/content/usage/packages/composer.en-us.md index 7fbd77ef5..60ad52ac2 100644 --- a/docs/content/usage/packages/composer.en-us.md +++ b/docs/content/usage/packages/composer.en-us.md @@ -25,6 +25,7 @@ To work with the Composer package registry, you can use [Composer](https://getco To publish a Composer package perform a HTTP PUT operation with the package content in the request body. The package content must be the zipped PHP project with the `composer.json` file. + You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. ``` @@ -64,7 +65,8 @@ The server responds with the following HTTP Status codes. | HTTP Status Code | Meaning | | ----------------- | ------- | | `201 Created` | The package has been published. | -| `400 Bad Request` | The package name and/or version are invalid or a package with the same name and version already exist. | +| `400 Bad Request` | The package is invalid. | +| `409 Conflict` | A package file with the same combination of parameters exists already. | ## Configuring the package registry diff --git a/docs/content/usage/packages/conan.en-us.md b/docs/content/usage/packages/conan.en-us.md index 24c7077a8..505460b31 100644 --- a/docs/content/usage/packages/conan.en-us.md +++ b/docs/content/usage/packages/conan.en-us.md @@ -63,6 +63,8 @@ For example: conan upload --remote=gitea ConanPackage/1.2@gitea/final ``` +You cannot publish a file with the same name twice to a package. You must delete the existing package or file first. + The Gitea Conan package registry has full [revision](https://docs.conan.io/en/latest/versioning/revisions.html) support. ## Install a package diff --git a/docs/content/usage/packages/conda.en-us.md b/docs/content/usage/packages/conda.en-us.md index 5b6f97679..a256dca51 100644 --- a/docs/content/usage/packages/conda.en-us.md +++ b/docs/content/usage/packages/conda.en-us.md @@ -63,8 +63,18 @@ curl --user your_username:your_password_or_token \ https://gitea.example.com/api/packages/testuser/conda/package-1.0.conda ``` +If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. + You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. +The server responds with the following HTTP Status codes. + +| HTTP Status Code | Meaning | +| ----------------- | ------- | +| `201 Created` | The package has been published. | +| `400 Bad Request` | The package is invalid. | +| `409 Conflict` | A package file with the same combination of parameters exists already. | + ## Install a package To install a package from the package registry, execute one of the following commands: diff --git a/docs/content/usage/packages/cran.en-us.md b/docs/content/usage/packages/cran.en-us.md index 68de425d2..a6b0d3185 100644 --- a/docs/content/usage/packages/cran.en-us.md +++ b/docs/content/usage/packages/cran.en-us.md @@ -68,8 +68,18 @@ curl --user your_username:your_password_or_token \ https://gitea.example.com/api/packages/testuser/cran/bin?platform=windows&rversion=4.2 ``` +If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. + You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. +The server responds with the following HTTP Status codes. + +| HTTP Status Code | Meaning | +| ----------------- | ------- | +| `201 Created` | The package has been published. | +| `400 Bad Request` | The package is invalid. | +| `409 Conflict` | A package file with the same combination of parameters exists already. | + ## Install a package To install a R package from the package registry, execute the following command: diff --git a/docs/content/usage/packages/debian.en-us.md b/docs/content/usage/packages/debian.en-us.md index 6bd7475dd..9ae1dc15c 100644 --- a/docs/content/usage/packages/debian.en-us.md +++ b/docs/content/usage/packages/debian.en-us.md @@ -77,14 +77,15 @@ curl --user your_username:your_password_or_token \ ``` If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. -You cannot publish a file with the same name twice to a package. You must delete the existing package version first. + +You cannot publish a package if a package of the same name, version, distribution, component and architecture already exists. You must delete the existing package first. The server responds with the following HTTP Status codes. | HTTP Status Code | Meaning | | ----------------- | ------- | | `201 Created` | The package has been published. | -| `400 Bad Request` | The package name, version, distribution, component or architecture are invalid. | +| `400 Bad Request` | The package is invalid. | | `409 Conflict` | A package file with the same combination of parameters exists already. | ## Delete a package diff --git a/docs/content/usage/packages/go.en-us.md b/docs/content/usage/packages/go.en-us.md index 7c4069248..ed3c1a87e 100644 --- a/docs/content/usage/packages/go.en-us.md +++ b/docs/content/usage/packages/go.en-us.md @@ -41,6 +41,8 @@ curl --user your_username:your_password_or_token \ If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. +You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. + The server responds with the following HTTP Status codes. | HTTP Status Code | Meaning | diff --git a/docs/content/usage/packages/swift.en-us.md b/docs/content/usage/packages/swift.en-us.md index 1bc271dda..606fa20b3 100644 --- a/docs/content/usage/packages/swift.en-us.md +++ b/docs/content/usage/packages/swift.en-us.md @@ -67,6 +67,14 @@ curl -X PUT --user {username}:{password} \ You cannot publish a package if a package of the same name and version already exists. You must delete the existing package first. +The server responds with the following HTTP Status codes. + +| HTTP Status Code | Meaning | +| ----------------- | ------- | +| `201 Created` | The package has been published. | +| `400 Bad Request` | The package is invalid. | +| `409 Conflict` | A package file with the same combination of parameters exists already. | + ## Install a package To install a Swift package from the package registry, add it in the `Package.swift` file dependencies list: diff --git a/docs/content/usage/packages/vagrant.en-us.md b/docs/content/usage/packages/vagrant.en-us.md index 93cf5e3e7..baa9c2b83 100644 --- a/docs/content/usage/packages/vagrant.en-us.md +++ b/docs/content/usage/packages/vagrant.en-us.md @@ -44,8 +44,18 @@ curl --user your_username:your_password_or_token \ https://gitea.example.com/api/packages/testuser/vagrant/test_system/1.0.0/hyperv.box ``` +If you are using 2FA or OAuth use a [personal access token](development/api-usage.md#authentication) instead of the password. + You cannot publish a box if a box of the same name, version and provider already exists. You must delete the existing package first. +The server responds with the following HTTP Status codes. + +| HTTP Status Code | Meaning | +| ----------------- | ------- | +| `201 Created` | The package has been published. | +| `400 Bad Request` | The package is invalid. | +| `409 Conflict` | A package with the same combination of parameters exists already. | + ## Install a package To install a box from the package registry, execute the following command: diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go index c261eee2d..bb14c5163 100644 --- a/routers/api/packages/alpine/alpine.go +++ b/routers/api/packages/alpine/alpine.go @@ -164,7 +164,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go index a1f5f49bd..f1e9ae12d 100644 --- a/routers/api/packages/chef/chef.go +++ b/routers/api/packages/chef/chef.go @@ -310,7 +310,7 @@ func UploadPackage(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index 313631d7d..0551093cd 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -247,7 +247,7 @@ func UploadPackage(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go index f440f83b2..4bf13222d 100644 --- a/routers/api/packages/conan/conan.go +++ b/routers/api/packages/conan/conan.go @@ -415,7 +415,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey if err != nil { switch err { case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go index dc7ebab09..379137e87 100644 --- a/routers/api/packages/debian/debian.go +++ b/routers/api/packages/debian/debian.go @@ -189,7 +189,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go index 52e31e803..0b93382b0 100644 --- a/routers/api/packages/maven/maven.go +++ b/routers/api/packages/maven/maven.go @@ -363,7 +363,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go index dd6b3f148..170edfbe1 100644 --- a/routers/api/packages/npm/npm.go +++ b/routers/api/packages/npm/npm.go @@ -214,7 +214,7 @@ func UploadPackage(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go index 8460f861c..1f605c6c9 100644 --- a/routers/api/packages/pub/pub.go +++ b/routers/api/packages/pub/pub.go @@ -213,7 +213,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go index 8c7f9bbf3..5718b1203 100644 --- a/routers/api/packages/pypi/pypi.go +++ b/routers/api/packages/pypi/pypi.go @@ -177,7 +177,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageFile: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go index 061fb0871..01fd4dad6 100644 --- a/routers/api/packages/rubygems/rubygems.go +++ b/routers/api/packages/rubygems/rubygems.go @@ -258,7 +258,7 @@ func UploadPackageFile(ctx *context.Context) { if err != nil { switch err { case packages_model.ErrDuplicatePackageVersion: - apiError(ctx, http.StatusBadRequest, err) + apiError(ctx, http.StatusConflict, err) case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: apiError(ctx, http.StatusForbidden, err) default: diff --git a/tests/integration/api_packages_chef_test.go b/tests/integration/api_packages_chef_test.go index 4a1fe2607..7f55a84f0 100644 --- a/tests/integration/api_packages_chef_test.go +++ b/tests/integration/api_packages_chef_test.go @@ -322,7 +322,7 @@ nwIDAQAB assert.Equal(t, fmt.Sprintf("%s.tar.gz", packageVersion), pfs[0].Name) assert.True(t, pfs[0].IsLead) - uploadPackage(t, packageVersion, http.StatusBadRequest) + uploadPackage(t, packageVersion, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_composer_test.go b/tests/integration/api_packages_composer_test.go index ac1259056..896462d9a 100644 --- a/tests/integration/api_packages_composer_test.go +++ b/tests/integration/api_packages_composer_test.go @@ -112,7 +112,7 @@ func TestPackageComposer(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) req = AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) + MakeRequest(t, req, http.StatusConflict) }) }) diff --git a/tests/integration/api_packages_debian_test.go b/tests/integration/api_packages_debian_test.go index 2d92b9315..f796d617d 100644 --- a/tests/integration/api_packages_debian_test.go +++ b/tests/integration/api_packages_debian_test.go @@ -147,7 +147,7 @@ func TestPackageDebian(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)) AddBasicAuthHeader(req, user.Name) - MakeRequest(t, req, http.StatusBadRequest) + MakeRequest(t, req, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_maven_test.go b/tests/integration/api_packages_maven_test.go index 81112f305..c78024563 100644 --- a/tests/integration/api_packages_maven_test.go +++ b/tests/integration/api_packages_maven_test.go @@ -50,7 +50,7 @@ func TestPackageMaven(t *testing.T) { defer tests.PrintCurrentTest(t)() putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusCreated) - putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusBadRequest) + putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusConflict) putFile(t, "/maven-metadata.xml", "test", http.StatusOK) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeMaven) @@ -78,7 +78,7 @@ func TestPackageMaven(t *testing.T) { t.Run("UploadExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusBadRequest) + putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_npm_test.go b/tests/integration/api_packages_npm_test.go index 433b183c2..bd3bfeeff 100644 --- a/tests/integration/api_packages_npm_test.go +++ b/tests/integration/api_packages_npm_test.go @@ -121,7 +121,7 @@ func TestPackageNpm(t *testing.T) { req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))) req = addTokenAuthHeader(req, token) - MakeRequest(t, req, http.StatusBadRequest) + MakeRequest(t, req, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_pub_test.go b/tests/integration/api_packages_pub_test.go index cae280c0e..6e9d8742f 100644 --- a/tests/integration/api_packages_pub_test.go +++ b/tests/integration/api_packages_pub_test.go @@ -121,7 +121,7 @@ description: ` + packageDescription assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - _ = uploadFile(t, result.URL, content, http.StatusBadRequest) + _ = uploadFile(t, result.URL, content, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_pypi_test.go b/tests/integration/api_packages_pypi_test.go index c7c466e73..76013b79c 100644 --- a/tests/integration/api_packages_pypi_test.go +++ b/tests/integration/api_packages_pypi_test.go @@ -129,8 +129,8 @@ func TestPackagePyPI(t *testing.T) { t.Run("UploadExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - uploadFile(t, "test.whl", content, http.StatusBadRequest) - uploadFile(t, "test.tar.gz", content, http.StatusBadRequest) + uploadFile(t, "test.whl", content, http.StatusConflict) + uploadFile(t, "test.tar.gz", content, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_packages_rubygems_test.go b/tests/integration/api_packages_rubygems_test.go index 2099357cb..a3df14320 100644 --- a/tests/integration/api_packages_rubygems_test.go +++ b/tests/integration/api_packages_rubygems_test.go @@ -150,7 +150,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`) t.Run("UploadExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - uploadFile(t, http.StatusBadRequest) + uploadFile(t, http.StatusConflict) }) t.Run("Download", func(t *testing.T) {