2026-03-14 10:03:29 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
|
|
|
|
|
|
package api
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"encoding/hex"
|
|
|
|
|
"net/http"
|
feat: AX v0.8.0 — Core primitives, Result returns, zero disallowed imports
- api.go: errors.Is → core.Is
- openapi.go: Build returns core.Result, encoding/json → core.JSONMarshal
- export.go: rewrite with core.Fs, core.JSONUnmarshal, returns core.Result
- codegen.go: rewrite with c.Process(), core.Fs, App.Find — no os/exec
- sse.go: encoding/json → core.JSONMarshalString, fmt → core.Sprintf
- swagger.go: fmt → core.Sprintf, Build caller updated for core.Result
- middleware.go: strings → core.HasPrefix/SplitN/Lower
- authentik.go: strings → core.HasPrefix/TrimPrefix/Split/Trim/Contains
- brotli.go: strings → core.Contains
Transport boundary files (net/http, io for compression) retained.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 08:39:59 +00:00
|
|
|
core "dappco.re/go/core"
|
2026-03-14 10:03:29 +00:00
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// bearerAuthMiddleware validates the Authorization: Bearer <token> header.
|
|
|
|
|
// Requests to paths in the skip list are allowed through without authentication.
|
|
|
|
|
// Returns 401 with Fail("unauthorised", ...) on missing or invalid tokens.
|
|
|
|
|
func bearerAuthMiddleware(token string, skip []string) gin.HandlerFunc {
|
|
|
|
|
return func(c *gin.Context) {
|
|
|
|
|
// Check whether the request path should bypass authentication.
|
|
|
|
|
for _, path := range skip {
|
feat: AX v0.8.0 — Core primitives, Result returns, zero disallowed imports
- api.go: errors.Is → core.Is
- openapi.go: Build returns core.Result, encoding/json → core.JSONMarshal
- export.go: rewrite with core.Fs, core.JSONUnmarshal, returns core.Result
- codegen.go: rewrite with c.Process(), core.Fs, App.Find — no os/exec
- sse.go: encoding/json → core.JSONMarshalString, fmt → core.Sprintf
- swagger.go: fmt → core.Sprintf, Build caller updated for core.Result
- middleware.go: strings → core.HasPrefix/SplitN/Lower
- authentik.go: strings → core.HasPrefix/TrimPrefix/Split/Trim/Contains
- brotli.go: strings → core.Contains
Transport boundary files (net/http, io for compression) retained.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 08:39:59 +00:00
|
|
|
if core.HasPrefix(c.Request.URL.Path, path) {
|
2026-03-14 10:03:29 +00:00
|
|
|
c.Next()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
header := c.GetHeader("Authorization")
|
|
|
|
|
if header == "" {
|
|
|
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, Fail("unauthorised", "missing authorization header"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
feat: AX v0.8.0 — Core primitives, Result returns, zero disallowed imports
- api.go: errors.Is → core.Is
- openapi.go: Build returns core.Result, encoding/json → core.JSONMarshal
- export.go: rewrite with core.Fs, core.JSONUnmarshal, returns core.Result
- codegen.go: rewrite with c.Process(), core.Fs, App.Find — no os/exec
- sse.go: encoding/json → core.JSONMarshalString, fmt → core.Sprintf
- swagger.go: fmt → core.Sprintf, Build caller updated for core.Result
- middleware.go: strings → core.HasPrefix/SplitN/Lower
- authentik.go: strings → core.HasPrefix/TrimPrefix/Split/Trim/Contains
- brotli.go: strings → core.Contains
Transport boundary files (net/http, io for compression) retained.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 08:39:59 +00:00
|
|
|
parts := core.SplitN(header, " ", 2)
|
|
|
|
|
if len(parts) != 2 || core.Lower(parts[0]) != "bearer" || parts[1] != token {
|
2026-03-14 10:03:29 +00:00
|
|
|
c.AbortWithStatusJSON(http.StatusUnauthorized, Fail("unauthorised", "invalid bearer token"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.Next()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// requestIDMiddleware ensures every response carries an X-Request-ID header.
|
|
|
|
|
// If the client sends one, it is preserved; otherwise a random 16-byte hex
|
|
|
|
|
// string is generated. The ID is also stored in the Gin context as "request_id".
|
|
|
|
|
func requestIDMiddleware() gin.HandlerFunc {
|
|
|
|
|
return func(c *gin.Context) {
|
|
|
|
|
id := c.GetHeader("X-Request-ID")
|
|
|
|
|
if id == "" {
|
|
|
|
|
b := make([]byte, 16)
|
|
|
|
|
_, _ = rand.Read(b)
|
|
|
|
|
id = hex.EncodeToString(b)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.Set("request_id", id)
|
|
|
|
|
c.Header("X-Request-ID", id)
|
|
|
|
|
c.Next()
|
|
|
|
|
}
|
|
|
|
|
}
|