83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
echojwt "github.com/labstack/echo-jwt/v4"
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/labstack/echo/v4/middleware"
|
|
"gitlab.com/texm/shokku/internal/env"
|
|
|
|
"gitlab.com/texm/shokku/internal/server/auth"
|
|
)
|
|
|
|
const (
|
|
tokenContextKey = "user-token"
|
|
usedCookieAuthContextKey = "cookie-auth"
|
|
)
|
|
|
|
func skipDuringSetup(e *env.Env, c echo.Context) bool {
|
|
reqPath := c.Request().URL.Path
|
|
return !e.SetupCompleted && strings.HasPrefix(reqPath, "/api/setup")
|
|
}
|
|
|
|
func ProvideUserContext(e *env.Env) echo.MiddlewareFunc {
|
|
logger := middlewareLogger("userContext")
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
return func(c echo.Context) error {
|
|
if skipDuringSetup(e, c) {
|
|
return next(c)
|
|
}
|
|
|
|
if err := e.Auth.SetUserContext(c, tokenContextKey); err != nil {
|
|
logger.Error().Err(err).Msg("failed to set context")
|
|
return echo.ErrInternalServerError
|
|
}
|
|
return next(c)
|
|
}
|
|
}
|
|
}
|
|
|
|
func tokenAuthSkipper(e *env.Env) middleware.Skipper {
|
|
return func(c echo.Context) bool {
|
|
return skipDuringSetup(e, c)
|
|
}
|
|
}
|
|
|
|
func TokenAuth(e *env.Env) echo.MiddlewareFunc {
|
|
config := echojwt.WithConfig(echojwt.Config{
|
|
NewClaimsFunc: func(c echo.Context) jwt.Claims {
|
|
// &auth.User{}
|
|
return jwt.MapClaims{}
|
|
},
|
|
SigningKey: e.Auth.GetSigningKey(),
|
|
TokenLookupFuncs: []middleware.ValuesExtractor{SplitTokenLookup},
|
|
TokenLookup: "header:Authorization",
|
|
ContextKey: tokenContextKey,
|
|
Skipper: tokenAuthSkipper(e),
|
|
})
|
|
return config
|
|
}
|
|
|
|
func SplitTokenLookup(c echo.Context) ([]string, error) {
|
|
dataCookie, err := c.Request().Cookie(auth.DataCookieName)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("no data cookie: %w", err)
|
|
}
|
|
signatureCookie, err := c.Request().Cookie(auth.SignatureCookieName)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("no signature cookie: %w", err)
|
|
}
|
|
|
|
c.Set(usedCookieAuthContextKey, true)
|
|
authToken := dataCookie.Value + "." + signatureCookie.Value
|
|
return []string{authToken}, nil
|
|
}
|
|
|
|
func CheckCookieAuthUsed(c echo.Context) bool {
|
|
v, ok := c.Get(usedCookieAuthContextKey).(bool)
|
|
return ok && v
|
|
}
|