mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Backport of #32693 Fix #32683 This PR adds the login endpoint and fixes the documentation links.
This commit is contained in:
		@@ -608,40 +608,46 @@ func CommonRoutes() *web.Route {
 | 
				
			|||||||
			}, reqPackageAccess(perm.AccessModeWrite))
 | 
								}, reqPackageAccess(perm.AccessModeWrite))
 | 
				
			||||||
		}, reqPackageAccess(perm.AccessModeRead))
 | 
							}, reqPackageAccess(perm.AccessModeRead))
 | 
				
			||||||
		r.Group("/swift", func() {
 | 
							r.Group("/swift", func() {
 | 
				
			||||||
			r.Group("/{scope}/{name}", func() {
 | 
								r.Group("", func() { // Needs to be unauthenticated.
 | 
				
			||||||
				r.Group("", func() {
 | 
									r.Post("", swift.CheckAuthenticate)
 | 
				
			||||||
					r.Get("", swift.EnumeratePackageVersions)
 | 
									r.Post("/login", swift.CheckAuthenticate)
 | 
				
			||||||
					r.Get(".json", swift.EnumeratePackageVersions)
 | 
								})
 | 
				
			||||||
				}, swift.CheckAcceptMediaType(swift.AcceptJSON))
 | 
								r.Group("", func() {
 | 
				
			||||||
				r.Group("/{version}", func() {
 | 
									r.Group("/{scope}/{name}", func() {
 | 
				
			||||||
					r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest)
 | 
										r.Group("", func() {
 | 
				
			||||||
					r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile)
 | 
											r.Get("", swift.EnumeratePackageVersions)
 | 
				
			||||||
					r.Get("", func(ctx *context.Context) {
 | 
											r.Get(".json", swift.EnumeratePackageVersions)
 | 
				
			||||||
						// Can't use normal routes here: https://github.com/go-chi/chi/issues/781
 | 
										}, 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.Params("version")
 | 
												version := ctx.Params("version")
 | 
				
			||||||
						if strings.HasSuffix(version, ".zip") {
 | 
												if strings.HasSuffix(version, ".zip") {
 | 
				
			||||||
							swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
 | 
													swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
 | 
				
			||||||
							if ctx.Written() {
 | 
													if ctx.Written() {
 | 
				
			||||||
								return
 | 
														return
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													ctx.SetParams("version", version[:len(version)-4])
 | 
				
			||||||
 | 
													swift.DownloadPackageFile(ctx)
 | 
				
			||||||
 | 
												} else {
 | 
				
			||||||
 | 
													swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
 | 
				
			||||||
 | 
													if ctx.Written() {
 | 
				
			||||||
 | 
														return
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													if strings.HasSuffix(version, ".json") {
 | 
				
			||||||
 | 
														ctx.SetParams("version", version[:len(version)-5])
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													swift.PackageVersionMetadata(ctx)
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							ctx.SetParams("version", version[:len(version)-4])
 | 
											})
 | 
				
			||||||
							swift.DownloadPackageFile(ctx)
 | 
					 | 
				
			||||||
						} else {
 | 
					 | 
				
			||||||
							swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
 | 
					 | 
				
			||||||
							if ctx.Written() {
 | 
					 | 
				
			||||||
								return
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							if strings.HasSuffix(version, ".json") {
 | 
					 | 
				
			||||||
								ctx.SetParams("version", version[:len(version)-5])
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
							swift.PackageVersionMetadata(ctx)
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					})
 | 
										})
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
			})
 | 
									r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers)
 | 
				
			||||||
			r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers)
 | 
								}, reqPackageAccess(perm.AccessModeRead))
 | 
				
			||||||
		}, reqPackageAccess(perm.AccessModeRead))
 | 
							})
 | 
				
			||||||
		r.Group("/vagrant", func() {
 | 
							r.Group("/vagrant", func() {
 | 
				
			||||||
			r.Group("/authenticate", func() {
 | 
								r.Group("/authenticate", func() {
 | 
				
			||||||
				r.Get("", vagrant.CheckAuthenticate)
 | 
									r.Get("", vagrant.CheckAuthenticate)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ import (
 | 
				
			|||||||
	"github.com/hashicorp/go-version"
 | 
						"github.com/hashicorp/go-version"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning
 | 
					// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	AcceptJSON  = "application/vnd.swift.registry.v1+json"
 | 
						AcceptJSON  = "application/vnd.swift.registry.v1+json"
 | 
				
			||||||
	AcceptSwift = "application/vnd.swift.registry.v1+swift"
 | 
						AcceptSwift = "application/vnd.swift.registry.v1+swift"
 | 
				
			||||||
@@ -35,9 +35,9 @@ const (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// https://github.com/apple/swift-package-manager/blob/main/Documentation/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`)
 | 
						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/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`)
 | 
						namePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-_]{0,99}\z`)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,7 +49,7 @@ type headers struct {
 | 
				
			|||||||
	Link        string
 | 
						Link        string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/apple/swift-package-manager/blob/main/Documentation/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) {
 | 
					func setResponseHeaders(resp http.ResponseWriter, h *headers) {
 | 
				
			||||||
	if h.ContentType != "" {
 | 
						if h.ContentType != "" {
 | 
				
			||||||
		resp.Header().Set("Content-Type", 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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling
 | 
				
			||||||
func apiError(ctx *context.Context, status int, obj any) {
 | 
					func apiError(ctx *context.Context, status int, obj any) {
 | 
				
			||||||
	// https://www.rfc-editor.org/rfc/rfc7807
 | 
						// https://www.rfc-editor.org/rfc/rfc7807
 | 
				
			||||||
	type Problem struct {
 | 
						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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning
 | 
				
			||||||
func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) {
 | 
					func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) {
 | 
				
			||||||
	return func(ctx *context.Context) {
 | 
						return func(ctx *context.Context) {
 | 
				
			||||||
		accept := ctx.Req.Header.Get("Accept")
 | 
							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 {
 | 
					func buildPackageID(scope, name string) string {
 | 
				
			||||||
	return scope + "." + name
 | 
						return scope + "." + name
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -113,7 +123,7 @@ type EnumeratePackageVersionsResponse struct {
 | 
				
			|||||||
	Releases map[string]Release `json:"releases"`
 | 
						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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases
 | 
				
			||||||
func EnumeratePackageVersions(ctx *context.Context) {
 | 
					func EnumeratePackageVersions(ctx *context.Context) {
 | 
				
			||||||
	packageScope := ctx.Params("scope")
 | 
						packageScope := ctx.Params("scope")
 | 
				
			||||||
	packageName := ctx.Params("name")
 | 
						packageName := ctx.Params("name")
 | 
				
			||||||
@@ -170,7 +180,7 @@ type PackageVersionMetadataResponse struct {
 | 
				
			|||||||
	Metadata  *swift_module.SoftwareSourceCode `json:"metadata"`
 | 
						Metadata  *swift_module.SoftwareSourceCode `json:"metadata"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-2
 | 
					// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2
 | 
				
			||||||
func PackageVersionMetadata(ctx *context.Context) {
 | 
					func PackageVersionMetadata(ctx *context.Context) {
 | 
				
			||||||
	id := buildPackageID(ctx.Params("scope"), ctx.Params("name"))
 | 
						id := buildPackageID(ctx.Params("scope"), ctx.Params("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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release
 | 
				
			||||||
func DownloadManifest(ctx *context.Context) {
 | 
					func DownloadManifest(ctx *context.Context) {
 | 
				
			||||||
	packageScope := ctx.Params("scope")
 | 
						packageScope := ctx.Params("scope")
 | 
				
			||||||
	packageName := ctx.Params("name")
 | 
						packageName := ctx.Params("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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6
 | 
				
			||||||
func UploadPackageFile(ctx *context.Context) {
 | 
					func UploadPackageFile(ctx *context.Context) {
 | 
				
			||||||
	packageScope := ctx.Params("scope")
 | 
						packageScope := ctx.Params("scope")
 | 
				
			||||||
	packageName := ctx.Params("name")
 | 
						packageName := ctx.Params("name")
 | 
				
			||||||
@@ -379,7 +389,7 @@ func UploadPackageFile(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Status(http.StatusCreated)
 | 
						ctx.Status(http.StatusCreated)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-4
 | 
					// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4
 | 
				
			||||||
func DownloadPackageFile(ctx *context.Context) {
 | 
					func DownloadPackageFile(ctx *context.Context) {
 | 
				
			||||||
	pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.Params("scope"), ctx.Params("name")), ctx.Params("version"))
 | 
						pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.Params("scope"), ctx.Params("name")), ctx.Params("version"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -420,7 +430,7 @@ type LookupPackageIdentifiersResponse struct {
 | 
				
			|||||||
	Identifiers []string `json:"identifiers"`
 | 
						Identifiers []string `json:"identifiers"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-5
 | 
					// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5
 | 
				
			||||||
func LookupPackageIdentifiers(ctx *context.Context) {
 | 
					func LookupPackageIdentifiers(ctx *context.Context) {
 | 
				
			||||||
	url := ctx.FormTrim("url")
 | 
						url := ctx.FormTrim("url")
 | 
				
			||||||
	if url == "" {
 | 
						if url == "" {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,24 @@ func TestPackageSwift(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	url := fmt.Sprintf("/api/packages/%s/swift", user.Name)
 | 
						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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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) {
 | 
						t.Run("CheckAcceptMediaType", func(t *testing.T) {
 | 
				
			||||||
		defer tests.PrintCurrentTest(t)()
 | 
							defer tests.PrintCurrentTest(t)()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user