aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api/packages
diff options
context:
space:
mode:
Diffstat (limited to 'routers/api/packages')
-rw-r--r--routers/api/packages/alpine/alpine.go2
-rw-r--r--routers/api/packages/api.go159
-rw-r--r--routers/api/packages/arch/arch.go2
-rw-r--r--routers/api/packages/cargo/cargo.go4
-rw-r--r--routers/api/packages/chef/chef.go6
-rw-r--r--routers/api/packages/composer/composer.go2
-rw-r--r--routers/api/packages/conan/conan.go23
-rw-r--r--routers/api/packages/conan/search.go11
-rw-r--r--routers/api/packages/container/blob.go9
-rw-r--r--routers/api/packages/container/container.go18
-rw-r--r--routers/api/packages/container/manifest.go31
-rw-r--r--routers/api/packages/debian/debian.go2
-rw-r--r--routers/api/packages/generic/generic.go6
-rw-r--r--routers/api/packages/helm/helm.go2
-rw-r--r--routers/api/packages/npm/api.go1
-rw-r--r--routers/api/packages/npm/npm.go10
-rw-r--r--routers/api/packages/nuget/nuget.go10
-rw-r--r--routers/api/packages/pub/pub.go6
-rw-r--r--routers/api/packages/pypi/pypi.go50
-rw-r--r--routers/api/packages/pypi/pypi_test.go10
-rw-r--r--routers/api/packages/rubygems/rubygems.go4
-rw-r--r--routers/api/packages/vagrant/vagrant.go3
22 files changed, 152 insertions, 219 deletions
diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go
index 4b652c9ecc..f35cff3df2 100644
--- a/routers/api/packages/alpine/alpine.go
+++ b/routers/api/packages/alpine/alpine.go
@@ -114,7 +114,7 @@ func UploadPackageFile(ctx *context.Context) {
pck, err := alpine_module.ParsePackage(buf)
if err != nil {
- if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF {
+ if errors.Is(err, util.ErrInvalidArgument) || errors.Is(err, io.EOF) {
apiError(ctx, http.StatusBadRequest, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index 5b035fbb71..41c3eb95e9 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -138,7 +138,8 @@ func CommonRoutes() *web.Router {
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/arch", func() {
r.Methods("HEAD,GET", "/repository.key", arch.GetRepositoryKey)
- r.PathGroup("*", func(g *web.RouterPathGroup) {
+ r.Methods("PUT", "" /* no repository */, reqPackageAccess(perm.AccessModeWrite), arch.UploadPackageFile)
+ r.PathGroup("/*", func(g *web.RouterPathGroup) {
g.MatchPath("PUT", "/<repository:*>", reqPackageAccess(perm.AccessModeWrite), arch.UploadPackageFile)
g.MatchPath("HEAD,GET", "/<repository:*>/<architecture>/<filename>", arch.GetPackageOrRepositoryFile)
g.MatchPath("DELETE", "/<repository:*>/<name>/<version>/<architecture>", reqPackageAccess(perm.AccessModeWrite), arch.DeletePackageVersion)
@@ -698,150 +699,28 @@ func ContainerRoutes() *web.Router {
})
r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList)
r.Group("/{username}", func() {
- r.Group("/{image}", func() {
- r.Group("/blobs/uploads", func() {
- r.Post("", container.InitiateUploadBlob)
- r.Group("/{uuid}", func() {
- r.Get("", container.GetUploadBlob)
- r.Patch("", container.UploadBlob)
- r.Put("", container.EndUploadBlob)
- r.Delete("", container.CancelUploadBlob)
- })
- }, reqPackageAccess(perm.AccessModeWrite))
- r.Group("/blobs/{digest}", func() {
- r.Head("", container.HeadBlob)
- r.Get("", container.GetBlob)
- r.Delete("", reqPackageAccess(perm.AccessModeWrite), container.DeleteBlob)
- })
- r.Group("/manifests/{reference}", func() {
- r.Put("", reqPackageAccess(perm.AccessModeWrite), container.UploadManifest)
- r.Head("", container.HeadManifest)
- r.Get("", container.GetManifest)
- r.Delete("", reqPackageAccess(perm.AccessModeWrite), container.DeleteManifest)
- })
- r.Get("/tags/list", container.GetTagList)
- }, container.VerifyImageName)
-
- var (
- blobsUploadsPattern = regexp.MustCompile(`\A(.+)/blobs/uploads/([a-zA-Z0-9-_.=]+)\z`)
- blobsPattern = regexp.MustCompile(`\A(.+)/blobs/([^/]+)\z`)
- manifestsPattern = regexp.MustCompile(`\A(.+)/manifests/([^/]+)\z`)
- )
-
- // Manual mapping of routes because {image} can contain slashes which chi does not support
- r.Methods("HEAD,GET,POST,PUT,PATCH,DELETE", "/*", func(ctx *context.Context) {
- path := ctx.PathParam("*")
- isHead := ctx.Req.Method == "HEAD"
- isGet := ctx.Req.Method == "GET"
- isPost := ctx.Req.Method == "POST"
- isPut := ctx.Req.Method == "PUT"
- isPatch := ctx.Req.Method == "PATCH"
- isDelete := ctx.Req.Method == "DELETE"
-
- if isPost && strings.HasSuffix(path, "/blobs/uploads") {
- reqPackageAccess(perm.AccessModeWrite)(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.SetPathParam("image", path[:len(path)-14])
- container.VerifyImageName(ctx)
- if ctx.Written() {
- return
- }
-
- container.InitiateUploadBlob(ctx)
- return
- }
- if isGet && strings.HasSuffix(path, "/tags/list") {
- ctx.SetPathParam("image", path[:len(path)-10])
- container.VerifyImageName(ctx)
- if ctx.Written() {
- return
- }
-
- container.GetTagList(ctx)
- return
- }
-
- m := blobsUploadsPattern.FindStringSubmatch(path)
- if len(m) == 3 && (isGet || isPut || isPatch || isDelete) {
- reqPackageAccess(perm.AccessModeWrite)(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.SetPathParam("image", m[1])
- container.VerifyImageName(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.SetPathParam("uuid", m[2])
-
- if isGet {
+ r.PathGroup("/*", func(g *web.RouterPathGroup) {
+ g.MatchPath("POST", "/<image:*>/blobs/uploads", reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, container.InitiateUploadBlob)
+ g.MatchPath("GET", "/<image:*>/tags/list", container.VerifyImageName, container.GetTagList)
+ g.MatchPath("GET,PATCH,PUT,DELETE", `/<image:*>/blobs/uploads/<uuid:[-.=\w]+>`, reqPackageAccess(perm.AccessModeWrite), container.VerifyImageName, func(ctx *context.Context) {
+ if ctx.Req.Method == http.MethodGet {
container.GetUploadBlob(ctx)
- } else if isPatch {
+ } else if ctx.Req.Method == http.MethodPatch {
container.UploadBlob(ctx)
- } else if isPut {
+ } else if ctx.Req.Method == http.MethodPut {
container.EndUploadBlob(ctx)
- } else {
+ } else /* DELETE */ {
container.CancelUploadBlob(ctx)
}
- return
- }
- m = blobsPattern.FindStringSubmatch(path)
- if len(m) == 3 && (isHead || isGet || isDelete) {
- ctx.SetPathParam("image", m[1])
- container.VerifyImageName(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.SetPathParam("digest", m[2])
-
- if isHead {
- container.HeadBlob(ctx)
- } else if isGet {
- container.GetBlob(ctx)
- } else {
- reqPackageAccess(perm.AccessModeWrite)(ctx)
- if ctx.Written() {
- return
- }
- container.DeleteBlob(ctx)
- }
- return
- }
- m = manifestsPattern.FindStringSubmatch(path)
- if len(m) == 3 && (isHead || isGet || isPut || isDelete) {
- ctx.SetPathParam("image", m[1])
- container.VerifyImageName(ctx)
- if ctx.Written() {
- return
- }
-
- ctx.SetPathParam("reference", m[2])
-
- if isHead {
- container.HeadManifest(ctx)
- } else if isGet {
- container.GetManifest(ctx)
- } else {
- reqPackageAccess(perm.AccessModeWrite)(ctx)
- if ctx.Written() {
- return
- }
- if isPut {
- container.UploadManifest(ctx)
- } else {
- container.DeleteManifest(ctx)
- }
- }
- return
- }
-
- ctx.Status(http.StatusNotFound)
+ })
+ g.MatchPath("HEAD", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.HeadBlob)
+ g.MatchPath("GET", `/<image:*>/blobs/<digest>`, container.VerifyImageName, container.GetBlob)
+ g.MatchPath("DELETE", `/<image:*>/blobs/<digest>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.DeleteBlob)
+
+ g.MatchPath("HEAD", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.HeadManifest)
+ g.MatchPath("GET", `/<image:*>/manifests/<reference>`, container.VerifyImageName, container.GetManifest)
+ g.MatchPath("PUT", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.UploadManifest)
+ g.MatchPath("DELETE", `/<image:*>/manifests/<reference>`, container.VerifyImageName, reqPackageAccess(perm.AccessModeWrite), container.DeleteManifest)
})
}, container.ReqContainerAccess, context.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead))
diff --git a/routers/api/packages/arch/arch.go b/routers/api/packages/arch/arch.go
index 573e93cfb0..f5dc6c1d01 100644
--- a/routers/api/packages/arch/arch.go
+++ b/routers/api/packages/arch/arch.go
@@ -62,7 +62,7 @@ func UploadPackageFile(ctx *context.Context) {
pck, err := arch_module.ParsePackage(buf)
if err != nil {
- if errors.Is(err, util.ErrInvalidArgument) || err == io.EOF {
+ if errors.Is(err, util.ErrInvalidArgument) || errors.Is(err, io.EOF) {
apiError(ctx, http.StatusBadRequest, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go
index 3d8407e6b6..42ef13476c 100644
--- a/routers/api/packages/cargo/cargo.go
+++ b/routers/api/packages/cargo/cargo.go
@@ -181,7 +181,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -276,7 +276,7 @@ func UnyankPackage(ctx *context.Context) {
func yankPackage(ctx *context.Context, yank bool) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeCargo, ctx.PathParam("package"), ctx.PathParam("version"))
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go
index b3cdf12697..a0c8c5696c 100644
--- a/routers/api/packages/chef/chef.go
+++ b/routers/api/packages/chef/chef.go
@@ -216,7 +216,7 @@ func PackageVersionMetadata(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -327,7 +327,7 @@ func UploadPackage(ctx *context.Context) {
func DownloadPackage(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeChef, ctx.PathParam("name"), ctx.PathParam("version"))
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -368,7 +368,7 @@ func DeletePackageVersion(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go
index 40f72f6484..c6c14e5cf4 100644
--- a/routers/api/packages/composer/composer.go
+++ b/routers/api/packages/composer/composer.go
@@ -176,7 +176,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go
index 4a9f0a3ffc..8019eee9f7 100644
--- a/routers/api/packages/conan/conan.go
+++ b/routers/api/packages/conan/conan.go
@@ -5,6 +5,7 @@ package conan
import (
std_ctx "context"
+ "errors"
"fmt"
"io"
"net/http"
@@ -183,7 +184,7 @@ func serveSnapshot(ctx *context.Context, fileKey string) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -244,7 +245,7 @@ func serveDownloadURLs(ctx *context.Context, fileKey, downloadURL string) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -493,7 +494,7 @@ func downloadFile(ctx *context.Context, fileFilter container.Set[string], fileKe
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -509,7 +510,7 @@ func DeleteRecipeV1(ctx *context.Context) {
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
if err := deleteRecipeOrPackage(ctx, rref, true, nil, false); err != nil {
- if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -524,7 +525,7 @@ func DeleteRecipeV2(ctx *context.Context) {
rref := ctx.Data[recipeReferenceKey].(*conan_module.RecipeReference)
if err := deleteRecipeOrPackage(ctx, rref, rref.Revision == "", nil, false); err != nil {
- if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -571,7 +572,7 @@ func DeletePackageV1(ctx *context.Context) {
for _, reference := range references {
pref, _ := conan_module.NewPackageReference(currentRref, reference.Value, conan_module.DefaultRevision)
if err := deleteRecipeOrPackage(ctx, currentRref, true, pref, true); err != nil {
- if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -590,7 +591,7 @@ func DeletePackageV2(ctx *context.Context) {
if pref != nil { // has package reference
if err := deleteRecipeOrPackage(ctx, rref, false, pref, pref.Revision == ""); err != nil {
- if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -615,7 +616,7 @@ func DeletePackageV2(ctx *context.Context) {
pref, _ := conan_module.NewPackageReference(rref, reference.Value, conan_module.DefaultRevision)
if err := deleteRecipeOrPackage(ctx, rref, false, pref, true); err != nil {
- if err == packages_model.ErrPackageNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -749,7 +750,7 @@ func LatestRecipeRevision(ctx *context.Context) {
revision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
if err != nil {
- if err == conan_model.ErrRecipeReferenceNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -766,7 +767,7 @@ func LatestPackageRevision(ctx *context.Context) {
revision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref)
if err != nil {
- if err == conan_model.ErrRecipeReferenceNotExist || err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) || errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -796,7 +797,7 @@ func listRevisionFiles(ctx *context.Context, fileKey string) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeConan, rref.Name, rref.Version)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/conan/search.go b/routers/api/packages/conan/search.go
index 7370c702cd..0dbbd500d2 100644
--- a/routers/api/packages/conan/search.go
+++ b/routers/api/packages/conan/search.go
@@ -4,6 +4,7 @@
package conan
import (
+ "errors"
"net/http"
"strings"
@@ -76,7 +77,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) {
if !searchAllRevisions && rref.Revision == "" {
lastRevision, err := conan_model.GetLastRecipeRevision(ctx, ctx.Package.Owner.ID, rref)
if err != nil {
- if err == conan_model.ErrRecipeReferenceNotExist {
+ if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -87,7 +88,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) {
} else {
has, err := conan_model.RecipeExists(ctx, ctx.Package.Owner.ID, rref)
if err != nil {
- if err == conan_model.ErrRecipeReferenceNotExist {
+ if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -119,7 +120,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) {
}
packageReferences, err := conan_model.GetPackageReferences(ctx, ctx.Package.Owner.ID, currentRef)
if err != nil {
- if err == conan_model.ErrRecipeReferenceNotExist {
+ if errors.Is(err, conan_model.ErrRecipeReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -133,7 +134,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) {
pref, _ := conan_module.NewPackageReference(currentRef, packageReference.Value, "")
lastPackageRevision, err := conan_model.GetLastPackageRevision(ctx, ctx.Package.Owner.ID, pref)
if err != nil {
- if err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -143,7 +144,7 @@ func searchPackages(ctx *context.Context, searchAllRevisions bool) {
pref = pref.WithRevision(lastPackageRevision.Value)
infoRaw, err := conan_model.GetPackageInfo(ctx, ctx.Package.Owner.ID, pref)
if err != nil {
- if err == conan_model.ErrPackageReferenceNotExist {
+ if errors.Is(err, conan_model.ErrPackageReferenceNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go
index 4595b9a33d..671803788a 100644
--- a/routers/api/packages/container/blob.go
+++ b/routers/api/packages/container/blob.go
@@ -111,12 +111,11 @@ func getOrCreateUploadVersion(ctx context.Context, pi *packages_service.PackageI
}
var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
- if err == packages_model.ErrDuplicatePackage {
- created = false
- } else {
+ if !errors.Is(err, packages_model.ErrDuplicatePackage) {
log.Error("Error inserting package: %v", err)
return err
}
+ created = false
}
if created {
@@ -135,7 +134,7 @@ func getOrCreateUploadVersion(ctx context.Context, pi *packages_service.PackageI
MetadataJSON: "null",
}
if pv, err = packages_model.GetOrInsertVersion(ctx, pv); err != nil {
- if err != packages_model.ErrDuplicatePackageVersion {
+ if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
log.Error("Error inserting package: %v", err)
return err
}
@@ -161,7 +160,7 @@ func createFileForBlob(ctx context.Context, pv *packages_model.PackageVersion, p
}
var err error
if pf, err = packages_model.TryInsertFile(ctx, pf); err != nil {
- if err == packages_model.ErrDuplicatePackageFile {
+ if errors.Is(err, packages_model.ErrDuplicatePackageFile) {
return nil
}
log.Error("Error inserting package file: %v", err)
diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go
index 3a470ad685..bb14db9db7 100644
--- a/routers/api/packages/container/container.go
+++ b/routers/api/packages/container/container.go
@@ -324,7 +324,7 @@ func GetUploadBlob(ctx *context.Context) {
upload, err := packages_model.GetBlobUploadByID(ctx, uuid)
if err != nil {
- if err == packages_model.ErrPackageBlobUploadNotExist {
+ if errors.Is(err, packages_model.ErrPackageBlobUploadNotExist) {
apiErrorDefined(ctx, errBlobUploadUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -345,7 +345,7 @@ func UploadBlob(ctx *context.Context) {
uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
if err != nil {
- if err == packages_model.ErrPackageBlobUploadNotExist {
+ if errors.Is(err, packages_model.ErrPackageBlobUploadNotExist) {
apiErrorDefined(ctx, errBlobUploadUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -396,7 +396,7 @@ func EndUploadBlob(ctx *context.Context) {
uploader, err := container_service.NewBlobUploader(ctx, ctx.PathParam("uuid"))
if err != nil {
- if err == packages_model.ErrPackageBlobUploadNotExist {
+ if errors.Is(err, packages_model.ErrPackageBlobUploadNotExist) {
apiErrorDefined(ctx, errBlobUploadUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -465,7 +465,7 @@ func CancelUploadBlob(ctx *context.Context) {
_, err := packages_model.GetBlobUploadByID(ctx, uuid)
if err != nil {
- if err == packages_model.ErrPackageBlobUploadNotExist {
+ if errors.Is(err, packages_model.ErrPackageBlobUploadNotExist) {
apiErrorDefined(ctx, errBlobUploadUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -501,7 +501,7 @@ func getBlobFromContext(ctx *context.Context) (*packages_model.PackageFileDescri
func HeadBlob(ctx *context.Context) {
blob, err := getBlobFromContext(ctx)
if err != nil {
- if err == container_model.ErrContainerBlobNotExist {
+ if errors.Is(err, container_model.ErrContainerBlobNotExist) {
apiErrorDefined(ctx, errBlobUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -520,7 +520,7 @@ func HeadBlob(ctx *context.Context) {
func GetBlob(ctx *context.Context) {
blob, err := getBlobFromContext(ctx)
if err != nil {
- if err == container_model.ErrContainerBlobNotExist {
+ if errors.Is(err, container_model.ErrContainerBlobNotExist) {
apiErrorDefined(ctx, errBlobUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -639,7 +639,7 @@ func getManifestFromContext(ctx *context.Context) (*packages_model.PackageFileDe
func HeadManifest(ctx *context.Context) {
manifest, err := getManifestFromContext(ctx)
if err != nil {
- if err == container_model.ErrContainerBlobNotExist {
+ if errors.Is(err, container_model.ErrContainerBlobNotExist) {
apiErrorDefined(ctx, errManifestUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -659,7 +659,7 @@ func HeadManifest(ctx *context.Context) {
func GetManifest(ctx *context.Context) {
manifest, err := getManifestFromContext(ctx)
if err != nil {
- if err == container_model.ErrContainerBlobNotExist {
+ if errors.Is(err, container_model.ErrContainerBlobNotExist) {
apiErrorDefined(ctx, errManifestUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
@@ -739,7 +739,7 @@ func GetTagList(ctx *context.Context) {
image := ctx.PathParam("image")
if _, err := packages_model.GetPackageByName(ctx, ctx.Package.Owner.ID, packages_model.TypeContainer, image); err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiErrorDefined(ctx, errNameUnknown)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go
index 4a79a58f51..ad035cf473 100644
--- a/routers/api/packages/container/manifest.go
+++ b/routers/api/packages/container/manifest.go
@@ -240,7 +240,7 @@ func processImageManifestIndex(ctx context.Context, mci *manifestCreationInfo, b
IsManifest: true,
})
if err != nil {
- if err == container_model.ErrContainerBlobNotExist {
+ if errors.Is(err, container_model.ErrContainerBlobNotExist) {
return errManifestBlobUnknown
}
return err
@@ -321,12 +321,11 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
}
var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
- if err == packages_model.ErrDuplicatePackage {
- created = false
- } else {
+ if !errors.Is(err, packages_model.ErrDuplicatePackage) {
log.Error("Error inserting package: %v", err)
return nil, err
}
+ created = false
}
if created {
@@ -352,21 +351,23 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
}
var pv *packages_model.PackageVersion
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
- if err == packages_model.ErrDuplicatePackageVersion {
- if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
- return nil, err
- }
+ if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
+ log.Error("Error inserting package: %v", err)
+ return nil, err
+ }
- // keep download count on overwrite
- _pv.DownloadCount = pv.DownloadCount
+ if err = packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
+ return nil, err
+ }
+
+ // keep download count on overwrite
+ _pv.DownloadCount = pv.DownloadCount
- if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
+ if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
+ if !errors.Is(err, packages_model.ErrDuplicatePackageVersion) {
log.Error("Error inserting package: %v", err)
return nil, err
}
- } else {
- log.Error("Error inserting package: %v", err)
- return nil, err
}
}
@@ -417,7 +418,7 @@ func createFileFromBlobReference(ctx context.Context, pv, uploadVersion *package
}
var err error
if pf, err = packages_model.TryInsertFile(ctx, pf); err != nil {
- if err == packages_model.ErrDuplicatePackageFile {
+ if errors.Is(err, packages_model.ErrDuplicatePackageFile) {
// Skip this blob because the manifest contains the same filesystem layer multiple times.
return nil
}
diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go
index 162122ccbd..fec34c91a6 100644
--- a/routers/api/packages/debian/debian.go
+++ b/routers/api/packages/debian/debian.go
@@ -68,7 +68,7 @@ func GetRepositoryFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
} else {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go
index 868caf9cf0..0b5daa7334 100644
--- a/routers/api/packages/generic/generic.go
+++ b/routers/api/packages/generic/generic.go
@@ -44,7 +44,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -155,7 +155,7 @@ func DeletePackage(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -182,7 +182,7 @@ func DeletePackageFile(ctx *context.Context) {
return pv, pf, nil
}()
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go
index cb30a20074..fb12daaa46 100644
--- a/routers/api/packages/helm/helm.go
+++ b/routers/api/packages/helm/helm.go
@@ -130,7 +130,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go
index b4379f3f49..636680242a 100644
--- a/routers/api/packages/npm/api.go
+++ b/routers/api/packages/npm/api.go
@@ -67,6 +67,7 @@ func createPackageMetadataVersion(registryURL string, pd *packages_model.Package
BundleDependencies: metadata.BundleDependencies,
DevDependencies: metadata.DevelopmentDependencies,
PeerDependencies: metadata.PeerDependencies,
+ PeerDependenciesMeta: metadata.PeerDependenciesMeta,
OptionalDependencies: metadata.OptionalDependencies,
Readme: metadata.Readme,
Bin: metadata.Bin,
diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go
index 284723e0d7..6ec46bcb36 100644
--- a/routers/api/packages/npm/npm.go
+++ b/routers/api/packages/npm/npm.go
@@ -98,7 +98,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -140,7 +140,7 @@ func DownloadPackageFileByName(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -163,7 +163,7 @@ func UploadPackage(ctx *context.Context) {
return
}
- repo, err := repo_model.GetRepositoryByURL(ctx, npmPackage.Metadata.Repository.URL)
+ repo, err := repo_model.GetRepositoryByURLRelax(ctx, npmPackage.Metadata.Repository.URL)
if err == nil {
canWrite := repo.OwnerID == ctx.Doer.ID
@@ -267,7 +267,7 @@ func DeletePackageVersion(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -341,7 +341,7 @@ func AddPackageTag(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName, version)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go
index 70b95e6a77..07a8de0a68 100644
--- a/routers/api/packages/nuget/nuget.go
+++ b/routers/api/packages/nuget/nuget.go
@@ -259,7 +259,7 @@ func RegistrationLeafV2(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -288,7 +288,7 @@ func RegistrationLeafV3(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -418,7 +418,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -671,7 +671,7 @@ func DownloadSymbolFile(ctx *context.Context) {
s, u, pf, err := packages_service.GetPackageFileStream(ctx, pfs[0])
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -699,7 +699,7 @@ func DeletePackage(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go
index 2be27323fd..e7b07aefd0 100644
--- a/routers/api/packages/pub/pub.go
+++ b/routers/api/packages/pub/pub.go
@@ -124,7 +124,7 @@ func PackageVersionMetadata(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -233,7 +233,7 @@ func FinalizePackage(ctx *context.Context) {
_, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -258,7 +258,7 @@ func DownloadPackageFile(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go
index 5ea86071a9..199f4e7478 100644
--- a/routers/api/packages/pypi/pypi.go
+++ b/routers/api/packages/pypi/pypi.go
@@ -5,11 +5,13 @@ package pypi
import (
"encoding/hex"
+ "errors"
"io"
"net/http"
"regexp"
"sort"
"strings"
+ "unicode"
packages_model "code.gitea.io/gitea/models/packages"
packages_module "code.gitea.io/gitea/modules/packages"
@@ -93,7 +95,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -139,9 +141,30 @@ func UploadPackageFile(ctx *context.Context) {
return
}
- projectURL := ctx.Req.FormValue("home_page")
- if !validation.IsValidURL(projectURL) {
- projectURL = ""
+ // Ensure ctx.Req.Form exists.
+ _ = ctx.Req.ParseForm()
+
+ var homepageURL string
+ projectURLs := ctx.Req.Form["project_urls"]
+ for _, purl := range projectURLs {
+ label, url, found := strings.Cut(purl, ",")
+ if !found {
+ continue
+ }
+ if normalizeLabel(label) != "homepage" {
+ continue
+ }
+ homepageURL = strings.TrimSpace(url)
+ break
+ }
+
+ if len(homepageURL) == 0 {
+ // TODO: Home-page is a deprecated metadata field. Remove this branch once it's no longer apart of the spec.
+ homepageURL = ctx.Req.FormValue("home_page")
+ }
+
+ if !validation.IsValidURL(homepageURL) {
+ homepageURL = ""
}
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
@@ -160,7 +183,7 @@ func UploadPackageFile(ctx *context.Context) {
Description: ctx.Req.FormValue("description"),
LongDescription: ctx.Req.FormValue("long_description"),
Summary: ctx.Req.FormValue("summary"),
- ProjectURL: projectURL,
+ ProjectURL: homepageURL,
License: ctx.Req.FormValue("license"),
RequiresPython: ctx.Req.FormValue("requires_python"),
},
@@ -189,6 +212,23 @@ func UploadPackageFile(ctx *context.Context) {
ctx.Status(http.StatusCreated)
}
+// Normalizes a Project-URL label.
+// See https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+func normalizeLabel(label string) string {
+ var builder strings.Builder
+
+ // "A label is normalized by deleting all ASCII punctuation and whitespace, and then converting the result
+ // to lowercase."
+ for _, r := range label {
+ if unicode.IsPunct(r) || unicode.IsSpace(r) {
+ continue
+ }
+ builder.WriteRune(unicode.ToLower(r))
+ }
+
+ return builder.String()
+}
+
func isValidNameAndVersion(packageName, packageVersion string) bool {
return nameMatcher.MatchString(packageName) && versionMatcher.MatchString(packageVersion)
}
diff --git a/routers/api/packages/pypi/pypi_test.go b/routers/api/packages/pypi/pypi_test.go
index 3023692177..786105693f 100644
--- a/routers/api/packages/pypi/pypi_test.go
+++ b/routers/api/packages/pypi/pypi_test.go
@@ -36,3 +36,13 @@ func TestIsValidNameAndVersion(t *testing.T) {
assert.False(t, isValidNameAndVersion("test-name", "1.0.1aa"))
assert.False(t, isValidNameAndVersion("test-name", "1.0.0-alpha.beta"))
}
+
+func TestNormalizeLabel(t *testing.T) {
+ // Cases fetched from https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+ assert.Equal(t, "homepage", normalizeLabel("Homepage"))
+ assert.Equal(t, "homepage", normalizeLabel("Home-page"))
+ assert.Equal(t, "homepage", normalizeLabel("Home page"))
+ assert.Equal(t, "changelog", normalizeLabel("Change_Log"))
+ assert.Equal(t, "whatsnew", normalizeLabel("What's New?"))
+ assert.Equal(t, "github", normalizeLabel("github"))
+}
diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go
index 958063e70a..de8c7ef3ed 100644
--- a/routers/api/packages/rubygems/rubygems.go
+++ b/routers/api/packages/rubygems/rubygems.go
@@ -185,7 +185,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
@@ -288,7 +288,7 @@ func DeletePackage(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}
diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go
index 1daf2a0527..3afaa5de1f 100644
--- a/routers/api/packages/vagrant/vagrant.go
+++ b/routers/api/packages/vagrant/vagrant.go
@@ -4,6 +4,7 @@
package vagrant
import (
+ "errors"
"fmt"
"io"
"net/http"
@@ -230,7 +231,7 @@ func DownloadPackageFile(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ if errors.Is(err, packages_model.ErrPackageNotExist) || errors.Is(err, packages_model.ErrPackageFileNotExist) {
apiError(ctx, http.StatusNotFound, err)
return
}