From b26d471fa7eaa804ad238f114699d9630ff35a3f Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Mon, 2 Dec 2024 20:30:18 +0000 Subject: [PATCH 1/3] Add login endpoint. Fix documentation links. --- routers/api/packages/api.go | 65 ++++++++++---------- routers/api/packages/swift/swift.go | 34 ++++++---- tests/integration/api_packages_swift_test.go | 11 ++++ 3 files changed, 67 insertions(+), 43 deletions(-) diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index d17e4875b13a7..f288a36e6784d 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -610,40 +610,43 @@ func CommonRoutes() *web.Router { }, reqPackageAccess(perm.AccessModeWrite)) }, reqPackageAccess(perm.AccessModeRead)) r.Group("/swift", func() { - r.Group("/{scope}/{name}", func() { - r.Group("", func() { - r.Get("", swift.EnumeratePackageVersions) - r.Get(".json", swift.EnumeratePackageVersions) - }, swift.CheckAcceptMediaType(swift.AcceptJSON)) - r.Group("/{version}", func() { - r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest) - r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile) - r.Get("", func(ctx *context.Context) { - // Can't use normal routes here: https://github.com/go-chi/chi/issues/781 - - version := ctx.PathParam("version") - if strings.HasSuffix(version, ".zip") { - swift.CheckAcceptMediaType(swift.AcceptZip)(ctx) - if ctx.Written() { - return - } - ctx.SetPathParam("version", version[:len(version)-4]) - swift.DownloadPackageFile(ctx) - } else { - swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx) - if ctx.Written() { - return - } - if strings.HasSuffix(version, ".json") { - ctx.SetPathParam("version", version[:len(version)-5]) + r.Post("", swift.CheckAuthenticate) // Needs to be unauthenticated. + r.Group("", func() { + r.Group("/{scope}/{name}", func() { + r.Group("", func() { + r.Get("", swift.EnumeratePackageVersions) + r.Get(".json", swift.EnumeratePackageVersions) + }, swift.CheckAcceptMediaType(swift.AcceptJSON)) + r.Group("/{version}", func() { + r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest) + r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile) + r.Get("", func(ctx *context.Context) { + // Can't use normal routes here: https://github.com/go-chi/chi/issues/781 + + version := ctx.PathParam("version") + if strings.HasSuffix(version, ".zip") { + swift.CheckAcceptMediaType(swift.AcceptZip)(ctx) + if ctx.Written() { + return + } + ctx.SetPathParam("version", version[:len(version)-4]) + swift.DownloadPackageFile(ctx) + } else { + swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx) + if ctx.Written() { + return + } + if strings.HasSuffix(version, ".json") { + ctx.SetPathParam("version", version[:len(version)-5]) + } + swift.PackageVersionMetadata(ctx) } - swift.PackageVersionMetadata(ctx) - } + }) }) }) - }) - r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers) - }, reqPackageAccess(perm.AccessModeRead)) + r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers) + }, reqPackageAccess(perm.AccessModeRead)) + }) r.Group("/vagrant", func() { r.Group("/authenticate", func() { r.Get("", vagrant.CheckAuthenticate) diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index d5d4d4e9d134c..1c033b4b79fd6 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -27,7 +27,7 @@ import ( "github.com/hashicorp/go-version" ) -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning const ( AcceptJSON = "application/vnd.swift.registry.v1+json" AcceptSwift = "application/vnd.swift.registry.v1+swift" @@ -35,9 +35,9 @@ const ( ) var ( - // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#361-package-scope + // https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#361-package-scope scopePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-]{0,38}\z`) - // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#362-package-name + // https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#362-package-name namePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-_]{0,99}\z`) ) @@ -49,7 +49,7 @@ type headers struct { Link string } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func setResponseHeaders(resp http.ResponseWriter, h *headers) { if h.ContentType != "" { resp.Header().Set("Content-Type", h.ContentType) @@ -69,7 +69,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) { } } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#33-error-handling +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling func apiError(ctx *context.Context, status int, obj any) { // https://www.rfc-editor.org/rfc/rfc7807 type Problem struct { @@ -91,7 +91,7 @@ func apiError(ctx *context.Context, status int, obj any) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) { return func(ctx *context.Context) { accept := ctx.Req.Header.Get("Accept") @@ -101,6 +101,16 @@ func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context } } +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/PackageRegistryUsage.md#registry-authentication +func CheckAuthenticate(ctx *context.Context) { + if ctx.Doer == nil { + apiError(ctx, http.StatusUnauthorized, nil) + return + } + + ctx.Status(http.StatusOK) +} + func buildPackageID(scope, name string) string { return scope + "." + name } @@ -113,7 +123,7 @@ type EnumeratePackageVersionsResponse struct { Releases map[string]Release `json:"releases"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#41-list-package-releases +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases func EnumeratePackageVersions(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -170,7 +180,7 @@ type PackageVersionMetadataResponse struct { Metadata *swift_module.SoftwareSourceCode `json:"metadata"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-2 +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2 func PackageVersionMetadata(ctx *context.Context) { id := buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")) @@ -228,7 +238,7 @@ func PackageVersionMetadata(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#43-fetch-manifest-for-a-package-release +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release func DownloadManifest(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -280,7 +290,7 @@ func DownloadManifest(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-6 +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6 func UploadPackageFile(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -379,7 +389,7 @@ func UploadPackageFile(ctx *context.Context) { ctx.Status(http.StatusCreated) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-4 +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4 func DownloadPackageFile(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")), ctx.PathParam("version")) if err != nil { @@ -420,7 +430,7 @@ type LookupPackageIdentifiersResponse struct { Identifiers []string `json:"identifiers"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-5 +// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5 func LookupPackageIdentifiers(ctx *context.Context) { url := ctx.FormTrim("url") if url == "" { diff --git a/tests/integration/api_packages_swift_test.go b/tests/integration/api_packages_swift_test.go index 7d4ff954e2274..33f4bf5fbec48 100644 --- a/tests/integration/api_packages_swift_test.go +++ b/tests/integration/api_packages_swift_test.go @@ -42,6 +42,17 @@ func TestPackageSwift(t *testing.T) { url := fmt.Sprintf("/api/packages/%s/swift", user.Name) + t.Run("CheckLogin", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + req := NewRequestWithBody(t, "POST", url, strings.NewReader("")) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequestWithBody(t, "POST", url, strings.NewReader("")). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusOK) + }) + t.Run("CheckAcceptMediaType", func(t *testing.T) { defer tests.PrintCurrentTest(t)() From 5c367d20d2e57c8d8247edfde704b7e6f4827c67 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Mon, 2 Dec 2024 20:51:13 +0000 Subject: [PATCH 2/3] Add /login endpoint. --- routers/api/packages/api.go | 5 ++++- tests/integration/api_packages_swift_test.go | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index f288a36e6784d..c3da5a7513bc3 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -610,7 +610,10 @@ func CommonRoutes() *web.Router { }, reqPackageAccess(perm.AccessModeWrite)) }, reqPackageAccess(perm.AccessModeRead)) r.Group("/swift", func() { - r.Post("", swift.CheckAuthenticate) // Needs to be unauthenticated. + r.Group("", func() { // Needs to be unauthenticated. + r.Post("", swift.CheckAuthenticate) + r.Post("/login", swift.CheckAuthenticate) + }) r.Group("", func() { r.Group("/{scope}/{name}", func() { r.Group("", func() { diff --git a/tests/integration/api_packages_swift_test.go b/tests/integration/api_packages_swift_test.go index 33f4bf5fbec48..c0e0dccfab11b 100644 --- a/tests/integration/api_packages_swift_test.go +++ b/tests/integration/api_packages_swift_test.go @@ -51,6 +51,13 @@ func TestPackageSwift(t *testing.T) { req = NewRequestWithBody(t, "POST", url, strings.NewReader("")). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) + + req = NewRequestWithBody(t, "POST", url+"/login", strings.NewReader("")) + MakeRequest(t, req, http.StatusUnauthorized) + + req = NewRequestWithBody(t, "POST", url+"/login", strings.NewReader("")). + AddBasicAuth(user.Name) + MakeRequest(t, req, http.StatusOK) }) t.Run("CheckAcceptMediaType", func(t *testing.T) { From 806b42dfe4749aca2ae199bbca5bc97383bf7f3b Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 3 Dec 2024 15:43:00 +0100 Subject: [PATCH 3/3] Use redirected url. --- routers/api/packages/swift/swift.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index 1c033b4b79fd6..4d7fb8b1a6992 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -27,7 +27,7 @@ import ( "github.com/hashicorp/go-version" ) -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning const ( AcceptJSON = "application/vnd.swift.registry.v1+json" AcceptSwift = "application/vnd.swift.registry.v1+swift" @@ -35,9 +35,9 @@ const ( ) var ( - // https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#361-package-scope + // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#361-package-scope scopePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-]{0,38}\z`) - // https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#362-package-name + // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#362-package-name namePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-_]{0,99}\z`) ) @@ -49,7 +49,7 @@ type headers struct { Link string } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func setResponseHeaders(resp http.ResponseWriter, h *headers) { if h.ContentType != "" { resp.Header().Set("Content-Type", h.ContentType) @@ -69,7 +69,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) { } } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling func apiError(ctx *context.Context, status int, obj any) { // https://www.rfc-editor.org/rfc/rfc7807 type Problem struct { @@ -91,7 +91,7 @@ func apiError(ctx *context.Context, status int, obj any) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) { return func(ctx *context.Context) { accept := ctx.Req.Header.Get("Accept") @@ -123,7 +123,7 @@ type EnumeratePackageVersionsResponse struct { Releases map[string]Release `json:"releases"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases func EnumeratePackageVersions(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -180,7 +180,7 @@ type PackageVersionMetadataResponse struct { Metadata *swift_module.SoftwareSourceCode `json:"metadata"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2 func PackageVersionMetadata(ctx *context.Context) { id := buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")) @@ -238,7 +238,7 @@ func PackageVersionMetadata(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release func DownloadManifest(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -290,7 +290,7 @@ func DownloadManifest(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6 func UploadPackageFile(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -389,7 +389,7 @@ func UploadPackageFile(ctx *context.Context) { ctx.Status(http.StatusCreated) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4 func DownloadPackageFile(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")), ctx.PathParam("version")) if err != nil { @@ -430,7 +430,7 @@ type LookupPackageIdentifiersResponse struct { Identifiers []string `json:"identifiers"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5 func LookupPackageIdentifiers(ctx *context.Context) { url := ctx.FormTrim("url") if url == "" {