Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Oct 10, 2023
Merged
1 change: 1 addition & 0 deletions docs/content/usage/packages/alpine.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 3 additions & 1 deletion docs/content/usage/packages/composer.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

```
Expand Down Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions docs/content/usage/packages/conan.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions docs/content/usage/packages/conda.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 10 additions & 0 deletions docs/content/usage/packages/cran.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 3 additions & 2 deletions docs/content/usage/packages/debian.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions docs/content/usage/packages/go.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
8 changes: 8 additions & 0 deletions docs/content/usage/packages/swift.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 10 additions & 0 deletions docs/content/usage/packages/vagrant.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/alpine/alpine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/chef/chef.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/composer/composer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/conan/conan.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/debian/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/maven/maven.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/npm/npm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/pub/pub.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/pypi/pypi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion routers/api/packages/rubygems/rubygems.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_chef_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_composer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
})

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_debian_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/api_packages_maven_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_npm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_pub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions tests/integration/api_packages_pypi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/api_packages_rubygems_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down