From 0faaba5f7ceb324119ac4eb5c4a837429d0d00e2 Mon Sep 17 00:00:00 2001 From: Peter Grlica Date: Fri, 28 Jan 2022 12:33:45 +0100 Subject: [PATCH] Moved HttpRequest expr Type to automation --- automation/automation/expr_types.gen.go | 578 ++++++++++++++++++++++++ automation/automation/expr_types.go | 107 +++++ automation/automation/expr_types.yaml | 31 ++ automation/service/service.go | 3 + system/automation/expr_types.gen.go | 436 ------------------ system/automation/expr_types.go | 50 -- system/automation/expr_types.yaml | 23 - system/types/http_request.go | 28 -- 8 files changed, 719 insertions(+), 537 deletions(-) delete mode 100644 system/types/http_request.go diff --git a/automation/automation/expr_types.gen.go b/automation/automation/expr_types.gen.go index b96cb0580..dea5f3e04 100644 --- a/automation/automation/expr_types.gen.go +++ b/automation/automation/expr_types.gen.go @@ -11,6 +11,7 @@ package automation import ( "context" "fmt" + "github.com/cortezaproject/corteza-server/automation/types" . "github.com/cortezaproject/corteza-server/pkg/expr" "sync" ) @@ -66,3 +67,580 @@ func (t *EmailMessage) Assign(val interface{}) error { return nil } } + +// HttpRequest is an expression type, wrapper for *types.HttpRequest type +type HttpRequest struct { + value *types.HttpRequest + mux sync.RWMutex +} + +// NewHttpRequest creates new instance of HttpRequest expression type +func NewHttpRequest(val interface{}) (*HttpRequest, error) { + if c, err := CastToHttpRequest(val); err != nil { + return nil, fmt.Errorf("unable to create HttpRequest: %w", err) + } else { + return &HttpRequest{value: c}, nil + } +} + +// Get return underlying value on HttpRequest +func (t *HttpRequest) Get() interface{} { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// GetValue returns underlying value on HttpRequest +func (t *HttpRequest) GetValue() *types.HttpRequest { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// Type return type name +func (HttpRequest) Type() string { return "HttpRequest" } + +// Cast converts value to *types.HttpRequest +func (HttpRequest) Cast(val interface{}) (TypedValue, error) { + return NewHttpRequest(val) +} + +// Assign new value to HttpRequest +// +// value is first passed through CastToHttpRequest +func (t *HttpRequest) Assign(val interface{}) error { + if c, err := CastToHttpRequest(val); err != nil { + return err + } else { + t.value = c + return nil + } +} + +func (t *HttpRequest) AssignFieldValue(key string, val TypedValue) error { + t.mux.Lock() + defer t.mux.Unlock() + return assignToHttpRequest(t.value, key, val) +} + +// SelectGVal implements gval.Selector requirements +// +// It allows gval lib to access HttpRequest's underlying value (*types.HttpRequest) +// and it's fields +// +func (t *HttpRequest) SelectGVal(ctx context.Context, k string) (interface{}, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return httpRequestGValSelector(t.value, k) +} + +// Select is field accessor for *types.HttpRequest +// +// Similar to SelectGVal but returns typed values +func (t *HttpRequest) Select(k string) (TypedValue, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return httpRequestTypedValueSelector(t.value, k) +} + +func (t *HttpRequest) Has(k string) bool { + t.mux.RLock() + defer t.mux.RUnlock() + switch k { + case "Method": + return true + case "URL": + return true + case "Header": + return true + case "Body": + return true + case "Form": + return true + case "PostForm": + return true + } + return false +} + +// httpRequestGValSelector is field accessor for *types.HttpRequest +func httpRequestGValSelector(res *types.HttpRequest, k string) (interface{}, error) { + if res == nil { + return nil, nil + } + switch k { + case "Method": + return res.Method, nil + case "URL": + return res.URL, nil + case "Header": + return res.Header, nil + case "Body": + return res.Body, nil + case "Form": + return res.Form, nil + case "PostForm": + return res.PostForm, nil + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// httpRequestTypedValueSelector is field accessor for *types.HttpRequest +func httpRequestTypedValueSelector(res *types.HttpRequest, k string) (TypedValue, error) { + if res == nil { + return nil, nil + } + switch k { + case "Method": + return NewString(res.Method) + case "URL": + return NewUrl(res.URL) + case "Header": + return NewKVV(res.Header) + case "Body": + return NewHttpRequestBody(res.Body) + case "Form": + return NewKVV(res.Form) + case "PostForm": + return NewKVV(res.PostForm) + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// assignToHttpRequest is field value setter for *types.HttpRequest +func assignToHttpRequest(res *types.HttpRequest, k string, val interface{}) error { + switch k { + case "Method": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Method = aux + return nil + case "URL": + aux, err := CastToUrl(val) + if err != nil { + return err + } + + res.URL = aux + return nil + case "Header": + aux, err := CastToKVV(val) + if err != nil { + return err + } + + res.Header = aux + return nil + case "Body": + aux, err := CastToHttpRequestBody(val) + if err != nil { + return err + } + + res.Body = aux + return nil + case "Form": + aux, err := CastToKVV(val) + if err != nil { + return err + } + + res.Form = aux + return nil + case "PostForm": + aux, err := CastToKVV(val) + if err != nil { + return err + } + + res.PostForm = aux + return nil + } + + return fmt.Errorf("unknown field '%s'", k) +} + +// HttpRequestBody is an expression type, wrapper for *types.HttpRequestBody type +type HttpRequestBody struct { + value *types.HttpRequestBody + mux sync.RWMutex +} + +// NewHttpRequestBody creates new instance of HttpRequestBody expression type +func NewHttpRequestBody(val interface{}) (*HttpRequestBody, error) { + if c, err := CastToHttpRequestBody(val); err != nil { + return nil, fmt.Errorf("unable to create HttpRequestBody: %w", err) + } else { + return &HttpRequestBody{value: c}, nil + } +} + +// Get return underlying value on HttpRequestBody +func (t *HttpRequestBody) Get() interface{} { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// GetValue returns underlying value on HttpRequestBody +func (t *HttpRequestBody) GetValue() *types.HttpRequestBody { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// Type return type name +func (HttpRequestBody) Type() string { return "HttpRequestBody" } + +// Cast converts value to *types.HttpRequestBody +func (HttpRequestBody) Cast(val interface{}) (TypedValue, error) { + return NewHttpRequestBody(val) +} + +// Assign new value to HttpRequestBody +// +// value is first passed through CastToHttpRequestBody +func (t *HttpRequestBody) Assign(val interface{}) error { + if c, err := CastToHttpRequestBody(val); err != nil { + return err + } else { + t.value = c + return nil + } +} + +func (t *HttpRequestBody) AssignFieldValue(key string, val TypedValue) error { + t.mux.Lock() + defer t.mux.Unlock() + return assignToHttpRequestBody(t.value, key, val) +} + +// SelectGVal implements gval.Selector requirements +// +// It allows gval lib to access HttpRequestBody's underlying value (*types.HttpRequestBody) +// and it's fields +// +func (t *HttpRequestBody) SelectGVal(ctx context.Context, k string) (interface{}, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return httpRequestBodyGValSelector(t.value, k) +} + +// Select is field accessor for *types.HttpRequestBody +// +// Similar to SelectGVal but returns typed values +func (t *HttpRequestBody) Select(k string) (TypedValue, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return httpRequestBodyTypedValueSelector(t.value, k) +} + +func (t *HttpRequestBody) Has(k string) bool { + t.mux.RLock() + defer t.mux.RUnlock() + switch k { + case "Body": + return true + case "Buffer": + return true + } + return false +} + +// httpRequestBodyGValSelector is field accessor for *types.HttpRequestBody +func httpRequestBodyGValSelector(res *types.HttpRequestBody, k string) (interface{}, error) { + if res == nil { + return nil, nil + } + switch k { + case "Body": + return res.Body, nil + case "Buffer": + return res.Buffer, nil + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// httpRequestBodyTypedValueSelector is field accessor for *types.HttpRequestBody +func httpRequestBodyTypedValueSelector(res *types.HttpRequestBody, k string) (TypedValue, error) { + if res == nil { + return nil, nil + } + switch k { + case "Body": + return NewReader(res.Body) + case "Buffer": + return NewBytes(res.Buffer) + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// assignToHttpRequestBody is field value setter for *types.HttpRequestBody +func assignToHttpRequestBody(res *types.HttpRequestBody, k string, val interface{}) error { + switch k { + case "Body": + aux, err := CastToReader(val) + if err != nil { + return err + } + + res.Body = aux + return nil + case "Buffer": + aux, err := CastToBytes(val) + if err != nil { + return err + } + + res.Buffer = aux + return nil + } + + return fmt.Errorf("unknown field '%s'", k) +} + +// Url is an expression type, wrapper for *types.Url type +type Url struct { + value *types.Url + mux sync.RWMutex +} + +// NewUrl creates new instance of Url expression type +func NewUrl(val interface{}) (*Url, error) { + if c, err := CastToUrl(val); err != nil { + return nil, fmt.Errorf("unable to create Url: %w", err) + } else { + return &Url{value: c}, nil + } +} + +// Get return underlying value on Url +func (t *Url) Get() interface{} { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// GetValue returns underlying value on Url +func (t *Url) GetValue() *types.Url { + t.mux.RLock() + defer t.mux.RUnlock() + return t.value +} + +// Type return type name +func (Url) Type() string { return "Url" } + +// Cast converts value to *types.Url +func (Url) Cast(val interface{}) (TypedValue, error) { + return NewUrl(val) +} + +// Assign new value to Url +// +// value is first passed through CastToUrl +func (t *Url) Assign(val interface{}) error { + if c, err := CastToUrl(val); err != nil { + return err + } else { + t.value = c + return nil + } +} + +func (t *Url) AssignFieldValue(key string, val TypedValue) error { + t.mux.Lock() + defer t.mux.Unlock() + return assignToUrl(t.value, key, val) +} + +// SelectGVal implements gval.Selector requirements +// +// It allows gval lib to access Url's underlying value (*types.Url) +// and it's fields +// +func (t *Url) SelectGVal(ctx context.Context, k string) (interface{}, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return urlGValSelector(t.value, k) +} + +// Select is field accessor for *types.Url +// +// Similar to SelectGVal but returns typed values +func (t *Url) Select(k string) (TypedValue, error) { + t.mux.RLock() + defer t.mux.RUnlock() + return urlTypedValueSelector(t.value, k) +} + +func (t *Url) Has(k string) bool { + t.mux.RLock() + defer t.mux.RUnlock() + switch k { + case "Scheme": + return true + case "Opaque": + return true + case "Host": + return true + case "Path": + return true + case "RawPath": + return true + case "ForceQuery": + return true + case "RawQuery": + return true + case "Fragment": + return true + case "RawFragment": + return true + } + return false +} + +// urlGValSelector is field accessor for *types.Url +func urlGValSelector(res *types.Url, k string) (interface{}, error) { + if res == nil { + return nil, nil + } + switch k { + case "Scheme": + return res.Scheme, nil + case "Opaque": + return res.Opaque, nil + case "Host": + return res.Host, nil + case "Path": + return res.Path, nil + case "RawPath": + return res.RawPath, nil + case "ForceQuery": + return res.ForceQuery, nil + case "RawQuery": + return res.RawQuery, nil + case "Fragment": + return res.Fragment, nil + case "RawFragment": + return res.RawFragment, nil + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// urlTypedValueSelector is field accessor for *types.Url +func urlTypedValueSelector(res *types.Url, k string) (TypedValue, error) { + if res == nil { + return nil, nil + } + switch k { + case "Scheme": + return NewString(res.Scheme) + case "Opaque": + return NewString(res.Opaque) + case "Host": + return NewString(res.Host) + case "Path": + return NewString(res.Path) + case "RawPath": + return NewString(res.RawPath) + case "ForceQuery": + return NewBoolean(res.ForceQuery) + case "RawQuery": + return NewString(res.RawQuery) + case "Fragment": + return NewString(res.Fragment) + case "RawFragment": + return NewString(res.RawFragment) + } + + return nil, fmt.Errorf("unknown field '%s'", k) +} + +// assignToUrl is field value setter for *types.Url +func assignToUrl(res *types.Url, k string, val interface{}) error { + switch k { + case "Scheme": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Scheme = aux + return nil + case "Opaque": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Opaque = aux + return nil + case "Host": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Host = aux + return nil + case "Path": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Path = aux + return nil + case "RawPath": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.RawPath = aux + return nil + case "ForceQuery": + aux, err := CastToBoolean(val) + if err != nil { + return err + } + + res.ForceQuery = aux + return nil + case "RawQuery": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.RawQuery = aux + return nil + case "Fragment": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.Fragment = aux + return nil + case "RawFragment": + aux, err := CastToString(val) + if err != nil { + return err + } + + res.RawFragment = aux + return nil + } + + return fmt.Errorf("unknown field '%s'", k) +} diff --git a/automation/automation/expr_types.go b/automation/automation/expr_types.go index 39ef7cc0c..15cfe6cd7 100644 --- a/automation/automation/expr_types.go +++ b/automation/automation/expr_types.go @@ -1,7 +1,14 @@ package automation import ( + "encoding/json" "fmt" + "io" + "net/http" + "net/url" + + "github.com/cortezaproject/corteza-server/automation/types" + atypes "github.com/cortezaproject/corteza-server/pkg/apigw/types" "github.com/cortezaproject/corteza-server/pkg/expr" "gopkg.in/mail.v2" ) @@ -29,3 +36,103 @@ func CastToEmailMessage(val interface{}) (out *emailMessage, err error) { return nil, fmt.Errorf("unable to cast type %T to %T", val, out) } } + +func CastToHttpRequest(val interface{}) (out *types.HttpRequest, err error) { + switch val := val.(type) { + case expr.Iterator: + out = &types.HttpRequest{} + return out, val.Each(func(k string, v expr.TypedValue) error { + return assignToHttpRequest(out, k, v) + }) + } + + switch val := expr.UntypedValue(val).(type) { + case *http.Request: + rr := &types.HttpRequest{} + + assignToHttpRequest(rr, "Method", val.Method) + assignToHttpRequest(rr, "URL", val.URL) + assignToHttpRequest(rr, "Header", val.Header) + assignToHttpRequest(rr, "Body", val.Body) + assignToHttpRequest(rr, "Form", val.Form) + assignToHttpRequest(rr, "PostForm", val.PostForm) + + return rr, nil + case *types.HttpRequest: + return val, nil + case nil: + return &types.HttpRequest{}, nil + default: + return &types.HttpRequest{}, fmt.Errorf("unable to cast type %T to %T", val, out) + } +} + +func CastToHttpRequestBody(val interface{}) (out *types.HttpRequestBody, err error) { + switch val := val.(type) { + case io.ReadCloser: + rr := &types.HttpRequestBody{} + return rr, assignToHttpRequestBody(rr, "Body", val) + } + + switch val := expr.UntypedValue(val).(type) { + case *io.ReadCloser: + rr := &types.HttpRequestBody{} + return rr, assignToHttpRequestBody(rr, "Body", val) + case *types.HttpRequestBody: + return val, nil + case nil: + return &types.HttpRequestBody{}, nil + default: + return &types.HttpRequestBody{}, fmt.Errorf("unable to cast type %T to %T", val, out) + } +} + +func CastToUrl(val interface{}) (out *types.Url, err error) { + switch val := expr.UntypedValue(val).(type) { + case *url.URL: + u := &types.Url{} + + m, _ := json.Marshal(val) + _ = json.Unmarshal(m, u) + + return u, nil + case *types.Url: + return val, nil + case nil: + return &types.Url{}, nil + default: + return &types.Url{}, fmt.Errorf("unable to cast type %T to %T", val, out) + } +} + +func ReadRequestBody(in interface{}) (s string) { + var ( + b []byte + err error + ) + + switch val := in.(type) { + case *HttpRequest: + b, err = val.Get().(*types.HttpRequest).ReadBody() + case *HttpRequestBody: + b, err = val.Get().(*types.HttpRequestBody).Read() + case *atypes.HttpRequest: + b, err = val.ReadBody() + case *types.HttpRequest: + b, err = val.ReadBody() + case *atypes.HttpRequestBody: + b, err = val.Read() + case *types.HttpRequestBody: + b, err = val.Read() + case io.Reader: + b, err = io.ReadAll(val) + default: + b = []byte{} + } + + if err != nil { + return "" + } + + return string(b) +} diff --git a/automation/automation/expr_types.yaml b/automation/automation/expr_types.yaml index 2df9cc83f..131cc6841 100644 --- a/automation/automation/expr_types.yaml +++ b/automation/automation/expr_types.yaml @@ -1,5 +1,8 @@ package: automation +imports: + - github.com/cortezaproject/corteza-server/automation/types + types: EmailMessage: # using ad-hoc type for now, we'll port this to something internal @@ -16,3 +19,31 @@ types: # - { name: 'parts', exprType: 'Any', goType: 'map[string]io.Reader', mode: ro } # - { name: 'embedded', exprType: 'Any', goType: 'map[string]io.Reader', mode: ro } # - { name: 'attachments', exprType: 'Any', goType: 'map[string]io.Reader', mode: ro } + HttpRequest: + as: '*types.HttpRequest' + struct: + - { name: 'Method', exprType: 'String', goType: 'string' } + - { name: 'URL', exprType: 'Url', goType: 'url.Url' } + - { name: 'Header', exprType: 'KVV', goType: 'map[string][]string' } + - { name: 'Body', exprType: 'HttpRequestBody', goType: '*types.HttpRequestBody' } + - { name: 'Form', exprType: 'KVV', goType: 'map[string][]string' } + - { name: 'PostForm', exprType: 'KVV', goType: 'map[string][]string' } + + HttpRequestBody: + as: '*types.HttpRequestBody' + struct: + - { name: 'Body', exprType: 'Reader', goType: 'io.Reader' } + - { name: 'Buffer', exprType: 'Bytes', goType: '[]byte' } + + Url: + as: '*types.Url' + struct: + - { name: 'Scheme', exprType: 'String', goType: 'string' } + - { name: 'Opaque', exprType: 'String', goType: 'string' } + - { name: 'Host', exprType: 'String', goType: 'string' } + - { name: 'Path', exprType: 'String', goType: 'string' } + - { name: 'RawPath', exprType: 'String', goType: 'string' } + - { name: 'ForceQuery', exprType: 'Boolean', goType: 'bool' } + - { name: 'RawQuery', exprType: 'String', goType: 'string' } + - { name: 'Fragment', exprType: 'String', goType: 'string' } + - { name: 'RawFragment', exprType: 'String', goType: 'string' } diff --git a/automation/service/service.go b/automation/service/service.go index 84a5cc6e1..184eea406 100644 --- a/automation/service/service.go +++ b/automation/service/service.go @@ -115,6 +115,8 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock &expr.Vars{}, &automation.EmailMessage{}, + &automation.HttpRequest{}, + &automation.HttpRequestBody{}, ) automation.HttpRequestHandler(Registry()) @@ -126,6 +128,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock automation.CorredorHandler(Registry(), corredor.Service()) automation.EmailHandler(Registry()) automation.JwtHandler(Registry()) + automation.ApigwBodyHandler(Registry()) return } diff --git a/system/automation/expr_types.gen.go b/system/automation/expr_types.gen.go index b914cf0dd..59bf496fe 100644 --- a/system/automation/expr_types.gen.go +++ b/system/automation/expr_types.gen.go @@ -119,203 +119,6 @@ func (t *DocumentType) Assign(val interface{}) error { } } -// HttpRequest is an expression type, wrapper for *types.HttpRequest type -type HttpRequest struct { - value *types.HttpRequest - mux sync.RWMutex -} - -// NewHttpRequest creates new instance of HttpRequest expression type -func NewHttpRequest(val interface{}) (*HttpRequest, error) { - if c, err := CastToHttpRequest(val); err != nil { - return nil, fmt.Errorf("unable to create HttpRequest: %w", err) - } else { - return &HttpRequest{value: c}, nil - } -} - -// Get return underlying value on HttpRequest -func (t *HttpRequest) Get() interface{} { - t.mux.RLock() - defer t.mux.RUnlock() - return t.value -} - -// GetValue returns underlying value on HttpRequest -func (t *HttpRequest) GetValue() *types.HttpRequest { - t.mux.RLock() - defer t.mux.RUnlock() - return t.value -} - -// Type return type name -func (HttpRequest) Type() string { return "HttpRequest" } - -// Cast converts value to *types.HttpRequest -func (HttpRequest) Cast(val interface{}) (TypedValue, error) { - return NewHttpRequest(val) -} - -// Assign new value to HttpRequest -// -// value is first passed through CastToHttpRequest -func (t *HttpRequest) Assign(val interface{}) error { - if c, err := CastToHttpRequest(val); err != nil { - return err - } else { - t.value = c - return nil - } -} - -func (t *HttpRequest) AssignFieldValue(key string, val TypedValue) error { - t.mux.Lock() - defer t.mux.Unlock() - return assignToHttpRequest(t.value, key, val) -} - -// SelectGVal implements gval.Selector requirements -// -// It allows gval lib to access HttpRequest's underlying value (*types.HttpRequest) -// and it's fields -// -func (t *HttpRequest) SelectGVal(ctx context.Context, k string) (interface{}, error) { - t.mux.RLock() - defer t.mux.RUnlock() - return httpRequestGValSelector(t.value, k) -} - -// Select is field accessor for *types.HttpRequest -// -// Similar to SelectGVal but returns typed values -func (t *HttpRequest) Select(k string) (TypedValue, error) { - t.mux.RLock() - defer t.mux.RUnlock() - return httpRequestTypedValueSelector(t.value, k) -} - -func (t *HttpRequest) Has(k string) bool { - t.mux.RLock() - defer t.mux.RUnlock() - switch k { - case "Method": - return true - case "URL": - return true - case "Header": - return true - case "Body": - return true - case "Form": - return true - case "PostForm": - return true - } - return false -} - -// httpRequestGValSelector is field accessor for *types.HttpRequest -func httpRequestGValSelector(res *types.HttpRequest, k string) (interface{}, error) { - if res == nil { - return nil, nil - } - switch k { - case "Method": - return res.Method, nil - case "URL": - return res.URL, nil - case "Header": - return res.Header, nil - case "Body": - return res.Body, nil - case "Form": - return res.Form, nil - case "PostForm": - return res.PostForm, nil - } - - return nil, fmt.Errorf("unknown field '%s'", k) -} - -// httpRequestTypedValueSelector is field accessor for *types.HttpRequest -func httpRequestTypedValueSelector(res *types.HttpRequest, k string) (TypedValue, error) { - if res == nil { - return nil, nil - } - switch k { - case "Method": - return NewString(res.Method) - case "URL": - return NewUrl(res.URL) - case "Header": - return NewKVV(res.Header) - case "Body": - return NewReader(res.Body) - case "Form": - return NewKVV(res.Form) - case "PostForm": - return NewKVV(res.PostForm) - } - - return nil, fmt.Errorf("unknown field '%s'", k) -} - -// assignToHttpRequest is field value setter for *types.HttpRequest -func assignToHttpRequest(res *types.HttpRequest, k string, val interface{}) error { - switch k { - case "Method": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Method = aux - return nil - case "URL": - aux, err := CastToUrl(val) - if err != nil { - return err - } - - res.URL = aux - return nil - case "Header": - aux, err := CastToKVV(val) - if err != nil { - return err - } - - res.Header = aux - return nil - case "Body": - aux, err := CastToReader(val) - if err != nil { - return err - } - - res.Body = aux - return nil - case "Form": - aux, err := CastToKVV(val) - if err != nil { - return err - } - - res.Form = aux - return nil - case "PostForm": - aux, err := CastToKVV(val) - if err != nil { - return err - } - - res.PostForm = aux - return nil - } - - return fmt.Errorf("unknown field '%s'", k) -} - // QueueMessage is an expression type, wrapper for *types.QueueMessage type type QueueMessage struct { value *types.QueueMessage @@ -1299,245 +1102,6 @@ func assignToTemplateMeta(res types.TemplateMeta, k string, val interface{}) err return fmt.Errorf("unknown field '%s'", k) } -// Url is an expression type, wrapper for *types.Url type -type Url struct { - value *types.Url - mux sync.RWMutex -} - -// NewUrl creates new instance of Url expression type -func NewUrl(val interface{}) (*Url, error) { - if c, err := CastToUrl(val); err != nil { - return nil, fmt.Errorf("unable to create Url: %w", err) - } else { - return &Url{value: c}, nil - } -} - -// Get return underlying value on Url -func (t *Url) Get() interface{} { - t.mux.RLock() - defer t.mux.RUnlock() - return t.value -} - -// GetValue returns underlying value on Url -func (t *Url) GetValue() *types.Url { - t.mux.RLock() - defer t.mux.RUnlock() - return t.value -} - -// Type return type name -func (Url) Type() string { return "Url" } - -// Cast converts value to *types.Url -func (Url) Cast(val interface{}) (TypedValue, error) { - return NewUrl(val) -} - -// Assign new value to Url -// -// value is first passed through CastToUrl -func (t *Url) Assign(val interface{}) error { - if c, err := CastToUrl(val); err != nil { - return err - } else { - t.value = c - return nil - } -} - -func (t *Url) AssignFieldValue(key string, val TypedValue) error { - t.mux.Lock() - defer t.mux.Unlock() - return assignToUrl(t.value, key, val) -} - -// SelectGVal implements gval.Selector requirements -// -// It allows gval lib to access Url's underlying value (*types.Url) -// and it's fields -// -func (t *Url) SelectGVal(ctx context.Context, k string) (interface{}, error) { - t.mux.RLock() - defer t.mux.RUnlock() - return urlGValSelector(t.value, k) -} - -// Select is field accessor for *types.Url -// -// Similar to SelectGVal but returns typed values -func (t *Url) Select(k string) (TypedValue, error) { - t.mux.RLock() - defer t.mux.RUnlock() - return urlTypedValueSelector(t.value, k) -} - -func (t *Url) Has(k string) bool { - t.mux.RLock() - defer t.mux.RUnlock() - switch k { - case "Scheme": - return true - case "Opaque": - return true - case "Host": - return true - case "Path": - return true - case "RawPath": - return true - case "ForceQuery": - return true - case "RawQuery": - return true - case "Fragment": - return true - case "RawFragment": - return true - } - return false -} - -// urlGValSelector is field accessor for *types.Url -func urlGValSelector(res *types.Url, k string) (interface{}, error) { - if res == nil { - return nil, nil - } - switch k { - case "Scheme": - return res.Scheme, nil - case "Opaque": - return res.Opaque, nil - case "Host": - return res.Host, nil - case "Path": - return res.Path, nil - case "RawPath": - return res.RawPath, nil - case "ForceQuery": - return res.ForceQuery, nil - case "RawQuery": - return res.RawQuery, nil - case "Fragment": - return res.Fragment, nil - case "RawFragment": - return res.RawFragment, nil - } - - return nil, fmt.Errorf("unknown field '%s'", k) -} - -// urlTypedValueSelector is field accessor for *types.Url -func urlTypedValueSelector(res *types.Url, k string) (TypedValue, error) { - if res == nil { - return nil, nil - } - switch k { - case "Scheme": - return NewString(res.Scheme) - case "Opaque": - return NewString(res.Opaque) - case "Host": - return NewString(res.Host) - case "Path": - return NewString(res.Path) - case "RawPath": - return NewString(res.RawPath) - case "ForceQuery": - return NewBoolean(res.ForceQuery) - case "RawQuery": - return NewString(res.RawQuery) - case "Fragment": - return NewString(res.Fragment) - case "RawFragment": - return NewString(res.RawFragment) - } - - return nil, fmt.Errorf("unknown field '%s'", k) -} - -// assignToUrl is field value setter for *types.Url -func assignToUrl(res *types.Url, k string, val interface{}) error { - switch k { - case "Scheme": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Scheme = aux - return nil - case "Opaque": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Opaque = aux - return nil - case "Host": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Host = aux - return nil - case "Path": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Path = aux - return nil - case "RawPath": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.RawPath = aux - return nil - case "ForceQuery": - aux, err := CastToBoolean(val) - if err != nil { - return err - } - - res.ForceQuery = aux - return nil - case "RawQuery": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.RawQuery = aux - return nil - case "Fragment": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.Fragment = aux - return nil - case "RawFragment": - aux, err := CastToString(val) - if err != nil { - return err - } - - res.RawFragment = aux - return nil - } - - return fmt.Errorf("unknown field '%s'", k) -} - // User is an expression type, wrapper for *types.User type type User struct { value *types.User diff --git a/system/automation/expr_types.go b/system/automation/expr_types.go index 5c9ff6713..5738be451 100644 --- a/system/automation/expr_types.go +++ b/system/automation/expr_types.go @@ -5,8 +5,6 @@ import ( "fmt" "io" "io/ioutil" - "net/http" - "net/url" "github.com/cortezaproject/corteza-server/pkg/actionlog" "github.com/cortezaproject/corteza-server/pkg/expr" @@ -186,54 +184,6 @@ func CastToQueueMessage(val interface{}) (out *types.QueueMessage, err error) { } } -func CastToHttpRequest(val interface{}) (out *types.HttpRequest, err error) { - switch val := val.(type) { - case expr.Iterator: - out = &types.HttpRequest{} - return out, val.Each(func(k string, v expr.TypedValue) error { - return assignToHttpRequest(out, k, v) - }) - } - - switch val := expr.UntypedValue(val).(type) { - case *http.Request: - rr := &types.HttpRequest{} - - assignToHttpRequest(rr, "Method", val.Method) - assignToHttpRequest(rr, "URL", val.URL) - assignToHttpRequest(rr, "Header", val.Header) - assignToHttpRequest(rr, "Body", val.Body) - assignToHttpRequest(rr, "Form", val.Form) - assignToHttpRequest(rr, "PostForm", val.PostForm) - - return rr, nil - case *types.HttpRequest: - return val, nil - case nil: - return &types.HttpRequest{}, nil - default: - return &types.HttpRequest{}, fmt.Errorf("unable to cast type %T to %T", val, out) - } -} - -func CastToUrl(val interface{}) (out *types.Url, err error) { - switch val := expr.UntypedValue(val).(type) { - case *url.URL: - u := &types.Url{} - - m, _ := json.Marshal(val) - _ = json.Unmarshal(m, u) - - return u, nil - case *types.Url: - return val, nil - case nil: - return &types.Url{}, nil - default: - return &types.Url{}, fmt.Errorf("unable to cast type %T to %T", val, out) - } -} - func (doc renderedDocument) String() string { aux, _ := ioutil.ReadAll(doc.Document) return string(aux) diff --git a/system/automation/expr_types.yaml b/system/automation/expr_types.yaml index 8eb307ccc..c768d0334 100644 --- a/system/automation/expr_types.yaml +++ b/system/automation/expr_types.yaml @@ -72,29 +72,6 @@ types: - { name: 'Queue', exprType: 'String', goType: 'string' } - { name: 'Payload', exprType: 'Bytes', goType: '[]byte' } - HttpRequest: - as: '*types.HttpRequest' - struct: - - { name: 'Method', exprType: 'String', goType: 'string' } - - { name: 'URL', exprType: 'Url', goType: 'url.Url' } - - { name: 'Header', exprType: 'KVV', goType: 'map[string][]string' } - - { name: 'Body', exprType: 'Reader', goType: 'io.Reader' } - - { name: 'Form', exprType: 'KVV', goType: 'map[string][]string' } - - { name: 'PostForm', exprType: 'KVV', goType: 'map[string][]string' } - - Url: - as: '*types.Url' - struct: - - { name: 'Scheme', exprType: 'String', goType: 'string' } - - { name: 'Opaque', exprType: 'String', goType: 'string' } - - { name: 'Host', exprType: 'String', goType: 'string' } - - { name: 'Path', exprType: 'String', goType: 'string' } - - { name: 'RawPath', exprType: 'String', goType: 'string' } - - { name: 'ForceQuery', exprType: 'Boolean', goType: 'bool' } - - { name: 'RawQuery', exprType: 'String', goType: 'string' } - - { name: 'Fragment', exprType: 'String', goType: 'string' } - - { name: 'RawFragment', exprType: 'String', goType: 'string' } - RbacResource: as: 'rbac.Resource' diff --git a/system/types/http_request.go b/system/types/http_request.go deleted file mode 100644 index 75f5442f5..000000000 --- a/system/types/http_request.go +++ /dev/null @@ -1,28 +0,0 @@ -package types - -import ( - "io" -) - -type ( - HttpRequest struct { - Method string `json:"method"` - URL *Url `json:"url"` - Header map[string][]string `json:"header"` - Body io.Reader `json:"body"` - Form map[string][]string `json:"form"` - PostForm map[string][]string `json:"post_form"` - } - - Url struct { - Scheme string - Opaque string - Host string - Path string - RawPath string - ForceQuery bool - RawQuery string - Fragment string - RawFragment string - } -)