feature (template): enhance templating functions

This commit is contained in:
MickaelK 2025-02-13 15:56:24 +11:00
parent 00eed6e922
commit 2c1edd85e9

View file

@ -1,12 +1,18 @@
package ctrl package ctrl
import ( import (
"crypto/rsa"
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt"
"math/big"
"regexp" "regexp"
"strings" "strings"
"text/template" "text/template"
. "github.com/mickael-kerjean/filestash/server/common" . "github.com/mickael-kerjean/filestash/server/common"
"github.com/golang-jwt/jwt/v4"
) )
var tmplFuncs = template.FuncMap{ var tmplFuncs = template.FuncMap{
@ -113,4 +119,66 @@ var tmplFuncs = template.FuncMap{
data, err := EncryptAESGCM([]byte(key), []byte(str)) data, err := EncryptAESGCM([]byte(key), []byte(str))
return base64.StdEncoding.EncodeToString(data), err return base64.StdEncoding.EncodeToString(data), err
}, },
"jwt": func(args ...string) (string, error) {
if len(args) == 0 {
return "", ErrNotValid
}
var stdin = args[len(args)-1]
var token *jwt.Token
var err error
claims := jwt.MapClaims{}
if len(args) == 1 {
token, _, err = jwt.NewParser().ParseUnverified(stdin, claims)
token.Valid = true
} else if len(args) == 2 {
token, err = jwt.ParseWithClaims(stdin, claims, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); ok {
return []byte(args[0]), nil
} else if _, ok := token.Method.(*jwt.SigningMethodRSA); ok {
modBytes, err := base64.RawURLEncoding.DecodeString(args[0])
if err != nil {
return "", err
}
return &rsa.PublicKey{
N: new(big.Int).SetBytes(modBytes),
E: 65537,
}, nil
}
Log.Debug("ctrl::tmpl invalid jwt signing method: %v", token.Header["alg"])
return nil, ErrNotImplemented
})
}
if err != nil {
return "", err
} else if !token.Valid {
return "", ErrNotValid
}
b, err := json.Marshal(claims)
return string(b), err
},
"jq": func(args ...string) (out string, err error) {
if len(args) == 0 || len(args) > 2 {
return "", ErrNotValid
}
stdin := args[len(args)-1]
data := map[string]any{}
if err = json.Unmarshal([]byte(stdin), &data); err != nil {
return "", err
}
if len(args) == 1 {
return stdin, nil
}
filters := strings.Split(args[0], ".")
for i := 0; i < len(filters)-1; i++ {
if filters[i] == "" {
continue
}
if obj, ok := data[filters[i]].(map[string]any); ok {
data = obj
} else {
return "", nil
}
}
return fmt.Sprintf("%v", data[filters[len(filters)-1]]), nil
},
} }