mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01:00 
			
		
		
		
	Add Swift login endpoint (#32693)
Fix #32683 This PR adds the login endpoint and fixes the documentation links.
This commit is contained in:
		@@ -610,6 +610,11 @@ func CommonRoutes() *web.Router {
 | 
				
			|||||||
			}, reqPackageAccess(perm.AccessModeWrite))
 | 
								}, reqPackageAccess(perm.AccessModeWrite))
 | 
				
			||||||
		}, reqPackageAccess(perm.AccessModeRead))
 | 
							}, reqPackageAccess(perm.AccessModeRead))
 | 
				
			||||||
		r.Group("/swift", func() {
 | 
							r.Group("/swift", func() {
 | 
				
			||||||
 | 
								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("/{scope}/{name}", func() {
 | 
				
			||||||
					r.Group("", func() {
 | 
										r.Group("", func() {
 | 
				
			||||||
						r.Get("", swift.EnumeratePackageVersions)
 | 
											r.Get("", swift.EnumeratePackageVersions)
 | 
				
			||||||
@@ -644,6 +649,7 @@ func CommonRoutes() *web.Router {
 | 
				
			|||||||
				})
 | 
									})
 | 
				
			||||||
				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.PathParam("scope")
 | 
						packageScope := ctx.PathParam("scope")
 | 
				
			||||||
	packageName := ctx.PathParam("name")
 | 
						packageName := ctx.PathParam("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.PathParam("scope"), ctx.PathParam("name"))
 | 
						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/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.PathParam("scope")
 | 
						packageScope := ctx.PathParam("scope")
 | 
				
			||||||
	packageName := ctx.PathParam("name")
 | 
						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/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6
 | 
				
			||||||
func UploadPackageFile(ctx *context.Context) {
 | 
					func UploadPackageFile(ctx *context.Context) {
 | 
				
			||||||
	packageScope := ctx.PathParam("scope")
 | 
						packageScope := ctx.PathParam("scope")
 | 
				
			||||||
	packageName := ctx.PathParam("name")
 | 
						packageName := ctx.PathParam("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.PathParam("scope"), ctx.PathParam("name")), ctx.PathParam("version"))
 | 
						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 {
 | 
						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