Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
302 lines
7.2 KiB
Go
302 lines
7.2 KiB
Go
package envoy
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/cortezaproject/corteza/server/compose/dalutils"
|
|
"github.com/cortezaproject/corteza/server/compose/service"
|
|
"github.com/cortezaproject/corteza/server/compose/types"
|
|
"github.com/cortezaproject/corteza/server/pkg/dal"
|
|
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
|
"github.com/cortezaproject/corteza/server/pkg/filter"
|
|
"github.com/cortezaproject/corteza/server/pkg/id"
|
|
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
|
"github.com/cortezaproject/corteza/server/store"
|
|
"github.com/spf13/cast"
|
|
)
|
|
|
|
func (d StoreDecoder) extendNamespaceFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.NamespaceFilter) (out types.NamespaceFilter) {
|
|
out = base
|
|
|
|
if scope == nil {
|
|
return
|
|
}
|
|
|
|
if scope.ResourceType == "" {
|
|
return
|
|
}
|
|
|
|
// Overwrite it
|
|
out.NamespaceID = id.Strings(scope.Resource.GetID())
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) extendModuleFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.ModuleFilter) (out types.ModuleFilter) {
|
|
out = base
|
|
|
|
if scope == nil {
|
|
return
|
|
}
|
|
|
|
if scope.ResourceType == "" {
|
|
return
|
|
}
|
|
|
|
// Overwrite it
|
|
out.NamespaceID = scope.Resource.GetID()
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) extendPageFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter, base types.PageFilter) (out types.PageFilter) {
|
|
out = base
|
|
|
|
if scope == nil {
|
|
return
|
|
}
|
|
|
|
if scope.ResourceType == "" {
|
|
return
|
|
}
|
|
|
|
// Overwrite it
|
|
out.NamespaceID = scope.Resource.GetID()
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) makeModuleFieldFilter(scope *envoyx.Node, refs map[string]*envoyx.Node, auxf envoyx.ResourceFilter) (out types.ModuleFieldFilter) {
|
|
out.Limit = auxf.Limit
|
|
|
|
ids, hh := auxf.Identifiers.Idents()
|
|
_ = ids
|
|
_ = hh
|
|
|
|
// Refs
|
|
var (
|
|
ar *envoyx.Node
|
|
ok bool
|
|
)
|
|
_ = ar
|
|
_ = ok
|
|
|
|
// ar, ok = refs["ModuleID"]
|
|
// if ok {
|
|
// out.ModuleID = ar.Resource.GetID()
|
|
// }
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) extendedModuleDecoder(ctx context.Context, s store.Storer, dl dal.FullService, f types.ModuleFilter, base envoyx.NodeSet) (out envoyx.NodeSet, err error) {
|
|
var ff envoyx.NodeSet
|
|
|
|
for _, b := range base {
|
|
mod := b.Resource.(*types.Module)
|
|
|
|
// Get all of the related module fields, append them to the output and
|
|
// the original module (so other code can have access to the related fields)
|
|
ff, err = d.decodeModuleField(ctx, s, dl, types.ModuleFieldFilter{ModuleID: []uint64{mod.ID}})
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for _, f := range ff {
|
|
f.Scope = b.Scope
|
|
f.References = envoyx.MergeRefs(f.References, b.References, map[string]envoyx.Ref{
|
|
"ModuleID": b.ToRef(),
|
|
})
|
|
for k, ref := range f.References {
|
|
ref.Scope = b.Scope
|
|
f.References[k] = ref
|
|
}
|
|
|
|
mod.Fields = append(mod.Fields, f.Resource.(*types.ModuleField))
|
|
}
|
|
|
|
out = append(out, ff...)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func decodeChartRefs(c *types.Chart) (refs map[string]envoyx.Ref) {
|
|
refs = make(map[string]envoyx.Ref, len(c.Config.Reports))
|
|
|
|
for i, r := range c.Config.Reports {
|
|
if r.ModuleID == 0 {
|
|
continue
|
|
}
|
|
|
|
refs[fmt.Sprintf("Config.Reports.%d.ModuleID", i)] = envoyx.Ref{
|
|
ResourceType: types.ModuleResourceType,
|
|
Identifiers: envoyx.MakeIdentifiers(r.ModuleID),
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func decodeModuleFieldRefs(c *types.ModuleField) (refs map[string]envoyx.Ref) {
|
|
refs = make(map[string]envoyx.Ref, 1)
|
|
|
|
refs["NamespaceID"] = envoyx.Ref{
|
|
ResourceType: types.NamespaceResourceType,
|
|
Identifiers: envoyx.MakeIdentifiers(c.NamespaceID),
|
|
}
|
|
|
|
id := c.Options.UInt64("moduleID")
|
|
if id == 0 {
|
|
return
|
|
}
|
|
|
|
refs["Options.ModuleID"] = envoyx.Ref{
|
|
ResourceType: types.ModuleResourceType,
|
|
Identifiers: envoyx.MakeIdentifiers(id),
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func decodePageRefs(p *types.Page) (refs map[string]envoyx.Ref) {
|
|
refs = make(map[string]envoyx.Ref, len(p.Blocks)/2)
|
|
|
|
for index, b := range p.Blocks {
|
|
switch b.Kind {
|
|
case "RecordList":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockRecordListRefs(b, index))
|
|
|
|
case "Automation":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockAutomationRefs(b, index))
|
|
|
|
case "RecordOrganizer":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockRecordOrganizerRefs(b, index))
|
|
|
|
case "Chart":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockChartRefs(b, index))
|
|
|
|
case "Calendar":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockCalendarRefs(b, index))
|
|
|
|
case "Metric":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockMetricRefs(b, index))
|
|
|
|
case "Comment":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockCommentRefs(b, index))
|
|
|
|
case "Progress":
|
|
refs = envoyx.MergeRefs(refs, getPageBlockProgressRefs(b, index))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) extendDecoder(ctx context.Context, s store.Storer, dl dal.FullService, p envoyx.DecodeParams, rt string, refs map[string]*envoyx.Node, rf envoyx.ResourceFilter) (out envoyx.NodeSet, err error) {
|
|
switch rt {
|
|
// @todo consider hooking into the regular record resource type as well
|
|
case ComposeRecordDatasourceAuxType:
|
|
return d.decodeRecordDatasource(ctx, s, dl, p, refs, rf)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (d StoreDecoder) decodeRecordDatasource(ctx context.Context, s store.Storer, dl dal.FullService, p envoyx.DecodeParams, refs map[string]*envoyx.Node, rf envoyx.ResourceFilter) (out envoyx.NodeSet, err error) {
|
|
var (
|
|
ok bool
|
|
|
|
module *types.Module
|
|
moduleNode *envoyx.Node
|
|
namespace *types.Namespace
|
|
namespaceNode *envoyx.Node
|
|
)
|
|
|
|
// Get the refs
|
|
namespaceNode, ok = refs["NamespaceID"]
|
|
if !ok {
|
|
err = fmt.Errorf("missing NamespaceID reference")
|
|
return
|
|
}
|
|
namespace = namespaceNode.Resource.(*types.Namespace)
|
|
|
|
moduleNode, ok = refs["ModuleID"]
|
|
if !ok {
|
|
err = fmt.Errorf("missing ModuleID reference")
|
|
return
|
|
}
|
|
module = moduleNode.Resource.(*types.Module)
|
|
|
|
// Get the iterator
|
|
iter, _, err := dalutils.ComposeRecordsIterator(ctx, dl, module, types.RecordFilter{
|
|
Query: rf.Query,
|
|
ModuleID: module.ID,
|
|
NamespaceID: namespace.ID,
|
|
Paging: filter.Paging{
|
|
Limit: rf.Limit,
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
mv := make(map[string]bool)
|
|
dt := make(map[string]bool)
|
|
for _, f := range module.Fields {
|
|
if f.Multi {
|
|
mv[f.Name] = true
|
|
}
|
|
if f.Kind == "DateTime" {
|
|
dt[f.Name] = true
|
|
}
|
|
}
|
|
|
|
for _, n := range []string{"createdAt", "updatedAt", "deletedAt"} {
|
|
dt[n] = true
|
|
}
|
|
|
|
rds := &RecordDatasource{
|
|
Provider: &iteratorProvider{iter: iter},
|
|
multivalues: mv,
|
|
datetimeFields: dt,
|
|
|
|
refToID: make(map[string]uint64),
|
|
existingIDs: make(map[uint64]bool),
|
|
// @todo consider providing defaults from the outside
|
|
Mapping: envoyx.DatasourceMapping{
|
|
KeyField: []string{"id"},
|
|
Defaultable: true,
|
|
},
|
|
}
|
|
|
|
// Get access controller to enforce field-level read permissions
|
|
ac := service.AccessControl(s)
|
|
if rbac.Global() == nil {
|
|
ac = nil
|
|
}
|
|
|
|
rds.Provider, err = mkIteratorProvider(ctx, ac, s, dl, iter, module, cast.ToBool(p.Params["resolveRefs"]), cast.ToBool(p.Params["includeRefID"]))
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
rr := map[string]envoyx.Ref{
|
|
"NamespaceID": namespaceNode.ToRef(),
|
|
"ModuleID": moduleNode.ToRef(),
|
|
}
|
|
|
|
out = append(out, &envoyx.Node{
|
|
Datasource: rds,
|
|
ResourceType: ComposeRecordDatasourceAuxType,
|
|
|
|
Identifiers: envoyx.MakeIdentifiers(module.ID, module.Handle),
|
|
References: rr,
|
|
Scope: moduleNode.Scope,
|
|
})
|
|
|
|
return
|
|
}
|