Merge branch '2021.9.x-feature-wf-jwt' into 2021.9.x
This commit is contained in:
Generated
+184
@@ -0,0 +1,184 @@
|
||||
package automation
|
||||
|
||||
// This file is auto-generated.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
//
|
||||
// Definitions file that controls how this file is generated:
|
||||
// automation/automation/jwt_handler.yaml
|
||||
|
||||
import (
|
||||
"context"
|
||||
atypes "github.com/cortezaproject/corteza-server/automation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"io"
|
||||
)
|
||||
|
||||
var _ wfexec.ExecResponse
|
||||
|
||||
type (
|
||||
jwtHandlerRegistry interface {
|
||||
AddFunctions(ff ...*atypes.Function)
|
||||
Type(ref string) expr.Type
|
||||
}
|
||||
)
|
||||
|
||||
func (h jwtHandler) register() {
|
||||
h.reg.AddFunctions(
|
||||
h.Generate(),
|
||||
)
|
||||
}
|
||||
|
||||
type (
|
||||
jwtGenerateArgs struct {
|
||||
hasScope bool
|
||||
Scope string
|
||||
|
||||
hasHeader bool
|
||||
Header interface{}
|
||||
headerVars map[string]expr.TypedValue
|
||||
headerString string
|
||||
|
||||
hasPayload bool
|
||||
Payload interface{}
|
||||
payloadVars map[string]expr.TypedValue
|
||||
payloadString string
|
||||
|
||||
hasSecret bool
|
||||
Secret interface{}
|
||||
secretString string
|
||||
secretStream io.Reader
|
||||
}
|
||||
|
||||
jwtGenerateResults struct {
|
||||
Token string
|
||||
}
|
||||
)
|
||||
|
||||
func (a jwtGenerateArgs) GetHeader() (bool, map[string]expr.TypedValue, string) {
|
||||
return a.hasHeader, a.headerVars, a.headerString
|
||||
}
|
||||
|
||||
func (a jwtGenerateArgs) GetPayload() (bool, map[string]expr.TypedValue, string) {
|
||||
return a.hasPayload, a.payloadVars, a.payloadString
|
||||
}
|
||||
|
||||
func (a jwtGenerateArgs) GetSecret() (bool, string, io.Reader) {
|
||||
return a.hasSecret, a.secretString, a.secretStream
|
||||
}
|
||||
|
||||
// Generate function Generate JWT
|
||||
//
|
||||
// expects implementation of generate function:
|
||||
// func (h jwtHandler) generate(ctx context.Context, args *jwtGenerateArgs) (results *jwtGenerateResults, err error) {
|
||||
// return
|
||||
// }
|
||||
func (h jwtHandler) Generate() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "jwtGenerate",
|
||||
Kind: "function",
|
||||
Labels: map[string]string(nil),
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "Generate JWT",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "scope",
|
||||
Types: []string{"String"},
|
||||
},
|
||||
{
|
||||
Name: "header",
|
||||
Types: []string{"Vars", "String"}, Required: true,
|
||||
},
|
||||
{
|
||||
Name: "payload",
|
||||
Types: []string{"Vars", "String"}, Required: true,
|
||||
},
|
||||
{
|
||||
Name: "secret",
|
||||
Types: []string{"String", "Reader"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Results: []*atypes.Param{
|
||||
|
||||
{
|
||||
Name: "token",
|
||||
Types: []string{"String"},
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &jwtGenerateArgs{
|
||||
hasScope: in.Has("scope"),
|
||||
hasHeader: in.Has("header"),
|
||||
hasPayload: in.Has("payload"),
|
||||
hasSecret: in.Has("secret"),
|
||||
}
|
||||
)
|
||||
|
||||
if err = in.Decode(args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Converting Header argument
|
||||
if args.hasHeader {
|
||||
aux := expr.Must(expr.Select(in, "header"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("Vars").Type():
|
||||
args.headerVars = aux.Get().(map[string]expr.TypedValue)
|
||||
case h.reg.Type("String").Type():
|
||||
args.headerString = aux.Get().(string)
|
||||
}
|
||||
}
|
||||
|
||||
// Converting Payload argument
|
||||
if args.hasPayload {
|
||||
aux := expr.Must(expr.Select(in, "payload"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("Vars").Type():
|
||||
args.payloadVars = aux.Get().(map[string]expr.TypedValue)
|
||||
case h.reg.Type("String").Type():
|
||||
args.payloadString = aux.Get().(string)
|
||||
}
|
||||
}
|
||||
|
||||
// Converting Secret argument
|
||||
if args.hasSecret {
|
||||
aux := expr.Must(expr.Select(in, "secret"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("String").Type():
|
||||
args.secretString = aux.Get().(string)
|
||||
case h.reg.Type("Reader").Type():
|
||||
args.secretStream = aux.Get().(io.Reader)
|
||||
}
|
||||
}
|
||||
|
||||
var results *jwtGenerateResults
|
||||
if results, err = h.generate(ctx, args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = &expr.Vars{}
|
||||
|
||||
{
|
||||
// converting results.Token (string) to String
|
||||
var (
|
||||
tval expr.TypedValue
|
||||
)
|
||||
|
||||
if tval, err = h.reg.Type("String").Cast(results.Token); err != nil {
|
||||
return
|
||||
} else if err = expr.Assign(out, "token", tval); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package automation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type (
|
||||
jwtHandler struct {
|
||||
reg jwtHandlerRegistry
|
||||
}
|
||||
)
|
||||
|
||||
func JwtHandler(reg jwtHandlerRegistry) *jwtHandler {
|
||||
h := &jwtHandler{
|
||||
reg: reg,
|
||||
}
|
||||
|
||||
h.register()
|
||||
return h
|
||||
}
|
||||
|
||||
func (h jwtHandler) generate(ctx context.Context, args *jwtGenerateArgs) (res *jwtGenerateResults, err error) {
|
||||
var (
|
||||
secret interface{}
|
||||
|
||||
auxp = make(map[string]interface{})
|
||||
auxh = make(map[string]interface{})
|
||||
)
|
||||
|
||||
if !args.hasPayload {
|
||||
err = fmt.Errorf("could not generate JWT, payload missing")
|
||||
return
|
||||
}
|
||||
|
||||
if !args.hasSecret {
|
||||
err = fmt.Errorf("could not generate JWT, secret or cert missing")
|
||||
return
|
||||
}
|
||||
|
||||
for k, v := range args.headerVars {
|
||||
auxp[k] = v.Get()
|
||||
}
|
||||
|
||||
for k, v := range args.payloadVars {
|
||||
auxp[k] = v.Get()
|
||||
}
|
||||
|
||||
if args.payloadString != "" {
|
||||
if err = json.Unmarshal([]byte(args.payloadString), &auxp); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if args.headerString != "" {
|
||||
if err = json.Unmarshal([]byte(args.headerString), &auxh); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// check for delimiters
|
||||
auxp["scope"] = strings.FieldsFunc(args.Scope, func(r rune) bool {
|
||||
return r == ' ' || r == ','
|
||||
})
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims(auxp))
|
||||
|
||||
// merge header with user-provided header
|
||||
for k, v := range auxh {
|
||||
token.Header[k] = v
|
||||
}
|
||||
|
||||
// check if we use cert
|
||||
{
|
||||
pemBlock, _ := pem.Decode([]byte(args.secretString))
|
||||
|
||||
if pemBlock != nil {
|
||||
if secret, err = x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
secret = args.secretString
|
||||
}
|
||||
}
|
||||
|
||||
res = &jwtGenerateResults{}
|
||||
res.Token, err = token.SignedString(secret)
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
imports:
|
||||
- io
|
||||
|
||||
functions:
|
||||
generate:
|
||||
meta:
|
||||
short: Generate JWT
|
||||
params:
|
||||
scope:
|
||||
require: false
|
||||
types:
|
||||
- { wf: String }
|
||||
header:
|
||||
required: true
|
||||
types:
|
||||
- { wf: Vars, suffix: Vars, go: 'map[string]expr.TypedValue' }
|
||||
- { wf: String, suffix: String }
|
||||
payload:
|
||||
required: true
|
||||
types:
|
||||
- { wf: Vars, suffix: Vars, go: 'map[string]expr.TypedValue' }
|
||||
- { wf: String, suffix: String }
|
||||
secret:
|
||||
required: true
|
||||
types:
|
||||
- { wf: String, suffix: String }
|
||||
- { wf: Reader, suffix: Stream }
|
||||
results:
|
||||
token:
|
||||
wf: String
|
||||
@@ -125,6 +125,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
|
||||
automation.LoopHandler(Registry(), DefaultWorkflow.parser)
|
||||
automation.CorredorHandler(Registry(), corredor.Service())
|
||||
automation.EmailHandler(Registry())
|
||||
automation.JwtHandler(Registry())
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package expr
|
||||
|
||||
import (
|
||||
"github.com/PaesslerAG/gval"
|
||||
"github.com/pkg/errors"
|
||||
"math"
|
||||
"math/rand"
|
||||
|
||||
"github.com/PaesslerAG/gval"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
func NumericFunctions() []gval.Language {
|
||||
@@ -21,6 +23,7 @@ func NumericFunctions() []gval.Language {
|
||||
gval.Function("sum", sum),
|
||||
gval.Function("average", average),
|
||||
gval.Function("random", random),
|
||||
gval.Function("int", toInt64),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,3 +144,7 @@ func random(v ...float64) (out float64, err error) {
|
||||
out = from + rand.Float64()*(to-from)
|
||||
return
|
||||
}
|
||||
|
||||
func toInt64(aa interface{}) (i int64) {
|
||||
return cast.ToInt64(aa)
|
||||
}
|
||||
|
||||
@@ -90,3 +90,24 @@ func Example_randomWithTwoInput() {
|
||||
// output:
|
||||
// 1
|
||||
}
|
||||
|
||||
func Example_castStringToInt() {
|
||||
eval(`int("abc")`, nil)
|
||||
|
||||
// output:
|
||||
// 0
|
||||
}
|
||||
|
||||
func Example_castStringNumberToInt() {
|
||||
eval(`int("42690")`, nil)
|
||||
|
||||
// output:
|
||||
// 42690
|
||||
}
|
||||
|
||||
func Example_castFloatToInt() {
|
||||
eval(`int("42.690")`, nil)
|
||||
|
||||
// output:
|
||||
// 0
|
||||
}
|
||||
|
||||
@@ -190,10 +190,15 @@ func prepMod(base interface{}, mod interface{}) (*time.Time, int, error) {
|
||||
// https://github.com/lestrrat-go/strftime#supported-conversion-specifications
|
||||
func strfTime(base interface{}, f string) (string, error) {
|
||||
t, _, err := prepMod(base, 0)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
o, _ := strftime.Format(f, *t, strftime.WithMilliseconds('b'))
|
||||
|
||||
o, _ := strftime.Format(f, *t,
|
||||
strftime.WithMilliseconds('b'),
|
||||
strftime.WithUnixSeconds('L'))
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -134,3 +134,10 @@ func Example_subErrorCheck() {
|
||||
// output:
|
||||
// error: can not evaluate sub(ghd, hgp): expecting 2nd input to be less than 1st input
|
||||
}
|
||||
|
||||
func Example_unix() {
|
||||
eval(`strftime(ghd, "%L")`, exampleTimeParams)
|
||||
|
||||
// output:
|
||||
// 728650800
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package workflows
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/automation/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
//go:embed testdata/jwt_generate/match_token
|
||||
var tkn string
|
||||
|
||||
func Test_jwt_generate(t *testing.T) {
|
||||
var (
|
||||
ctx = bypassRBAC(context.Background())
|
||||
req = require.New(t)
|
||||
|
||||
aux = struct {
|
||||
Token string
|
||||
}{}
|
||||
)
|
||||
|
||||
req.NoError(defStore.TruncateAttachments(ctx))
|
||||
|
||||
loadNewScenario(ctx, t)
|
||||
|
||||
vars, _ := mustExecWorkflow(ctx, t, "jwt_generate", types.WorkflowExecParams{})
|
||||
|
||||
req.NoError(vars.Decode(&aux))
|
||||
req.Equal(strings.TrimSuffix(tkn, "\n"), aux.Token)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
eyJhbGciOiJSUzI1NiIsImZvbyI6ImJhciIsInR5cCI6IkpXVCJ9.eyJleHAiOjcyODY1NDQwMCwiaWF0Ijo3Mjg2NTA4MDAsInNjb3BlIjpbXSwic3ViIjoiMTIzNDU2Nzg5MCJ9.Tk19aAqkcSuVd54OHSSX6VOjLk4MFhxoeufiEDGo8U7wtsW6EL3YGFCiWtcMpjrK03aNVUqQwue2BjB8ysqq3NsNvFVWiJFDUZR-4jaRHrz4FALZpb43do95YQFhJHliAnzmAEgbFQY704FTd9PYP9IGuw0EUwq_WOAtIiaKNHG20rPIRvltr_p1t54rDG0Xx_9iGCU-J-GJSWuYV7-XNHsdz0xJqxRAUeaH4Ly5BzjHBX8HSB0VezopZly2sJDlqfZCUBkL80eMvECJWc7g4znN9dPHKDcKclqvFI5sPSdQIQ7zZVeSbTizqXe-KXz9TykVTDOudnY4iRXzNerZ0_rzq7qT253qGoypkM0_N3oidFU0UkSnLgWIyeuw09bFraDyWuYEhYbsDif7qT8tP-w6YaKv0mFZ8BwRKl6yZafR8Ji7UNWhVQ3Qz8rJjAclX4elEFGq0deK7B2Kiwo6U33tNyx2Xi56QRMs6r26S9QoA3fNbA7C2HrFwy3coZxyJAKVCAHcfYOue-u1oersq0vAk_HGXytBrdiz6xL6wbRjNqfrT--I-uq2MfUEsZSh2Xy0SCEUt8IJeX6vt7nGeKqu6AUuKbCpA6CrXRI7K9jShuAsFeyTdKKjJsKCXwZRQp9ZyTmWYXcyXlDHf63I8JXNP2wzPM_3p0CCQ313S_Q
|
||||
@@ -0,0 +1,93 @@
|
||||
workflows:
|
||||
jwt_generate:
|
||||
enabled: true
|
||||
trace: true
|
||||
|
||||
triggers:
|
||||
- enabled: true
|
||||
stepID: 5
|
||||
|
||||
steps:
|
||||
- stepID: 5
|
||||
kind: function
|
||||
ref: jwtGenerate
|
||||
|
||||
arguments:
|
||||
- target: scope
|
||||
type: String
|
||||
|
||||
- target: header
|
||||
value: |-
|
||||
{
|
||||
"foo": "bar"
|
||||
}
|
||||
type: String
|
||||
|
||||
- target: payload
|
||||
expr: |-
|
||||
{
|
||||
"sub": "1234567890",
|
||||
"iat": int(strftime(date("1993-02-02T06:00:00-05:00"), "%L")),
|
||||
"exp": int(strftime(modTime(date("1993-02-02T06:00:00-05:00"), "+1h"), "%L"))
|
||||
}
|
||||
type: Vars
|
||||
|
||||
- target: secret
|
||||
value: |-
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
C/p2c759krBsxv/zOxJJsWDEF1AolQI=
|
||||
-----END PRIVATE KEY-----
|
||||
type: String
|
||||
|
||||
results:
|
||||
- target: token
|
||||
expr: token
|
||||
Reference in New Issue
Block a user