Fix the wrong HTTP response status code for duplicate packages (#27480)

fix #27470 
(hope there is nothing missing 😢 )

---------

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
This commit is contained in:
Nanguan Lin 2023-10-10 21:39:58 +08:00 committed by GitHub
parent 2c7b6c378e
commit 5b6258a0b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 69 additions and 23 deletions

View file

@ -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. 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. 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. The server responds with the following HTTP Status codes.

View file

@ -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. 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. 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. 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 | | HTTP Status Code | Meaning |
| ----------------- | ------- | | ----------------- | ------- |
| `201 Created` | The package has been published. | | `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 ## Configuring the package registry

View file

@ -63,6 +63,8 @@ For example:
conan upload --remote=gitea ConanPackage/1.2@gitea/final 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. The Gitea Conan package registry has full [revision](https://docs.conan.io/en/latest/versioning/revisions.html) support.
## Install a package ## Install a package

View file

@ -63,8 +63,18 @@ curl --user your_username:your_password_or_token \
https://gitea.example.com/api/packages/testuser/conda/package-1.0.conda 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. 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 ## Install a package
To install a package from the package registry, execute one of the following commands: To install a package from the package registry, execute one of the following commands:

View file

@ -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 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. 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 ## Install a package
To install a R package from the package registry, execute the following command: To install a R package from the package registry, execute the following command:

View file

@ -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. 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. The server responds with the following HTTP Status codes.
| HTTP Status Code | Meaning | | HTTP Status Code | Meaning |
| ----------------- | ------- | | ----------------- | ------- |
| `201 Created` | The package has been published. | | `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. | | `409 Conflict` | A package file with the same combination of parameters exists already. |
## Delete a package ## Delete a package

View file

@ -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. 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. The server responds with the following HTTP Status codes.
| HTTP Status Code | Meaning | | HTTP Status Code | Meaning |

View file

@ -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. 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 ## Install a package
To install a Swift package from the package registry, add it in the `Package.swift` file dependencies list: To install a Swift package from the package registry, add it in the `Package.swift` file dependencies list:

View file

@ -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 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. 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 ## Install a package
To install a box from the package registry, execute the following command: To install a box from the package registry, execute the following command:

View file

@ -164,7 +164,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: 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: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -310,7 +310,7 @@ func UploadPackage(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion: case packages_model.ErrDuplicatePackageVersion:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -247,7 +247,7 @@ func UploadPackage(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion: case packages_model.ErrDuplicatePackageVersion:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -415,7 +415,7 @@ func uploadFile(ctx *context.Context, fileFilter container.Set[string], fileKey
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageFile: case packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -189,7 +189,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile: 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: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -363,7 +363,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageFile: case packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -214,7 +214,7 @@ func UploadPackage(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion: case packages_model.ErrDuplicatePackageVersion:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -213,7 +213,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion: case packages_model.ErrDuplicatePackageVersion:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -177,7 +177,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageFile: case packages_model.ErrDuplicatePackageFile:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -258,7 +258,7 @@ func UploadPackageFile(ctx *context.Context) {
if err != nil { if err != nil {
switch err { switch err {
case packages_model.ErrDuplicatePackageVersion: case packages_model.ErrDuplicatePackageVersion:
apiError(ctx, http.StatusBadRequest, err) apiError(ctx, http.StatusConflict, err)
case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize: case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
apiError(ctx, http.StatusForbidden, err) apiError(ctx, http.StatusForbidden, err)
default: default:

View file

@ -322,7 +322,7 @@ nwIDAQAB
assert.Equal(t, fmt.Sprintf("%s.tar.gz", packageVersion), pfs[0].Name) assert.Equal(t, fmt.Sprintf("%s.tar.gz", packageVersion), pfs[0].Name)
assert.True(t, pfs[0].IsLead) assert.True(t, pfs[0].IsLead)
uploadPackage(t, packageVersion, http.StatusBadRequest) uploadPackage(t, packageVersion, http.StatusConflict)
}) })
t.Run("Download", func(t *testing.T) { t.Run("Download", func(t *testing.T) {

View file

@ -112,7 +112,7 @@ func TestPackageComposer(t *testing.T) {
req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content))
req = AddBasicAuthHeader(req, user.Name) req = AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusBadRequest) MakeRequest(t, req, http.StatusConflict)
}) })
}) })

View file

@ -147,7 +147,7 @@ func TestPackageDebian(t *testing.T) {
req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)) req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture))
AddBasicAuthHeader(req, user.Name) AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusBadRequest) MakeRequest(t, req, http.StatusConflict)
}) })
t.Run("Download", func(t *testing.T) { t.Run("Download", func(t *testing.T) {

View file

@ -50,7 +50,7 @@ func TestPackageMaven(t *testing.T) {
defer tests.PrintCurrentTest(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.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) putFile(t, "/maven-metadata.xml", "test", http.StatusOK)
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeMaven) 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) { t.Run("UploadExists", func(t *testing.T) {
defer tests.PrintCurrentTest(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) { t.Run("Download", func(t *testing.T) {

View file

@ -121,7 +121,7 @@ func TestPackageNpm(t *testing.T) {
req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))) req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion)))
req = addTokenAuthHeader(req, token) req = addTokenAuthHeader(req, token)
MakeRequest(t, req, http.StatusBadRequest) MakeRequest(t, req, http.StatusConflict)
}) })
t.Run("Download", func(t *testing.T) { t.Run("Download", func(t *testing.T) {

View file

@ -121,7 +121,7 @@ description: ` + packageDescription
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, int64(len(content)), pb.Size) 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) { t.Run("Download", func(t *testing.T) {

View file

@ -129,8 +129,8 @@ func TestPackagePyPI(t *testing.T) {
t.Run("UploadExists", func(t *testing.T) { t.Run("UploadExists", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
uploadFile(t, "test.whl", content, http.StatusBadRequest) uploadFile(t, "test.whl", content, http.StatusConflict)
uploadFile(t, "test.tar.gz", content, http.StatusBadRequest) uploadFile(t, "test.tar.gz", content, http.StatusConflict)
}) })
t.Run("Download", func(t *testing.T) { t.Run("Download", func(t *testing.T) {

View file

@ -150,7 +150,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`)
t.Run("UploadExists", func(t *testing.T) { t.Run("UploadExists", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
uploadFile(t, http.StatusBadRequest) uploadFile(t, http.StatusConflict)
}) })
t.Run("Download", func(t *testing.T) { t.Run("Download", func(t *testing.T) {