snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
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
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
This commit is contained in:
1294
server/system/envoy/store_decode.gen.go
generated
Normal file
1294
server/system/envoy/store_decode.gen.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
110
server/system/envoy/store_decode.go
Normal file
110
server/system/envoy/store_decode.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/dal"
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
)
|
||||
|
||||
func (d StoreDecoder) extendDecoder(ctx context.Context, s store.Storer, dl dal.FullService, _ envoyx.DecodeParams, rt string, nodes map[string]*envoyx.Node, f envoyx.ResourceFilter) (out envoyx.NodeSet, err error) {
|
||||
switch rt {
|
||||
case types.SettingValueResourceType:
|
||||
return d.decodeSettingValue(ctx, s, dl, types.SettingsFilter{})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d StoreDecoder) decodeSettingValue(ctx context.Context, s store.Storer, dl dal.FullService, f types.SettingsFilter) (out envoyx.NodeSet, err error) {
|
||||
// @todo this might need to be improved.
|
||||
// Currently, no resource is vast enough to pose a problem.
|
||||
rr, _, err := store.SearchSettingValues(ctx, s, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, r := range rr {
|
||||
var n *envoyx.Node
|
||||
n, err = SettingValueToEnvoyNode(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func SettingValueToEnvoyNode(r *types.SettingValue) (node *envoyx.Node, err error) {
|
||||
// SettingValues don't have references so it can be omitted
|
||||
|
||||
node = &envoyx.Node{
|
||||
Resource: r,
|
||||
ResourceType: types.SettingValueResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(
|
||||
r.Name,
|
||||
),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d StoreDecoder) extendedApigwRouteDecoder(ctx context.Context, s store.Storer, dl dal.FullService, f types.ApigwRouteFilter, base envoyx.NodeSet) (out envoyx.NodeSet, err error) {
|
||||
for _, b := range base {
|
||||
route := b.Resource.(*types.ApigwRoute)
|
||||
|
||||
filters, err := d.decodeApigwFilter(ctx, s, dl, types.ApigwFilterFilter{
|
||||
RouteID: route.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out = append(out, filters...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func decodeAuthClientRefs(c *types.AuthClient) (refs map[string]envoyx.Ref) {
|
||||
refs = make(map[string]envoyx.Ref, 4)
|
||||
|
||||
if c.Security.ImpersonateUser > 0 {
|
||||
refs["Security.ImpersonateUser"] = envoyx.Ref{
|
||||
ResourceType: types.UserResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(c.Security.ImpersonateUser),
|
||||
}
|
||||
}
|
||||
|
||||
roleSliceToRefs(refs, "Security.PermittedRoles", c.Security.PermittedRoles)
|
||||
roleSliceToRefs(refs, "Security.ProhibitedRoles", c.Security.ProhibitedRoles)
|
||||
roleSliceToRefs(refs, "Security.ForcedRoles", c.Security.ForcedRoles)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func decodeDalConnectionRefs(c *types.DalConnection) (refs map[string]envoyx.Ref) {
|
||||
if c.Config.Privacy.SensitivityLevelID == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
refs = map[string]envoyx.Ref{
|
||||
"Config.Privacy.SensitivityLevelID": {
|
||||
ResourceType: types.DalSensitivityLevelResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(c.Config.Privacy.SensitivityLevelID),
|
||||
},
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func roleSliceToRefs(refs map[string]envoyx.Ref, k string, rr []string) {
|
||||
for i, r := range rr {
|
||||
refs[fmt.Sprintf("%s.%d.RoleID", k, i)] = envoyx.Ref{
|
||||
ResourceType: types.RoleResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(r),
|
||||
}
|
||||
}
|
||||
}
|
||||
2458
server/system/envoy/store_encode.gen.go
generated
Normal file
2458
server/system/envoy/store_encode.gen.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
173
server/system/envoy/store_encode.go
Normal file
173
server/system/envoy/store_encode.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
)
|
||||
|
||||
func (e StoreEncoder) prepare(ctx context.Context, p envoyx.EncodeParams, s store.Storer, rt string, nn envoyx.NodeSet) (err error) {
|
||||
switch rt {
|
||||
case rbac.RuleResourceType:
|
||||
return e.prepareRbacRule(ctx, p, s, nn)
|
||||
case types.ResourceTranslationResourceType:
|
||||
return e.prepareResourceTranslation(ctx, p, s, nn)
|
||||
case types.SettingValueResourceType:
|
||||
return e.prepareSetting(ctx, p, s, nn)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) encode(ctx context.Context, p envoyx.EncodeParams, s store.Storer, rt string, nn envoyx.NodeSet, tree envoyx.Traverser) (err error) {
|
||||
switch rt {
|
||||
case rbac.RuleResourceType:
|
||||
return e.encodeRbacRules(ctx, p, s, nn, tree)
|
||||
case types.ResourceTranslationResourceType:
|
||||
return e.encodeResourceTranslations(ctx, p, s, nn, tree)
|
||||
case types.SettingValueResourceType:
|
||||
return e.encodeSettings(ctx, p, s, nn, tree)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setApplicationDefaults(res *types.Application) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
if res.Unify == nil {
|
||||
res.Unify = &types.ApplicationUnify{}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateApplication(res *types.Application) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setApigwRouteDefaults(res *types.ApigwRoute) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateApigwRoute(res *types.ApigwRoute) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setApigwFilterDefaults(res *types.ApigwFilter) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateApigwFilter(res *types.ApigwFilter) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setAuthClientDefaults(res *types.AuthClient) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateAuthClient(res *types.AuthClient) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setQueueDefaults(res *types.Queue) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateQueue(res *types.Queue) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setReportDefaults(res *types.Report) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateReport(res *types.Report) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setRoleDefaults(res *types.Role) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateRole(res *types.Role) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setTemplateDefaults(res *types.Template) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateTemplate(res *types.Template) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setUserDefaults(res *types.User) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateUser(res *types.User) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setDalConnectionDefaults(res *types.DalConnection) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateDalConnection(res *types.DalConnection) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) setDalSensitivityLevelDefaults(res *types.DalSensitivityLevel) (err error) {
|
||||
if res.CreatedAt.IsZero() {
|
||||
res.CreatedAt = time.Now()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e StoreEncoder) validateDalSensitivityLevel(res *types.DalSensitivityLevel) (err error) {
|
||||
return
|
||||
}
|
||||
123
server/system/envoy/store_encode_locale.go
Normal file
123
server/system/envoy/store_encode_locale.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"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/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (e StoreEncoder) prepareResourceTranslation(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet) (err error) {
|
||||
// @todo existing resource translations?
|
||||
for _, n := range nn {
|
||||
if n.Resource == nil {
|
||||
panic("unexpected state: cannot call prepareResourceTranslation with nodes without a defined Resource")
|
||||
}
|
||||
|
||||
res, ok := n.Resource.(*types.ResourceTranslation)
|
||||
if !ok {
|
||||
panic("unexpected resource type: node expecting type of ResourceTranslation")
|
||||
}
|
||||
|
||||
// Run expressions on the nodes
|
||||
err = e.runEvals(ctx, false, n)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
res.ID = id.Next()
|
||||
|
||||
// @todo merge conflicts if we do existing assertion
|
||||
|
||||
n.Resource = res
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeResourceTranslations encodes a set of resource into the database
|
||||
func (e StoreEncoder) encodeResourceTranslations(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet, tree envoyx.Traverser) (err error) {
|
||||
seen := make(map[string]uint64)
|
||||
|
||||
for _, n := range nn {
|
||||
err = e.encodeResourceTranslation(ctx, p, s, n, tree, seen)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeResourceTranslation encodes the resource into the database
|
||||
func (e StoreEncoder) encodeResourceTranslation(ctx context.Context, p envoyx.EncodeParams, s store.Storer, n *envoyx.Node, tree envoyx.Traverser, seen map[string]uint64) (err error) {
|
||||
// Grab dependency references
|
||||
var auxID uint64
|
||||
err = func() (err error) {
|
||||
for fieldLabel, ref := range n.References {
|
||||
auxID = safeParentID(tree, n, ref)
|
||||
err = n.Resource.SetValue(fieldLabel, 0, auxID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("failed to set dependency references for %s %s", n.ResourceType, n.Resource))
|
||||
return
|
||||
}
|
||||
|
||||
res := n.Resource.(*types.ResourceTranslation)
|
||||
|
||||
// Reuse the ID of the matching translation so the upsert updates it instead
|
||||
// of tripping the unique (lang, resource, key) constraint; translations can
|
||||
// repeat inside the import batch or already exist in the database
|
||||
key := strings.ToLower(res.Lang.String() + "|" + res.Resource + "|" + res.K)
|
||||
if ID, ok := seen[key]; ok {
|
||||
res.ID = ID
|
||||
} else {
|
||||
if err = e.setExistingResourceTranslationID(ctx, s, res); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
seen[key] = res.ID
|
||||
}
|
||||
|
||||
// Flush to the DB
|
||||
err = store.UpsertResourceTranslation(ctx, s, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// setExistingResourceTranslationID looks up the stored translation with the
|
||||
// same (lang, resource, key) and reuses its ID; deleted translations are
|
||||
// matched too as the unique constraint covers them as well
|
||||
func (e StoreEncoder) setExistingResourceTranslationID(ctx context.Context, s store.Storer, res *types.ResourceTranslation) (err error) {
|
||||
ee, _, err := store.SearchResourceTranslations(ctx, s, types.ResourceTranslationFilter{
|
||||
Lang: res.Lang.String(),
|
||||
Resource: res.Resource,
|
||||
Deleted: filter.StateInclusive,
|
||||
})
|
||||
if err != nil && err != store.ErrNotFound {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, ex := range ee {
|
||||
if strings.EqualFold(ex.K, res.K) {
|
||||
res.ID = ex.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
77
server/system/envoy/store_encode_rbac.go
Normal file
77
server/system/envoy/store_encode_rbac.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (e StoreEncoder) prepareRbacRule(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet) (err error) {
|
||||
// @todo existing RBAC rules?
|
||||
for _, n := range nn {
|
||||
if n.Resource == nil {
|
||||
panic("unexpected state: cannot call prepareRbacRule with nodes without a defined Resource")
|
||||
}
|
||||
|
||||
res, ok := n.Resource.(*rbac.Rule)
|
||||
if !ok {
|
||||
panic("unexpected resource type: node expecting type of RbacRule")
|
||||
}
|
||||
|
||||
// Run expressions on the nodes
|
||||
err = e.runEvals(ctx, false, n)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// @todo merge conflicts if we do existing assertion
|
||||
|
||||
n.Resource = res
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeRbacRules encodes a set of resource into the database
|
||||
func (e StoreEncoder) encodeRbacRules(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet, tree envoyx.Traverser) (err error) {
|
||||
for _, n := range nn {
|
||||
err = e.encodeRbacRule(ctx, p, s, n, tree)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeRbacRule encodes the resource into the database
|
||||
func (e StoreEncoder) encodeRbacRule(ctx context.Context, p envoyx.EncodeParams, s store.Storer, n *envoyx.Node, tree envoyx.Traverser) (err error) {
|
||||
// Grab dependency references
|
||||
var auxID uint64
|
||||
err = func() (err error) {
|
||||
for fieldLabel, ref := range n.References {
|
||||
auxID = safeParentID(tree, n, ref)
|
||||
err = n.Resource.SetValue(fieldLabel, 0, auxID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("failed to set dependency references for %s %s", n.ResourceType, n.Resource))
|
||||
return
|
||||
}
|
||||
|
||||
// Flush to the DB
|
||||
err = store.UpsertRbacRule(ctx, s, n.Resource.(*rbac.Rule))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
68
server/system/envoy/store_encode_setting.go
Normal file
68
server/system/envoy/store_encode_setting.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
systemTypes "github.com/cortezaproject/corteza/server/system/types"
|
||||
)
|
||||
|
||||
func (e StoreEncoder) prepareSetting(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet) (err error) {
|
||||
// @todo existing settings?
|
||||
for _, n := range nn {
|
||||
if n.Resource == nil {
|
||||
panic("unexpected state: cannot call prepareSetting with nodes without a defined Resource")
|
||||
}
|
||||
|
||||
res, ok := n.Resource.(*types.SettingValue)
|
||||
if !ok {
|
||||
panic("unexpected resource type: node expecting type of SettingValue")
|
||||
}
|
||||
|
||||
// Run expressions on the nodes
|
||||
err = e.runEvals(ctx, false, n)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// @todo merge conflicts if we do existing assertion
|
||||
|
||||
if res.UpdatedAt.IsZero() {
|
||||
res.UpdatedAt = time.Now()
|
||||
}
|
||||
|
||||
n.Resource = res
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeSettings encodes a set of resource into the database
|
||||
func (e StoreEncoder) encodeSettings(ctx context.Context, p envoyx.EncodeParams, s store.Storer, nn envoyx.NodeSet, tree envoyx.Traverser) (err error) {
|
||||
for _, n := range nn {
|
||||
err = e.encodeSetting(ctx, p, s, n, tree)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// encodeSetting encodes the resource into the database
|
||||
func (e StoreEncoder) encodeSetting(ctx context.Context, p envoyx.EncodeParams, s store.Storer, n *envoyx.Node, tree envoyx.Traverser) (err error) {
|
||||
// SettingValues don't have any references so there is no need to handle them
|
||||
|
||||
// Flush to the DB
|
||||
if !n.Evaluated.Skip {
|
||||
err = store.UpsertSettingValue(ctx, s, n.Resource.(*systemTypes.SettingValue))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
119
server/system/envoy/user_getter.go
Normal file
119
server/system/envoy/user_getter.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
type (
|
||||
// UserGetter is a utility struct to resolve user references from
|
||||
// different parts of the system such as the dep graph and the database
|
||||
UserGetter struct {
|
||||
depGraph *envoyx.DepGraph
|
||||
|
||||
store store.Storer
|
||||
baseFilter types.UserFilter
|
||||
|
||||
// resolved refs, including misses; imports resolve the same handful
|
||||
// of refs over and over so this saves a query per value
|
||||
cache map[string]uint64
|
||||
}
|
||||
)
|
||||
|
||||
func MakeUserGetter(s store.Storer, tt envoyx.Traverser) (g *UserGetter) {
|
||||
g = &UserGetter{
|
||||
store: s,
|
||||
cache: make(map[string]uint64),
|
||||
}
|
||||
|
||||
g.baseFilter = types.UserFilter{}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resolve returns the user ID for the provided reference
|
||||
//
|
||||
// If the user can not be resolved, 0 is returned.
|
||||
func (g *UserGetter) Resolve(ctx context.Context, ref any) (out uint64, err error) {
|
||||
// Try to get from datasource
|
||||
if g.depGraph != nil {
|
||||
out, err = g.getDS(ref)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if out > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Try to get from the database
|
||||
out, err = g.getDB(ctx, ref)
|
||||
return
|
||||
}
|
||||
|
||||
func (g *UserGetter) getDS(ref any) (out uint64, err error) {
|
||||
n := g.depGraph.NodeForRef(envoyx.Ref{
|
||||
ResourceType: types.UserResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(ref),
|
||||
})
|
||||
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
|
||||
return n.Resource.GetID(), nil
|
||||
}
|
||||
|
||||
// @todo this can be improved by prefetching and indexing refs
|
||||
func (g *UserGetter) getDB(ctx context.Context, ref any) (out uint64, err error) {
|
||||
aux := strings.TrimSpace(cast.ToString(ref))
|
||||
|
||||
// Nothing to resolve; without this the query below would match any user
|
||||
if aux == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// Numeric references are user IDs (record exports write IDs); keep them
|
||||
// as-is instead of reinterpreting them as a name/email query — the query
|
||||
// could substring-match an unrelated user, and unresolvable IDs (deleted
|
||||
// or purged users) round-tripped verbatim before user refs were resolved
|
||||
// through this getter.
|
||||
if id := cast.ToUint64(aux); id > 0 {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
if out, ok := g.cache[aux]; ok {
|
||||
return out, nil
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
g.cache[aux] = out
|
||||
}
|
||||
}()
|
||||
|
||||
f := g.baseFilter
|
||||
// @todo expand this
|
||||
f.Query = aux
|
||||
|
||||
set, _, err := store.SearchUsers(ctx, g.store, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(set) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if len(set) > 1 {
|
||||
err = fmt.Errorf("ambiguous reference %v: matches more then one user", ref)
|
||||
return
|
||||
}
|
||||
|
||||
return set[0].ID, nil
|
||||
}
|
||||
3779
server/system/envoy/yaml_decode.gen.go
generated
Normal file
3779
server/system/envoy/yaml_decode.gen.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
211
server/system/envoy/yaml_decode.go
Normal file
211
server/system/envoy/yaml_decode.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/pkg/y7s"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
systemTypes "github.com/cortezaproject/corteza/server/system/types"
|
||||
sqlt "github.com/jmoiron/sqlx/types"
|
||||
"golang.org/x/text/language"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func (d *auxYamlDoc) unmarshalYAML(k string, n *yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
switch k {
|
||||
case "settings", "setting":
|
||||
out, err = d.unmarshalSettingsNode(n)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *auxYamlDoc) unmarshalSettingsNode(n *yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
out = make(envoyx.NodeSet, 0, len(n.Content))
|
||||
|
||||
err = y7s.Each(n, func(k, v *yaml.Node) (err error) {
|
||||
if v == nil {
|
||||
return y7s.NodeErr(n, "malformed setting definition")
|
||||
}
|
||||
|
||||
s := &types.SettingValue{}
|
||||
switch v.Kind {
|
||||
case yaml.MappingNode:
|
||||
if err = v.Decode(&s); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
default:
|
||||
if err = y7s.DecodeScalar(k, "setting name", &s.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if y7s.IsKind(v, yaml.SequenceNode) {
|
||||
aux := make([]interface{}, 0, 10)
|
||||
|
||||
y7s.EachSeq(v, func(n *yaml.Node) error {
|
||||
var vx interface{}
|
||||
err := y7s.DecodeScalar(n, "setting value", &vx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aux = append(aux, vx)
|
||||
return nil
|
||||
})
|
||||
|
||||
m, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Value = sqlt.JSONText(m)
|
||||
} else if y7s.IsKind(v, yaml.MappingNode) {
|
||||
aux := make(map[string]interface{})
|
||||
|
||||
y7s.EachMap(v, func(k, v *yaml.Node) error {
|
||||
var vx interface{}
|
||||
err := y7s.DecodeScalar(v, "setting value", &vx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aux[k.Value] = vx
|
||||
return nil
|
||||
})
|
||||
|
||||
m, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Value = sqlt.JSONText(m)
|
||||
} else {
|
||||
var aux interface{}
|
||||
err = y7s.DecodeScalar(v, "setting value", &aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m, err := json.Marshal(aux)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Value = sqlt.JSONText(m)
|
||||
}
|
||||
}
|
||||
|
||||
out = append(out, &envoyx.Node{
|
||||
Resource: s,
|
||||
ResourceType: types.SettingValueResourceType,
|
||||
})
|
||||
return
|
||||
})
|
||||
|
||||
err = y7s.EachMap(n, func(lang, loc *yaml.Node) error {
|
||||
langTag := systemTypes.Lang{Tag: language.Make(lang.Value)}
|
||||
|
||||
return y7s.EachMap(loc, func(res, kv *yaml.Node) error {
|
||||
return y7s.EachMap(kv, func(k, msg *yaml.Node) error {
|
||||
out = append(out, &envoyx.Node{
|
||||
Resource: &systemTypes.ResourceTranslation{
|
||||
Resource: res.Value,
|
||||
Lang: langTag,
|
||||
K: k.Value,
|
||||
Message: msg.Value,
|
||||
},
|
||||
// Providing resource type as plain text to reduce cross component references
|
||||
ResourceType: "corteza::system:resource-translation",
|
||||
References: envoyx.SplitResourceIdentifier(res.Value),
|
||||
})
|
||||
return nil
|
||||
})
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, o := range out {
|
||||
for _, r := range o.References {
|
||||
if r.Scope.IsEmpty() {
|
||||
continue
|
||||
}
|
||||
o.Scope = r.Scope
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *auxYamlDoc) unmarshalFiltersExtendedNode(dctx documentContext, n *yaml.Node, meta ...*yaml.Node) (out envoyx.NodeSet, err error) {
|
||||
return d.unmarshalApigwFilterNode(dctx, n, meta...)
|
||||
}
|
||||
|
||||
func (d *auxYamlDoc) unmarshalUserRolesNode(r *types.User, n *yaml.Node) (refs map[string]envoyx.Ref, idents envoyx.Identifiers, err error) {
|
||||
refs = make(map[string]envoyx.Ref, len(n.Content))
|
||||
|
||||
i := 0
|
||||
err = y7s.EachSeq(n, func(n *yaml.Node) error {
|
||||
refs[fmt.Sprintf("Roles.%d", i)] = envoyx.Ref{
|
||||
ResourceType: types.RoleResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(n.Value),
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (d *auxYamlDoc) unmarshalAuthClientSecurityNode(r *types.AuthClient, n *yaml.Node) (refs map[string]envoyx.Ref, idents envoyx.Identifiers, err error) {
|
||||
refs = make(map[string]envoyx.Ref)
|
||||
|
||||
err = y7s.EachMap(n, func(k, v *yaml.Node) (err error) {
|
||||
switch strings.ToLower(k.Value) {
|
||||
case "impersonateuser":
|
||||
var av string
|
||||
err = y7s.DecodeScalar(v, "Impersonate user", &av)
|
||||
|
||||
refs["Security.ImpersonateUser"] = envoyx.Ref{
|
||||
ResourceType: types.UserResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(av),
|
||||
}
|
||||
break
|
||||
|
||||
case "permittedroles":
|
||||
refs = envoyx.MergeRefs(refs, roleNodeSliceToRefs("Security.PermittedRoles", v))
|
||||
break
|
||||
|
||||
case "prohibitedroles":
|
||||
refs = envoyx.MergeRefs(refs, roleNodeSliceToRefs("Security.ProhibitedRoles", v))
|
||||
break
|
||||
|
||||
case "forcedroles":
|
||||
refs = envoyx.MergeRefs(refs, roleNodeSliceToRefs("Security.ForcedRoles", v))
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func roleNodeSliceToRefs(k string, n *yaml.Node) (refs map[string]envoyx.Ref) {
|
||||
refs = make(map[string]envoyx.Ref, len(n.Content))
|
||||
|
||||
i := 0
|
||||
y7s.EachSeq(n, func(n *yaml.Node) error {
|
||||
refs[fmt.Sprintf("%s.%d", k, i)] = envoyx.Ref{
|
||||
ResourceType: types.RoleResourceType,
|
||||
Identifiers: envoyx.MakeIdentifiers(n.Value),
|
||||
}
|
||||
i++
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
1121
server/system/envoy/yaml_encode.gen.go
generated
Normal file
1121
server/system/envoy/yaml_encode.gen.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
339
server/system/envoy/yaml_encode.go
Normal file
339
server/system/envoy/yaml_encode.go
Normal file
@@ -0,0 +1,339 @@
|
||||
package envoy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/envoyx"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/pkg/y7s"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type (
|
||||
// Wrapper to avoid constant type casting for role nodes
|
||||
rbacRuleWrap struct {
|
||||
node *envoyx.Node
|
||||
rule *rbac.Rule
|
||||
}
|
||||
|
||||
// Wrapper to keep role and rules together
|
||||
rbacRuleRoleWrap struct {
|
||||
rules []rbacRuleWrap
|
||||
roleNode *envoyx.Node
|
||||
role *types.Role
|
||||
}
|
||||
)
|
||||
|
||||
func (e YamlEncoder) encode(ctx context.Context, base *yaml.Node, p envoyx.EncodeParams, rt string, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
switch rt {
|
||||
case rbac.RuleResourceType:
|
||||
return e.encodeRbacRules(ctx, base, p, nodes, tt)
|
||||
case types.ResourceTranslationResourceType:
|
||||
return e.encodeResourceTranslations(ctx, base, p, nodes, tt)
|
||||
case types.SettingValueResourceType:
|
||||
return e.encodeSettingValues(ctx, base, p, nodes, tt)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeResourceTranslations(ctx context.Context, base *yaml.Node, p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
err = e.resolveRulePathDeps(ctx, tt, nodes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
byLang := make(map[string][]*envoyx.Node)
|
||||
|
||||
for _, n := range nodes {
|
||||
byLang[n.Resource.(*types.ResourceTranslation).Lang.String()] = append(byLang[n.Resource.(*types.ResourceTranslation).Lang.String()], n)
|
||||
}
|
||||
|
||||
out = base
|
||||
|
||||
var aux *yaml.Node
|
||||
for lang, nodes := range byLang {
|
||||
aux, err = e.encodeResourceTranslationsByResource(p, nodes, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddMap(out, lang, aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return y7s.MakeMap("locale", out)
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeResourceTranslationsByResource(p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
byResource := make(map[string][]*envoyx.Node)
|
||||
|
||||
for _, n := range nodes {
|
||||
byResource[n.Resource.(*types.ResourceTranslation).Resource] = append(byResource[n.Resource.(*types.ResourceTranslation).Resource], n)
|
||||
}
|
||||
|
||||
var aux *yaml.Node
|
||||
for resource, nodes := range byResource {
|
||||
aux, err = e.encodeResourceTranslationsKv(p, nodes, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddMap(out, resource, aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeResourceTranslationsKv(p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
out, _ = y7s.MakeMap()
|
||||
|
||||
for _, n := range nodes {
|
||||
rt := n.Resource.(*types.ResourceTranslation)
|
||||
out, err = y7s.AddMap(out, rt.K, rt.Message)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeRbacRules(ctx context.Context, base *yaml.Node, p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
err = e.resolveRulePathDeps(ctx, tt, nodes)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Batch by access (allow, deny)
|
||||
allows := make([]rbacRuleWrap, 0, len(nodes))
|
||||
denies := make([]rbacRuleWrap, 0, len(nodes))
|
||||
for _, n := range nodes {
|
||||
r := n.Resource.(*rbac.Rule)
|
||||
if r.Access == rbac.Allow {
|
||||
allows = append(allows, rbacRuleWrap{
|
||||
node: n,
|
||||
rule: r,
|
||||
})
|
||||
} else {
|
||||
denies = append(denies, rbacRuleWrap{
|
||||
node: n,
|
||||
rule: r,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Encode allows
|
||||
var aux *yaml.Node
|
||||
aux, err = e.encodeRbacRulesByRole(p, allows, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out = base
|
||||
out, err = y7s.AddMap(out, "allow", aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Encode denies
|
||||
aux, err = e.encodeRbacRulesByRole(p, denies, tt)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
out, err = y7s.AddMap(out, "deny", aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeSettingValues(ctx context.Context, base *yaml.Node, p envoyx.EncodeParams, nodes envoyx.NodeSet, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
// Setting values don't have any refs
|
||||
|
||||
for _, n := range nodes {
|
||||
sv := n.Resource.(*types.SettingValue)
|
||||
base, err = y7s.AddMap(base, sv.Name, sv.Value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return y7s.MakeMap("settings", base)
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeRbacRulesByRole(p envoyx.EncodeParams, rules []rbacRuleWrap, tt envoyx.Traverser) (out *yaml.Node, err error) {
|
||||
// Batch by role; make sure to keep the multiple identifier thing in mind
|
||||
byRole := make(map[string]rbacRuleRoleWrap)
|
||||
for _, r := range rules {
|
||||
role := r.node.References["RoleID"]
|
||||
aux := rbacRuleRoleWrap{}
|
||||
ok := false
|
||||
|
||||
// Check if an identifier already exists
|
||||
for _, ident := range role.Identifiers.Slice {
|
||||
aux, ok = byRole[ident]
|
||||
if ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If not, create a new entry and resolve the role
|
||||
if !ok {
|
||||
aux.roleNode = tt.ParentForRef(r.node, role)
|
||||
if aux.roleNode != nil {
|
||||
aux.role = aux.roleNode.Resource.(*types.Role)
|
||||
}
|
||||
}
|
||||
|
||||
// Add the rule to the batch and update potentially missing identifiers
|
||||
aux.rules = append(aux.rules, r)
|
||||
for _, ident := range role.Identifiers.Slice {
|
||||
byRole[ident] = aux
|
||||
}
|
||||
}
|
||||
|
||||
// Encode
|
||||
var aux *yaml.Node
|
||||
for _, r := range byRole {
|
||||
aux, err = e.encodeRbacRulesByResource(p, r.rules)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddMap(out,
|
||||
r.roleNode.Identifiers.FriendlyIdentifier(), aux,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeRbacRulesByResource(p envoyx.EncodeParams, rules []rbacRuleWrap) (out *yaml.Node, err error) {
|
||||
byResource := make(map[string][]rbacRuleWrap)
|
||||
|
||||
// Batch
|
||||
for _, r := range rules {
|
||||
byResource[r.rule.Resource] = append(byResource[r.rule.Resource], r)
|
||||
}
|
||||
|
||||
// Encode
|
||||
var aux *yaml.Node
|
||||
for resource, rules := range byResource {
|
||||
aux, err = e.encodeRbacRuleOperations(p, rules)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out, err = y7s.AddMap(out, resource, aux)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeRbacRuleOperations(p envoyx.EncodeParams, rules []rbacRuleWrap) (out *yaml.Node, err error) {
|
||||
ops, _ := y7s.MakeSeq()
|
||||
|
||||
for _, r := range rules {
|
||||
ops, err = y7s.AddSeq(ops, r.rule.Operation)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return ops, nil
|
||||
}
|
||||
|
||||
func (e YamlEncoder) resolveRulePathDeps(ctx context.Context, tt envoyx.Traverser, nodes envoyx.NodeSet) (err error) {
|
||||
for _, n := range nodes {
|
||||
|
||||
var auxIdent string
|
||||
for fieldLabel, ref := range n.References {
|
||||
// Only resolve path refs; others are done later on
|
||||
if !strings.Contains(fieldLabel, "Path.") {
|
||||
continue
|
||||
}
|
||||
|
||||
auxIdent = safeParentIdentifier(tt, n, ref)
|
||||
if auxIdent == "" || auxIdent == "0" {
|
||||
continue
|
||||
}
|
||||
|
||||
err = n.Resource.SetValue(fieldLabel, 0, auxIdent)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeAuthClientSecurityC(ctx context.Context, p envoyx.EncodeParams, tt envoyx.Traverser, n *envoyx.Node, ac *types.AuthClient, sec *types.AuthClientSecurity) (_ any, err error) {
|
||||
sqPermittedRoles, err := e.encodeRoleSlice(n, tt, "Security.PermittedRoles", sec.PermittedRoles)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sqProhibitedRoles, err := e.encodeRoleSlice(n, tt, "Security.ProhibitedRoles", sec.ProhibitedRoles)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sqForcedRoles, err := e.encodeRoleSlice(n, tt, "Security.ForcedRoles", sec.ForcedRoles)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var impersonateUser string
|
||||
if _, ok := n.References["Security.ImpersonateUser.UserID"]; ok {
|
||||
usrRef := n.References["Security.ImpersonateUser.UserID"]
|
||||
node := tt.ParentForRef(n, usrRef)
|
||||
if node == nil {
|
||||
err = fmt.Errorf("invalid user reference %v: user does not exist", usrRef)
|
||||
return
|
||||
}
|
||||
impersonateUser = n.Identifiers.FriendlyIdentifier()
|
||||
}
|
||||
|
||||
return y7s.MakeMap(
|
||||
"impersonateUser", impersonateUser,
|
||||
"permittedRoles", sqPermittedRoles,
|
||||
"prohibitedRoles", sqProhibitedRoles,
|
||||
"forcedRoles", sqForcedRoles,
|
||||
)
|
||||
}
|
||||
|
||||
func (e YamlEncoder) encodeRoleSlice(n *envoyx.Node, tt envoyx.Traverser, k string, rr []string) (out *yaml.Node, err error) {
|
||||
sq, _ := y7s.MakeSeq()
|
||||
|
||||
for i := range rr {
|
||||
roleRef := n.References[fmt.Sprintf("%s.%d.RoleID", k, i)]
|
||||
node := tt.ParentForRef(n, roleRef)
|
||||
if node == nil {
|
||||
err = fmt.Errorf("invalid user reference %v: user does not exist", roleRef)
|
||||
return
|
||||
}
|
||||
|
||||
sq, err = y7s.AddSeq(sq, node.Identifiers.FriendlyIdentifier())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return sq, nil
|
||||
}
|
||||
Reference in New Issue
Block a user