Add resource load&check on access-control
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 != _|_ {
|
||||
|
||||
Reference in New Issue
Block a user