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>
forgejo-federated-star
Nanguan Lin 9 months ago committed by GitHub
parent 2c7b6c378e
commit 5b6258a0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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.

@ -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

@ -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

@ -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:

@ -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:

@ -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

@ -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 |

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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:

@ -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) {

@ -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)
}) })
}) })

@ -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) {

@ -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) {

@ -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) {

@ -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) {

@ -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) {

@ -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) {

Loading…
Cancel
Save