3
0

Add resource load&check on access-control

This commit is contained in:
Denis Arh
2022-07-24 11:50:56 +02:00
parent 805b160ec0
commit 74d0dfd6de
8 changed files with 237 additions and 260 deletions

View File

@@ -14,16 +14,13 @@ import (
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
"strings"
)
type (
roleMemberSearcher interface {
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
}
rbacService interface {
Can(rbac.Session, string, rbac.Resource) bool
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
@@ -34,14 +31,14 @@ type (
accessControl struct {
actionlog actionlog.Recorder
store roleMemberSearcher
store store.Storer
rbac rbacService
}
)
func AccessControl(rms roleMemberSearcher) *accessControl {
func AccessControl(s store.Storer) *accessControl {
return &accessControl{
store: rms,
store: s,
rbac: rbac.Global(),
actionlog: DefaultActionlog,
}
@@ -76,6 +73,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
}
var (
resource rbac.Resource
resources []rbac.Resource
members systemTypes.RoleMemberSet
)
@@ -86,7 +84,12 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
return nil, fmt.Errorf("can not use resource %q: %w", r, err)
}
resources = append(resources, rbac.NewResource(r))
resource, err = svc.resourceLoader(ctx, r)
if err != nil {
return
}
resources = append(resources, resource)
}
} else {
resources = svc.Resources()
@@ -436,7 +439,26 @@ func rbacResourceValidator(r string, oo ...string) error {
return rbacComponentResourceValidator(r, oo...)
}
return fmt.Errorf("unknown resource type '%q'", r)
return fmt.Errorf("unknown resource type %q", r)
}
// resourceLoader loads resource from store
//
// function assumes existence of loader functions for all resource types
//
// This function is auto-generated
func (svc accessControl) resourceLoader(ctx context.Context, resource string) (rbac.Resource, error) {
resourceType, ids := rbac.ParseResourceID(resource)
switch rbac.ResourceType(resourceType) {
case types.WorkflowResourceType:
return loadWorkflow(ctx, svc.store, ids[0])
case types.ComponentResourceType:
return &types.Component{}, nil
}
_ = ids
return nil, fmt.Errorf("unknown resource type %q", resourceType)
}
// rbacResourceOperations returns defined operations for a requested resource

View File

@@ -7,6 +7,7 @@ import (
"github.com/spf13/cast"
"strings"
"context"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
"github.com/cortezaproject/corteza-server/pkg/filter"
@@ -19,10 +20,6 @@ import (
type (
roleMemberSearcher interface {
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
}
rbacService interface {
Can(rbac.Session, string, rbac.Resource) bool
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
@@ -33,14 +30,14 @@ type (
accessControl struct {
actionlog actionlog.Recorder
store roleMemberSearcher
store store.Storer
rbac rbacService
}
)
func AccessControl(rms roleMemberSearcher) *accessControl {
func AccessControl(s store.Storer) *accessControl {
return &accessControl{
store: rms,
store: s,
rbac: rbac.Global(),
actionlog: DefaultActionlog,
}
@@ -75,6 +72,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
}
var (
resource rbac.Resource
resources []rbac.Resource
members systemTypes.RoleMemberSet
)
@@ -85,7 +83,12 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
return nil, fmt.Errorf("can not use resource %q: %w", r, err)
}
resources = append(resources, rbac.NewResource(r))
resource, err = svc.resourceLoader(ctx, r)
if err != nil {
return
}
resources = append(resources, resource)
}
} else {
resources = svc.Resources()
@@ -294,7 +297,29 @@ func rbacResourceValidator(r string, oo ...string) error {
{{- end }}
}
return fmt.Errorf("unknown resource type '%q'", r)
return fmt.Errorf("unknown resource type %q", r)
}
// resourceLoader loads resource from store
//
// function assumes existence of loader functions for all resource types
//
// This function is auto-generated
func (svc accessControl) resourceLoader(ctx context.Context, resource string) (rbac.Resource, error) {
resourceType, ids := rbac.ParseResourceID(resource)
switch rbac.ResourceType(resourceType) {
{{- range .loaders }}
case {{ .const }}:
return {{ .funcName }}(ctx, svc.store {{ range $i := .refIndex }}, ids[{{ $i }}]{{ end }})
{{- end }}
case types.ComponentResourceType:
return &types.Component{}, nil
}
_ = ids
return nil, fmt.Errorf("unknown resource type %q", resourceType)
}
// rbacResourceOperations returns defined operations for a requested resource

View File

@@ -52,6 +52,15 @@ import (
},
]
// Operation/resource validators, grouped by resource
loaders: [
for res in cmp.resources if res.rbac != _|_ {
const: "types.\(res.expIdent)ResourceType"
funcName: "load\(res.expIdent)"
refIndex: [ { 0 }, for i, p in res.parents {i + 1} ]
},
]
// Operation/resource validators, grouped by resource
validation: [
for res in cmp.resources if res.rbac != _|_ {

View File

@@ -14,16 +14,13 @@ import (
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
"strings"
)
type (
roleMemberSearcher interface {
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
}
rbacService interface {
Can(rbac.Session, string, rbac.Resource) bool
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
@@ -34,14 +31,14 @@ type (
accessControl struct {
actionlog actionlog.Recorder
store roleMemberSearcher
store store.Storer
rbac rbacService
}
)
func AccessControl(rms roleMemberSearcher) *accessControl {
func AccessControl(s store.Storer) *accessControl {
return &accessControl{
store: rms,
store: s,
rbac: rbac.Global(),
actionlog: DefaultActionlog,
}
@@ -76,6 +73,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
}
var (
resource rbac.Resource
resources []rbac.Resource
members systemTypes.RoleMemberSet
)
@@ -86,7 +84,12 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
return nil, fmt.Errorf("can not use resource %q: %w", r, err)
}
resources = append(resources, rbac.NewResource(r))
resource, err = svc.resourceLoader(ctx, r)
if err != nil {
return
}
resources = append(resources, resource)
}
} else {
resources = svc.Resources()
@@ -120,8 +123,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
session := rbac.ParamsToSession(ctx, userID, roles...)
for _, res := range resources {
r := res.RbacResource()
for op := range rbacResourceOperations(r) {
for op := range rbacResourceOperations(res.RbacResource()) {
ee = append(ee, svc.rbac.Trace(session, op, res))
}
}
@@ -703,7 +705,36 @@ func rbacResourceValidator(r string, oo ...string) error {
return rbacComponentResourceValidator(r, oo...)
}
return fmt.Errorf("unknown resource type '%q'", r)
return fmt.Errorf("unknown resource type %q", r)
}
// resourceLoader loads resource from store
//
// function assumes existence of loader functions for all resource types
//
// This function is auto-generated
func (svc accessControl) resourceLoader(ctx context.Context, resource string) (rbac.Resource, error) {
resourceType, ids := rbac.ParseResourceID(resource)
switch rbac.ResourceType(resourceType) {
case types.ChartResourceType:
return loadChart(ctx, svc.store, ids[0], ids[1])
case types.ModuleResourceType:
return loadModule(ctx, svc.store, ids[0], ids[1])
case types.ModuleFieldResourceType:
return loadModuleField(ctx, svc.store, ids[0], ids[1], ids[2])
case types.NamespaceResourceType:
return loadNamespace(ctx, svc.store, ids[0])
case types.PageResourceType:
return loadPage(ctx, svc.store, ids[0], ids[1])
case types.RecordResourceType:
return loadRecord(ctx, svc.store, ids[0], ids[1], ids[2])
case types.ComponentResourceType:
return &types.Component{}, nil
}
_ = ids
return nil, fmt.Errorf("unknown resource type %q", resourceType)
}
// rbacResourceOperations returns defined operations for a requested resource

View File

@@ -14,16 +14,13 @@ import (
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
"strings"
)
type (
roleMemberSearcher interface {
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
}
rbacService interface {
Can(rbac.Session, string, rbac.Resource) bool
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
@@ -34,14 +31,14 @@ type (
accessControl struct {
actionlog actionlog.Recorder
store roleMemberSearcher
store store.Storer
rbac rbacService
}
)
func AccessControl(rms roleMemberSearcher) *accessControl {
func AccessControl(s store.Storer) *accessControl {
return &accessControl{
store: rms,
store: s,
rbac: rbac.Global(),
actionlog: DefaultActionlog,
}
@@ -76,6 +73,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
}
var (
resource rbac.Resource
resources []rbac.Resource
members systemTypes.RoleMemberSet
)
@@ -86,7 +84,12 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
return nil, fmt.Errorf("can not use resource %q: %w", r, err)
}
resources = append(resources, rbac.NewResource(r))
resource, err = svc.resourceLoader(ctx, r)
if err != nil {
return
}
resources = append(resources, resource)
}
} else {
resources = svc.Resources()
@@ -406,7 +409,30 @@ func rbacResourceValidator(r string, oo ...string) error {
return rbacComponentResourceValidator(r, oo...)
}
return fmt.Errorf("unknown resource type '%q'", r)
return fmt.Errorf("unknown resource type %q", r)
}
// resourceLoader loads resource from store
//
// function assumes existence of loader functions for all resource types
//
// This function is auto-generated
func (svc accessControl) resourceLoader(ctx context.Context, resource string) (rbac.Resource, error) {
resourceType, ids := rbac.ParseResourceID(resource)
switch rbac.ResourceType(resourceType) {
case types.NodeResourceType:
return loadNode(ctx, svc.store, ids[0])
case types.ExposedModuleResourceType:
return loadExposedModule(ctx, svc.store, ids[0], ids[1])
case types.SharedModuleResourceType:
return loadSharedModule(ctx, svc.store, ids[0], ids[1])
case types.ComponentResourceType:
return &types.Component{}, nil
}
_ = ids
return nil, fmt.Errorf("unknown resource type %q", resourceType)
}
// rbacResourceOperations returns defined operations for a requested resource

View File

@@ -1,6 +1,7 @@
package rbac
import (
"github.com/spf13/cast"
"path"
"strings"
)
@@ -64,6 +65,19 @@ func ResourceComponent(r string) string {
}
}
func ParseResourceID(r string) (string, []uint64) {
const sep = "/"
var (
pp = strings.Split(r, sep)
ids = make([]uint64, 0)
)
for i := 1; i < len(pp); i++ {
ids = append(ids, cast.ToUint64(pp[i]))
}
return pp[0], ids
}
// match returns true if the given resource matches the given pattern
func matchResource(matcher, resource string) (m bool) {
if matcher == resource {

View File

@@ -139,3 +139,26 @@ func TestIsSpecific(t *testing.T) {
})
}
}
func TestParseResourceID(t *testing.T) {
var (
tcc = []struct {
in string
outType string
outIDs []uint64
}{
{"corteza::test/*/*/*", "corteza::test", []uint64{0, 0, 0}},
{"corteza::test/234/*/123", "corteza::test", []uint64{234, 0, 123}},
{"corteza::test/3/2/1", "corteza::test", []uint64{3, 2, 1}},
}
)
for _, tc := range tcc {
t.Run(tc.in, func(t *testing.T) {
outType, outIDs := ParseResourceID(tc.in)
require.Equal(t, tc.outType, outType)
require.Equal(t, tc.outIDs, outIDs)
})
}
}

View File

@@ -13,6 +13,7 @@ import (
internalAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/spf13/cast"
@@ -20,10 +21,6 @@ import (
)
type (
roleMemberSearcher interface {
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
}
rbacService interface {
Can(rbac.Session, string, rbac.Resource) bool
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
@@ -34,14 +31,14 @@ type (
accessControl struct {
actionlog actionlog.Recorder
store roleMemberSearcher
store store.Storer
rbac rbacService
}
)
func AccessControl(rms roleMemberSearcher) *accessControl {
func AccessControl(s store.Storer) *accessControl {
return &accessControl{
store: rms,
store: s,
rbac: rbac.Global(),
actionlog: DefaultActionlog,
}
@@ -76,6 +73,7 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
}
var (
resource rbac.Resource
resources []rbac.Resource
members systemTypes.RoleMemberSet
)
@@ -86,7 +84,12 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
return nil, fmt.Errorf("can not use resource %q: %w", r, err)
}
resources = append(resources, rbac.NewResource(r))
resource, err = svc.resourceLoader(ctx, r)
if err != nil {
return
}
resources = append(resources, resource)
}
} else {
resources = svc.Resources()
@@ -138,15 +141,12 @@ func (svc accessControl) Resources() []rbac.Resource {
rbac.NewResource(types.ApigwRouteRbacResource(0)),
rbac.NewResource(types.AuthClientRbacResource(0)),
rbac.NewResource(types.DataPrivacyRequestRbacResource(0)),
rbac.NewResource(types.DataPrivacyRequestCommentRbacResource(0)),
rbac.NewResource(types.QueueRbacResource(0)),
rbac.NewResource(types.QueueMessageRbacResource(0)),
rbac.NewResource(types.ReportRbacResource(0)),
rbac.NewResource(types.RoleRbacResource(0)),
rbac.NewResource(types.TemplateRbacResource(0)),
rbac.NewResource(types.UserRbacResource(0)),
rbac.NewResource(types.DalConnectionRbacResource(0)),
rbac.NewResource(types.DalSensitivityLevelRbacResource(0)),
rbac.NewResource(types.ComponentRbacResource()),
}
}
@@ -241,31 +241,6 @@ func (svc accessControl) List() (out []map[string]string) {
"any": types.QueueRbacResource(0),
"op": "queue.write",
},
{
"type": types.QueueMessageResourceType,
"any": types.QueueMessageRbacResource(0),
"op": "read",
},
{
"type": types.QueueMessageResourceType,
"any": types.QueueMessageRbacResource(0),
"op": "update",
},
{
"type": types.QueueMessageResourceType,
"any": types.QueueMessageRbacResource(0),
"op": "delete",
},
{
"type": types.QueueMessageResourceType,
"any": types.QueueMessageRbacResource(0),
"op": "queue.read",
},
{
"type": types.QueueMessageResourceType,
"any": types.QueueMessageRbacResource(0),
"op": "queue.write",
},
{
"type": types.ReportResourceType,
"any": types.ReportRbacResource(0),
@@ -764,41 +739,6 @@ func (svc accessControl) CanWriteQueueOnQueue(ctx context.Context, r *types.Queu
return svc.can(ctx, "queue.write", r)
}
// CanReadQueueMessage checks if current user can read queue
//
// This function is auto-generated
func (svc accessControl) CanReadQueueMessage(ctx context.Context, r *types.QueueMessage) bool {
return svc.can(ctx, "read", r)
}
// CanUpdateQueueMessage checks if current user can update queue
//
// This function is auto-generated
func (svc accessControl) CanUpdateQueueMessage(ctx context.Context, r *types.QueueMessage) bool {
return svc.can(ctx, "update", r)
}
// CanDeleteQueueMessage checks if current user can delete queue
//
// This function is auto-generated
func (svc accessControl) CanDeleteQueueMessage(ctx context.Context, r *types.QueueMessage) bool {
return svc.can(ctx, "delete", r)
}
// CanReadQueueOnQueueMessage checks if current user can read from queue
//
// This function is auto-generated
func (svc accessControl) CanReadQueueOnQueueMessage(ctx context.Context, r *types.QueueMessage) bool {
return svc.can(ctx, "queue.read", r)
}
// CanWriteQueueOnQueueMessage checks if current user can write to queue
//
// This function is auto-generated
func (svc accessControl) CanWriteQueueOnQueueMessage(ctx context.Context, r *types.QueueMessage) bool {
return svc.can(ctx, "queue.write", r)
}
// CanReadReport checks if current user can read report
//
// This function is auto-generated
@@ -1205,12 +1145,8 @@ func rbacResourceValidator(r string, oo ...string) error {
return rbacAuthClientResourceValidator(r, oo...)
case types.DataPrivacyRequestResourceType:
return rbacDataPrivacyRequestResourceValidator(r, oo...)
case types.DataPrivacyRequestCommentResourceType:
return rbacDataPrivacyRequestCommentResourceValidator(r, oo...)
case types.QueueResourceType:
return rbacQueueResourceValidator(r, oo...)
case types.QueueMessageResourceType:
return rbacQueueMessageResourceValidator(r, oo...)
case types.ReportResourceType:
return rbacReportResourceValidator(r, oo...)
case types.RoleResourceType:
@@ -1221,13 +1157,48 @@ func rbacResourceValidator(r string, oo ...string) error {
return rbacUserResourceValidator(r, oo...)
case types.DalConnectionResourceType:
return rbacDalConnectionResourceValidator(r, oo...)
case types.DalSensitivityLevelResourceType:
return rbacDalSensitivityLevelResourceValidator(r, oo...)
case types.ComponentResourceType:
return rbacComponentResourceValidator(r, oo...)
}
return fmt.Errorf("unknown resource type '%q'", r)
return fmt.Errorf("unknown resource type %q", r)
}
// resourceLoader loads resource from store
//
// function assumes existence of loader functions for all resource types
//
// This function is auto-generated
func (svc accessControl) resourceLoader(ctx context.Context, resource string) (rbac.Resource, error) {
resourceType, ids := rbac.ParseResourceID(resource)
switch rbac.ResourceType(resourceType) {
case types.ApplicationResourceType:
return loadApplication(ctx, svc.store, ids[0])
case types.ApigwRouteResourceType:
return loadApigwRoute(ctx, svc.store, ids[0])
case types.AuthClientResourceType:
return loadAuthClient(ctx, svc.store, ids[0])
case types.DataPrivacyRequestResourceType:
return loadDataPrivacyRequest(ctx, svc.store, ids[0])
case types.QueueResourceType:
return loadQueue(ctx, svc.store, ids[0])
case types.ReportResourceType:
return loadReport(ctx, svc.store, ids[0])
case types.RoleResourceType:
return loadRole(ctx, svc.store, ids[0])
case types.TemplateResourceType:
return loadTemplate(ctx, svc.store, ids[0])
case types.UserResourceType:
return loadUser(ctx, svc.store, ids[0])
case types.DalConnectionResourceType:
return loadDalConnection(ctx, svc.store, ids[0])
case types.ComponentResourceType:
return &types.Component{}, nil
}
_ = ids
return nil, fmt.Errorf("unknown resource type %q", resourceType)
}
// rbacResourceOperations returns defined operations for a requested resource
@@ -1259,8 +1230,6 @@ func rbacResourceOperations(r string) map[string]bool {
"read": true,
"approve": true,
}
case types.DataPrivacyRequestCommentResourceType:
return map[string]bool{}
case types.QueueResourceType:
return map[string]bool{
"read": true,
@@ -1269,14 +1238,6 @@ func rbacResourceOperations(r string) map[string]bool {
"queue.read": true,
"queue.write": true,
}
case types.QueueMessageResourceType:
return map[string]bool{
"read": true,
"update": true,
"delete": true,
"queue.read": true,
"queue.write": true,
}
case types.ReportResourceType:
return map[string]bool{
"read": true,
@@ -1315,8 +1276,6 @@ func rbacResourceOperations(r string) map[string]bool {
"update": true,
"delete": true,
}
case types.DalSensitivityLevelResourceType:
return map[string]bool{}
case types.ComponentResourceType:
return map[string]bool{
"grant": true,
@@ -1530,50 +1489,6 @@ func rbacDataPrivacyRequestResourceValidator(r string, oo ...string) error {
return nil
}
// rbacDataPrivacyRequestCommentResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacDataPrivacyRequestCommentResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.DataPrivacyRequestCommentResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for dataPrivacyRequestComment resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.DataPrivacyRequestCommentResourceType):], sep), sep)
prc = []string{
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for dataPrivacyRequestComment resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacQueueResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
@@ -1618,50 +1533,6 @@ func rbacQueueResourceValidator(r string, oo ...string) error {
return nil
}
// rbacQueueMessageResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacQueueMessageResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.QueueMessageResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for queueMessage resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.QueueMessageResourceType):], sep), sep)
prc = []string{
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for queueMessage resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacReportResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
@@ -1882,50 +1753,6 @@ func rbacDalConnectionResourceValidator(r string, oo ...string) error {
return nil
}
// rbacDalSensitivityLevelResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only
//
// This function is auto-generated
func rbacDalSensitivityLevelResourceValidator(r string, oo ...string) error {
if !strings.HasPrefix(r, types.DalSensitivityLevelResourceType) {
// expecting resource to always include path
return fmt.Errorf("invalid resource type")
}
defOps := rbacResourceOperations(r)
for _, o := range oo {
if !defOps[o] {
return fmt.Errorf("invalid operation '%s' for dalSensitivityLevel resource", o)
}
}
const sep = "/"
var (
pp = strings.Split(strings.Trim(r[len(types.DalSensitivityLevelResourceType):], sep), sep)
prc = []string{
"ID",
}
)
if len(pp) != len(prc) {
return fmt.Errorf("invalid resource path structure")
}
for i := 0; i < len(pp); i++ {
if pp[i] != "*" {
if i > 0 && pp[i-1] == "*" {
return fmt.Errorf("invalid path wildcard level (%d) for dalSensitivityLevel resource", i)
}
if _, err := cast.ToUint64E(pp[i]); err != nil {
return fmt.Errorf("invalid reference for %s: '%s'", prc[i], pp[i])
}
}
}
return nil
}
// rbacComponentResourceValidator checks validity of RBAC resource and operations
//
// Can be called without operations to check for validity of resource string only