Refactor RBAC evaluation processing
This commit is contained in:
parent
83ba7faa0f
commit
14d3b7033d
@ -15,13 +15,9 @@ type (
|
||||
ac permissionsAccessController
|
||||
}
|
||||
|
||||
rbacResWrap struct {
|
||||
res string
|
||||
}
|
||||
|
||||
permissionsAccessController interface {
|
||||
Effective(context.Context, ...rbac.Resource) rbac.EffectiveSet
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error)
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
@ -39,12 +35,7 @@ func (ctrl Permissions) Effective(ctx context.Context, r *request.PermissionsEff
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Evaluate(ctx context.Context, r *request.PermissionsEvaluate) (interface{}, error) {
|
||||
in := make([]rbac.Resource, 0, len(r.Resource))
|
||||
for _, res := range r.Resource {
|
||||
in = append(in, rbacResWrap{res: res})
|
||||
}
|
||||
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, in...)
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
|
||||
@ -76,7 +67,3 @@ func (ctrl Permissions) Update(ctx context.Context, r *request.PermissionsUpdate
|
||||
|
||||
return api.OK(), ctrl.ac.Grant(ctx, r.Rules...)
|
||||
}
|
||||
|
||||
func (ar rbacResWrap) RbacResource() string {
|
||||
return ar.res
|
||||
}
|
||||
|
||||
91
automation/service/access_control.gen.go
generated
91
automation/service/access_control.gen.go
generated
@ -12,29 +12,36 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/automation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
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 {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
actionlog actionlog.Recorder
|
||||
|
||||
roleFinder func(ctx context.Context, id uint64) ([]uint64, error)
|
||||
rbac interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
store roleMemberSearcher
|
||||
rbac rbacService
|
||||
}
|
||||
)
|
||||
|
||||
func AccessControl(rf func(ctx context.Context, id uint64) ([]uint64, error)) *accessControl {
|
||||
func AccessControl(rms roleMemberSearcher) *accessControl {
|
||||
return &accessControl{
|
||||
roleFinder: rf,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: rms,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +50,8 @@ func (svc accessControl) can(ctx context.Context, op string, res rbac.Resource)
|
||||
}
|
||||
|
||||
// Effective returns a list of effective permissions for all given resource
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee rbac.EffectiveSet) {
|
||||
for _, res := range rr {
|
||||
r := res.RbacResource()
|
||||
@ -55,38 +64,74 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
|
||||
}
|
||||
|
||||
// Evaluate returns a list of permissions evaluated for the given user/roles combo
|
||||
func (svc accessControl) Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error) {
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Evaluate(ctx context.Context, userID uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error) {
|
||||
// Reusing the grant permission since this is who the feature is for
|
||||
if !svc.CanGrant(ctx) {
|
||||
// @todo should be altered to check grant permissions PER resource
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
// Load roles for this user
|
||||
//
|
||||
// User's roles take priority over specified ones
|
||||
if user != 0 {
|
||||
rr, err := svc.roleFinder(ctx, user)
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
members systemTypes.RoleMemberSet
|
||||
)
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
resources = append(resources, rbac.NewResource(r))
|
||||
}
|
||||
} else {
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
// User ID specified, load its roles
|
||||
if userID != 0 {
|
||||
if len(roles) > 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("userID and roles are mutually exclusive")
|
||||
}
|
||||
|
||||
members, _, err = svc.store.SearchRoleMembers(ctx, systemTypes.RoleMemberFilter{UserID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(rr, roles...)
|
||||
for _, m := range members {
|
||||
roles = append(roles, m.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, user, roles...)
|
||||
for _, res := range rr {
|
||||
if len(roles) == 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
eval := svc.rbac.Evaluate(session, op, res)
|
||||
|
||||
ee = append(ee, eval)
|
||||
ee = append(ee, svc.rbac.Evaluate(session, op, res))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resources returns list of resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Resources() []rbac.Resource {
|
||||
return []rbac.Resource{
|
||||
rbac.NewResource(types.WorkflowRbacResource(0)),
|
||||
rbac.NewResource(types.ComponentRbacResource()),
|
||||
}
|
||||
}
|
||||
|
||||
// List returns list of operations on all resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{
|
||||
|
||||
@ -2,8 +2,6 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/automation/automation"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/corredor"
|
||||
@ -12,9 +10,9 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/objstore"
|
||||
"github.com/cortezaproject/corteza-server/pkg/options"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
sysTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -90,7 +88,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
|
||||
DefaultActionlog = actionlog.NewService(DefaultStore, log, tee, policy)
|
||||
}
|
||||
|
||||
DefaultAccessControl = AccessControl(RolesForUser(s))
|
||||
DefaultAccessControl = AccessControl(s)
|
||||
|
||||
DefaultSession = Session(DefaultLogger.Named("session"), c.Workflow, ws)
|
||||
DefaultWorkflow = Workflow(DefaultLogger.Named("workflow"), c.Corredor, c.Workflow)
|
||||
@ -164,19 +162,3 @@ func isStale(new *time.Time, updatedAt *time.Time, createdAt time.Time) bool {
|
||||
func trim1st(_ interface{}, err error) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// @note copied over from system/service/role@RolesForUser
|
||||
func RolesForUser(s store.Storer) func(ctx context.Context, userID uint64) ([]uint64, error) {
|
||||
return func(ctx context.Context, userID uint64) ([]uint64, error) {
|
||||
rr, _, err := store.SearchRoles(ctx, s, types.RoleFilter{MemberID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := make([]uint64, len(rr))
|
||||
for i, r := range rr {
|
||||
out[i] = r.ID
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
systemTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
{{- range .imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
@ -16,33 +17,40 @@ import (
|
||||
|
||||
|
||||
type (
|
||||
roleMemberSearcher interface {
|
||||
SearchRoleMembers(context.Context, systemTypes.RoleMemberFilter) (systemTypes.RoleMemberSet, systemTypes.RoleMemberFilter, error)
|
||||
}
|
||||
|
||||
rbacService interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
actionlog actionlog.Recorder
|
||||
|
||||
roleFinder func(ctx context.Context, id uint64) ([]uint64, error)
|
||||
rbac interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
store roleMemberSearcher
|
||||
rbac rbacService
|
||||
}
|
||||
)
|
||||
|
||||
func AccessControl(rf func(ctx context.Context, id uint64) ([]uint64, error)) *accessControl {
|
||||
func AccessControl(rms roleMemberSearcher) *accessControl {
|
||||
return &accessControl{
|
||||
roleFinder: rf,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: rms,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (svc accessControl) can(ctx context.Context, op string, res rbac.Resource) bool {
|
||||
return svc.rbac.Evaluate(rbac.ContextToSession(ctx), op, res).Can
|
||||
}
|
||||
|
||||
// Effective returns a list of effective permissions for all given resource
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Effective(ctx context.Context, rr ... rbac.Resource) (ee rbac.EffectiveSet) {
|
||||
for _, res := range rr {
|
||||
r := res.RbacResource()
|
||||
@ -55,38 +63,75 @@ func (svc accessControl) Effective(ctx context.Context, rr ... rbac.Resource) (e
|
||||
}
|
||||
|
||||
// Evaluate returns a list of permissions evaluated for the given user/roles combo
|
||||
func (svc accessControl) Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error) {
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Evaluate(ctx context.Context, userID uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error) {
|
||||
// Reusing the grant permission since this is who the feature is for
|
||||
if !svc.CanGrant(ctx) {
|
||||
// @todo should be altered to check grant permissions PER resource
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
// Load roles for this user
|
||||
//
|
||||
// User's roles take priority over specified ones
|
||||
if user != 0 {
|
||||
rr, err := svc.roleFinder(ctx, user)
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
members systemTypes.RoleMemberSet
|
||||
)
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
resources = append(resources, rbac.NewResource(r))
|
||||
}
|
||||
} else {
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
// User ID specified, load its roles
|
||||
if userID != 0 {
|
||||
if len(roles) > 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("userID and roles are mutually exclusive")
|
||||
}
|
||||
|
||||
members, _, err = svc.store.SearchRoleMembers(ctx, systemTypes.RoleMemberFilter{UserID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(rr, roles...)
|
||||
for _, m := range members {
|
||||
roles = append(roles, m.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, user, roles...)
|
||||
for _, res := range rr {
|
||||
if len(roles) == 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
eval := svc.rbac.Evaluate(session, op, res)
|
||||
|
||||
ee = append(ee, eval)
|
||||
ee = append(ee, svc.rbac.Evaluate(session, op, res))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resources returns list of resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Resources() []rbac.Resource {
|
||||
return []rbac.Resource{
|
||||
{{- range .resources }}
|
||||
rbac.NewResource({{ .resFunc }}({{ range .references }}0,{{ end }})),
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
// List returns list of operations on all resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{{- range .operations }}
|
||||
|
||||
@ -16,6 +16,18 @@ import (
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
// All known RBAC resources
|
||||
resources: [
|
||||
for res in cmp.resources if res.rbac != _|_ {
|
||||
resFunc: "types.\(res.expIdent)RbacResource"
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
},
|
||||
{
|
||||
resFunc: "types.ComponentRbacResource"
|
||||
component: true
|
||||
},
|
||||
]
|
||||
|
||||
// All possible RBAC operations on component and resources
|
||||
// flattened
|
||||
operations: [
|
||||
|
||||
@ -15,13 +15,9 @@ type (
|
||||
ac permissionsAccessController
|
||||
}
|
||||
|
||||
rbacResWrap struct {
|
||||
res string
|
||||
}
|
||||
|
||||
permissionsAccessController interface {
|
||||
Effective(context.Context, ...rbac.Resource) rbac.EffectiveSet
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error)
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
@ -39,12 +35,7 @@ func (ctrl Permissions) Effective(ctx context.Context, r *request.PermissionsEff
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Evaluate(ctx context.Context, r *request.PermissionsEvaluate) (interface{}, error) {
|
||||
in := make([]rbac.Resource, 0, len(r.Resource))
|
||||
for _, res := range r.Resource {
|
||||
in = append(in, rbacResWrap{res: res})
|
||||
}
|
||||
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, in...)
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
|
||||
@ -76,7 +67,3 @@ func (ctrl Permissions) Update(ctx context.Context, r *request.PermissionsUpdate
|
||||
|
||||
return api.OK(), ctrl.ac.Grant(ctx, r.Rules...)
|
||||
}
|
||||
|
||||
func (ar rbacResWrap) RbacResource() string {
|
||||
return ar.res
|
||||
}
|
||||
|
||||
96
compose/service/access_control.gen.go
generated
96
compose/service/access_control.gen.go
generated
@ -12,29 +12,36 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
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 {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
actionlog actionlog.Recorder
|
||||
|
||||
roleFinder func(ctx context.Context, id uint64) ([]uint64, error)
|
||||
rbac interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
store roleMemberSearcher
|
||||
rbac rbacService
|
||||
}
|
||||
)
|
||||
|
||||
func AccessControl(rf func(ctx context.Context, id uint64) ([]uint64, error)) *accessControl {
|
||||
func AccessControl(rms roleMemberSearcher) *accessControl {
|
||||
return &accessControl{
|
||||
roleFinder: rf,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: rms,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +50,8 @@ func (svc accessControl) can(ctx context.Context, op string, res rbac.Resource)
|
||||
}
|
||||
|
||||
// Effective returns a list of effective permissions for all given resource
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee rbac.EffectiveSet) {
|
||||
for _, res := range rr {
|
||||
r := res.RbacResource()
|
||||
@ -55,38 +64,79 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
|
||||
}
|
||||
|
||||
// Evaluate returns a list of permissions evaluated for the given user/roles combo
|
||||
func (svc accessControl) Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error) {
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Evaluate(ctx context.Context, userID uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error) {
|
||||
// Reusing the grant permission since this is who the feature is for
|
||||
if !svc.CanGrant(ctx) {
|
||||
// @todo should be altered to check grant permissions PER resource
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
// Load roles for this user
|
||||
//
|
||||
// User's roles take priority over specified ones
|
||||
if user != 0 {
|
||||
rr, err := svc.roleFinder(ctx, user)
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
members systemTypes.RoleMemberSet
|
||||
)
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
resources = append(resources, rbac.NewResource(r))
|
||||
}
|
||||
} else {
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
// User ID specified, load its roles
|
||||
if userID != 0 {
|
||||
if len(roles) > 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("userID and roles are mutually exclusive")
|
||||
}
|
||||
|
||||
members, _, err = svc.store.SearchRoleMembers(ctx, systemTypes.RoleMemberFilter{UserID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(rr, roles...)
|
||||
for _, m := range members {
|
||||
roles = append(roles, m.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, user, roles...)
|
||||
for _, res := range rr {
|
||||
if len(roles) == 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
eval := svc.rbac.Evaluate(session, op, res)
|
||||
|
||||
ee = append(ee, eval)
|
||||
ee = append(ee, svc.rbac.Evaluate(session, op, res))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resources returns list of resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Resources() []rbac.Resource {
|
||||
return []rbac.Resource{
|
||||
rbac.NewResource(types.ChartRbacResource(0, 0)),
|
||||
rbac.NewResource(types.ModuleRbacResource(0, 0)),
|
||||
rbac.NewResource(types.ModuleFieldRbacResource(0, 0, 0)),
|
||||
rbac.NewResource(types.NamespaceRbacResource(0)),
|
||||
rbac.NewResource(types.PageRbacResource(0, 0)),
|
||||
rbac.NewResource(types.RecordRbacResource(0, 0, 0)),
|
||||
rbac.NewResource(types.ComponentRbacResource()),
|
||||
}
|
||||
}
|
||||
|
||||
// List returns list of operations on all resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/discovery"
|
||||
|
||||
automationService "github.com/cortezaproject/corteza-server/automation/service"
|
||||
systemService "github.com/cortezaproject/corteza-server/automation/service"
|
||||
"github.com/cortezaproject/corteza-server/compose/automation"
|
||||
"github.com/cortezaproject/corteza-server/compose/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
@ -127,7 +126,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, c Config)
|
||||
}
|
||||
}
|
||||
|
||||
DefaultAccessControl = AccessControl(systemService.RolesForUser(s))
|
||||
DefaultAccessControl = AccessControl(s)
|
||||
DefaultResourceTranslation = ResourceTranslationsManager(locale.Global())
|
||||
|
||||
if DefaultObjectStore == nil {
|
||||
|
||||
@ -15,13 +15,9 @@ type (
|
||||
ac permissionsAccessController
|
||||
}
|
||||
|
||||
rbacResWrap struct {
|
||||
res string
|
||||
}
|
||||
|
||||
permissionsAccessController interface {
|
||||
Effective(context.Context, ...rbac.Resource) rbac.EffectiveSet
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error)
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
Grant(ctx context.Context, rr ...*rbac.Rule) error
|
||||
@ -39,12 +35,7 @@ func (ctrl Permissions) Effective(ctx context.Context, r *request.PermissionsEff
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Evaluate(ctx context.Context, r *request.PermissionsEvaluate) (interface{}, error) {
|
||||
in := make([]rbac.Resource, 0, len(r.Resource))
|
||||
for _, res := range r.Resource {
|
||||
in = append(in, rbacResWrap{res: res})
|
||||
}
|
||||
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, in...)
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
|
||||
@ -76,7 +67,3 @@ func (ctrl Permissions) Update(ctx context.Context, r *request.PermissionsUpdate
|
||||
|
||||
return api.OK(), ctrl.ac.Grant(ctx, r.Rules...)
|
||||
}
|
||||
|
||||
func (ar rbacResWrap) RbacResource() string {
|
||||
return ar.res
|
||||
}
|
||||
|
||||
93
federation/service/access_control.gen.go
generated
93
federation/service/access_control.gen.go
generated
@ -12,29 +12,36 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/federation/types"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
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 {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
actionlog actionlog.Recorder
|
||||
|
||||
roleFinder func(ctx context.Context, id uint64) ([]uint64, error)
|
||||
rbac interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
store roleMemberSearcher
|
||||
rbac rbacService
|
||||
}
|
||||
)
|
||||
|
||||
func AccessControl(rf func(ctx context.Context, id uint64) ([]uint64, error)) *accessControl {
|
||||
func AccessControl(rms roleMemberSearcher) *accessControl {
|
||||
return &accessControl{
|
||||
roleFinder: rf,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: rms,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +50,8 @@ func (svc accessControl) can(ctx context.Context, op string, res rbac.Resource)
|
||||
}
|
||||
|
||||
// Effective returns a list of effective permissions for all given resource
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee rbac.EffectiveSet) {
|
||||
for _, res := range rr {
|
||||
r := res.RbacResource()
|
||||
@ -55,38 +64,76 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
|
||||
}
|
||||
|
||||
// Evaluate returns a list of permissions evaluated for the given user/roles combo
|
||||
func (svc accessControl) Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error) {
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Evaluate(ctx context.Context, userID uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error) {
|
||||
// Reusing the grant permission since this is who the feature is for
|
||||
if !svc.CanGrant(ctx) {
|
||||
// @todo should be altered to check grant permissions PER resource
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
// Load roles for this user
|
||||
//
|
||||
// User's roles take priority over specified ones
|
||||
if user != 0 {
|
||||
rr, err := svc.roleFinder(ctx, user)
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
members systemTypes.RoleMemberSet
|
||||
)
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
resources = append(resources, rbac.NewResource(r))
|
||||
}
|
||||
} else {
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
// User ID specified, load its roles
|
||||
if userID != 0 {
|
||||
if len(roles) > 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("userID and roles are mutually exclusive")
|
||||
}
|
||||
|
||||
members, _, err = svc.store.SearchRoleMembers(ctx, systemTypes.RoleMemberFilter{UserID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(rr, roles...)
|
||||
for _, m := range members {
|
||||
roles = append(roles, m.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, user, roles...)
|
||||
for _, res := range rr {
|
||||
if len(roles) == 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
eval := svc.rbac.Evaluate(session, op, res)
|
||||
|
||||
ee = append(ee, eval)
|
||||
ee = append(ee, svc.rbac.Evaluate(session, op, res))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resources returns list of resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Resources() []rbac.Resource {
|
||||
return []rbac.Resource{
|
||||
rbac.NewResource(types.NodeRbacResource(0)),
|
||||
rbac.NewResource(types.ExposedModuleRbacResource(0, 0)),
|
||||
rbac.NewResource(types.SharedModuleRbacResource(0, 0)),
|
||||
rbac.NewResource(types.ComponentRbacResource()),
|
||||
}
|
||||
}
|
||||
|
||||
// List returns list of operations on all resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{
|
||||
|
||||
@ -2,21 +2,18 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
|
||||
cs "github.com/cortezaproject/corteza-server/compose/service"
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza-server/pkg/id"
|
||||
"github.com/cortezaproject/corteza-server/pkg/label"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/options"
|
||||
"github.com/cortezaproject/corteza-server/store"
|
||||
"github.com/cortezaproject/corteza-server/system/service"
|
||||
ss "github.com/cortezaproject/corteza-server/system/service"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"go.uber.org/zap"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
@ -85,11 +82,11 @@ func Initialize(_ context.Context, log *zap.Logger, s store.Storer, c Config) (e
|
||||
DefaultActionlog = actionlog.NewService(DefaultStore, log, tee, policy)
|
||||
}
|
||||
|
||||
DefaultAccessControl = AccessControl(service.RolesForUser(s))
|
||||
DefaultAccessControl = AccessControl(s)
|
||||
|
||||
DefaultNode = Node(
|
||||
DefaultStore,
|
||||
service.DefaultUser,
|
||||
ss.DefaultUser,
|
||||
DefaultActionlog,
|
||||
func(ctx context.Context, i auth.Identifiable) (token []byte, err error) {
|
||||
return auth.TokenIssuer.Issue(
|
||||
|
||||
@ -178,7 +178,7 @@ func (d *composeDecoder) decodeComposeRecord(ctx context.Context, s store.Storer
|
||||
}
|
||||
}
|
||||
|
||||
ac := service.AccessControl(nil)
|
||||
ac := service.AccessControl(s)
|
||||
|
||||
if len(d.namespaceID) > 0 {
|
||||
ffNs := make([]*composeRecordFilter, 0, len(ff)+len(d.namespaceID))
|
||||
|
||||
@ -8,29 +8,6 @@ type (
|
||||
}
|
||||
|
||||
EffectiveSet []effective
|
||||
|
||||
Evaluated struct {
|
||||
Resource string `json:"resource"`
|
||||
Operation string `json:"operation"`
|
||||
Access Access `json:"-"`
|
||||
Can bool `json:"can"`
|
||||
Step explanation `json:"step"`
|
||||
|
||||
RoleID uint64 `json:"roleID,string,omitempty"`
|
||||
Rule *Rule `json:"rule,omitempty"`
|
||||
|
||||
Default *Evaluated `json:"default,omitempty"`
|
||||
}
|
||||
EvaluatedSet []Evaluated
|
||||
|
||||
explanation string
|
||||
)
|
||||
|
||||
const (
|
||||
stepIntegrity explanation = "integrity"
|
||||
stepBypass explanation = "bypass"
|
||||
stepRuleless explanation = "ruleless"
|
||||
stepEvaluated explanation = "evaluated"
|
||||
)
|
||||
|
||||
func (ee *EffectiveSet) Push(res, op string, allow bool) {
|
||||
|
||||
27
pkg/rbac/evaluate.go
Normal file
27
pkg/rbac/evaluate.go
Normal file
@ -0,0 +1,27 @@
|
||||
package rbac
|
||||
|
||||
type (
|
||||
Evaluated struct {
|
||||
Resource string `json:"resource"`
|
||||
Operation string `json:"operation"`
|
||||
Access Access `json:"-"`
|
||||
Can bool `json:"can"`
|
||||
Step explanation `json:"step"`
|
||||
|
||||
RoleID uint64 `json:"roleID,string,omitempty"`
|
||||
Rule *Rule `json:"rule,omitempty"`
|
||||
|
||||
Default *Evaluated `json:"default,omitempty"`
|
||||
}
|
||||
|
||||
EvaluatedSet []Evaluated
|
||||
|
||||
explanation string
|
||||
)
|
||||
|
||||
const (
|
||||
stepIntegrity explanation = "integrity"
|
||||
stepBypass explanation = "bypass"
|
||||
stepRuleless explanation = "ruleless"
|
||||
stepEvaluated explanation = "evaluated"
|
||||
)
|
||||
@ -6,6 +6,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
resource string
|
||||
Resource interface {
|
||||
RbacResource() string
|
||||
}
|
||||
@ -22,6 +23,19 @@ const (
|
||||
wildcard = "*"
|
||||
)
|
||||
|
||||
// NewResource constructs untyped resource from the given string
|
||||
//
|
||||
// This is a utility method that should not be used for standard permission checking and granting
|
||||
// it's intended to be used for testing end permission evaluation where we do not have access to the resource struct
|
||||
func NewResource(s string) Resource {
|
||||
return resource(s)
|
||||
}
|
||||
|
||||
// RbacResource returns string of an untyped resource
|
||||
func (t resource) RbacResource() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
// ResourceType extracts 1st part of the resource
|
||||
//
|
||||
// ns::cmp:res/c returns ns::cmp:res
|
||||
|
||||
@ -6,14 +6,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type (
|
||||
testResource string
|
||||
)
|
||||
|
||||
func (t testResource) RbacResource() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
func Test_partitionRoles(t *testing.T) {
|
||||
var (
|
||||
req = require.New(t)
|
||||
@ -49,7 +41,7 @@ func Test_getContextRoles(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
tres = testResource("testResource")
|
||||
tres = NewResource("testResource")
|
||||
|
||||
tcc = []struct {
|
||||
name string
|
||||
|
||||
@ -110,7 +110,7 @@ func (svc *service) Check(ses Session, op string, res Resource) (v Access) {
|
||||
return access
|
||||
}
|
||||
|
||||
// Eval evaluates access for the given parameters
|
||||
// Evaluate access for the given session, operation and resource
|
||||
//
|
||||
// The evaluation outputs verbose details to assist the UI.
|
||||
func (svc *service) Evaluate(ses Session, op string, res Resource) Evaluated {
|
||||
@ -321,7 +321,7 @@ func (svc *service) SignificantRoles(res Resource, op string) (aRR, dRR []uint64
|
||||
return svc.rules.sigRoles(res.RbacResource(), op)
|
||||
}
|
||||
|
||||
func (svc service) String() (out string) {
|
||||
func (svc *service) String() (out string) {
|
||||
tpl := "%-5v %-20s to %-20s %-30s\n"
|
||||
out += strings.Repeat("-", 120) + "\n"
|
||||
|
||||
|
||||
@ -16,13 +16,9 @@ type (
|
||||
ac permissionsAccessController
|
||||
}
|
||||
|
||||
rbacResWrap struct {
|
||||
res string
|
||||
}
|
||||
|
||||
permissionsAccessController interface {
|
||||
Effective(context.Context, ...rbac.Resource) rbac.EffectiveSet
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error)
|
||||
Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error)
|
||||
List() []map[string]string
|
||||
FindRulesByRoleID(context.Context, uint64) (rbac.RuleSet, error)
|
||||
CloneRulesByRoleID(ctx context.Context, roleID uint64, toRoleID ...uint64) error
|
||||
@ -41,12 +37,7 @@ func (ctrl Permissions) Effective(ctx context.Context, r *request.PermissionsEff
|
||||
}
|
||||
|
||||
func (ctrl Permissions) Evaluate(ctx context.Context, r *request.PermissionsEvaluate) (interface{}, error) {
|
||||
in := make([]rbac.Resource, 0, len(r.Resource))
|
||||
for _, res := range r.Resource {
|
||||
in = append(in, rbacResWrap{res: res})
|
||||
}
|
||||
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, in...)
|
||||
return ctrl.ac.Evaluate(ctx, r.UserID, r.RoleID, r.Resource...)
|
||||
}
|
||||
|
||||
func (ctrl Permissions) List(ctx context.Context, r *request.PermissionsList) (interface{}, error) {
|
||||
@ -79,11 +70,10 @@ func (ctrl Permissions) Update(ctx context.Context, r *request.PermissionsUpdate
|
||||
return api.OK(), ctrl.ac.Grant(ctx, r.Rules...)
|
||||
}
|
||||
|
||||
// Clone all RBAC rules on ALL components (not just system)
|
||||
//
|
||||
// @todo needs to be moved under roles
|
||||
func (ctrl Permissions) Clone(ctx context.Context, r *request.PermissionsClone) (interface{}, error) {
|
||||
// Clone rules from role S to role T
|
||||
return api.OK(), ctrl.ac.CloneRulesByRoleID(ctx, r.RoleID, payload.ParseUint64s(r.CloneToRoleID)...)
|
||||
}
|
||||
|
||||
func (ar rbacResWrap) RbacResource() string {
|
||||
return ar.res
|
||||
}
|
||||
|
||||
103
system/service/access_control.gen.go
generated
103
system/service/access_control.gen.go
generated
@ -12,29 +12,36 @@ import (
|
||||
"github.com/cortezaproject/corteza-server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza-server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
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 {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
actionlog actionlog.Recorder
|
||||
|
||||
roleFinder func(ctx context.Context, id uint64) ([]uint64, error)
|
||||
rbac interface {
|
||||
Evaluate(rbac.Session, string, rbac.Resource) rbac.Evaluated
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
CloneRulesByRoleID(ctx context.Context, fromRoleID uint64, toRoleID ...uint64) error
|
||||
}
|
||||
store roleMemberSearcher
|
||||
rbac rbacService
|
||||
}
|
||||
)
|
||||
|
||||
func AccessControl(rf func(ctx context.Context, id uint64) ([]uint64, error)) *accessControl {
|
||||
func AccessControl(rms roleMemberSearcher) *accessControl {
|
||||
return &accessControl{
|
||||
roleFinder: rf,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
store: rms,
|
||||
rbac: rbac.Global(),
|
||||
actionlog: DefaultActionlog,
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,6 +50,8 @@ func (svc accessControl) can(ctx context.Context, op string, res rbac.Resource)
|
||||
}
|
||||
|
||||
// Effective returns a list of effective permissions for all given resource
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee rbac.EffectiveSet) {
|
||||
for _, res := range rr {
|
||||
r := res.RbacResource()
|
||||
@ -55,38 +64,86 @@ func (svc accessControl) Effective(ctx context.Context, rr ...rbac.Resource) (ee
|
||||
}
|
||||
|
||||
// Evaluate returns a list of permissions evaluated for the given user/roles combo
|
||||
func (svc accessControl) Evaluate(ctx context.Context, user uint64, roles []uint64, rr ...rbac.Resource) (ee rbac.EvaluatedSet, err error) {
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Evaluate(ctx context.Context, userID uint64, roles []uint64, rr ...string) (ee rbac.EvaluatedSet, err error) {
|
||||
// Reusing the grant permission since this is who the feature is for
|
||||
if !svc.CanGrant(ctx) {
|
||||
// @todo should be altered to check grant permissions PER resource
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
// Load roles for this user
|
||||
//
|
||||
// User's roles take priority over specified ones
|
||||
if user != 0 {
|
||||
rr, err := svc.roleFinder(ctx, user)
|
||||
var (
|
||||
resources []rbac.Resource
|
||||
members systemTypes.RoleMemberSet
|
||||
)
|
||||
if len(rr) > 0 {
|
||||
resources = make([]rbac.Resource, 0, len(rr))
|
||||
for _, r := range rr {
|
||||
resources = append(resources, rbac.NewResource(r))
|
||||
}
|
||||
} else {
|
||||
resources = svc.Resources()
|
||||
}
|
||||
|
||||
// User ID specified, load its roles
|
||||
if userID != 0 {
|
||||
if len(roles) > 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("userID and roles are mutually exclusive")
|
||||
}
|
||||
|
||||
members, _, err = svc.store.SearchRoleMembers(ctx, systemTypes.RoleMemberFilter{UserID: userID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
roles = append(rr, roles...)
|
||||
for _, m := range members {
|
||||
roles = append(roles, m.RoleID)
|
||||
}
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, user, roles...)
|
||||
for _, res := range rr {
|
||||
if len(roles) == 0 {
|
||||
// should be prevented on the client
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
eval := svc.rbac.Evaluate(session, op, res)
|
||||
|
||||
ee = append(ee, eval)
|
||||
ee = append(ee, svc.rbac.Evaluate(session, op, res))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Resources returns list of resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) Resources() []rbac.Resource {
|
||||
return []rbac.Resource{
|
||||
rbac.NewResource(types.ApplicationRbacResource(0)),
|
||||
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()),
|
||||
}
|
||||
}
|
||||
|
||||
// List returns list of operations on all resources
|
||||
//
|
||||
// This function is auto-generated
|
||||
func (svc accessControl) List() (out []map[string]string) {
|
||||
def := []map[string]string{
|
||||
{
|
||||
|
||||
@ -147,7 +147,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, primaryCon
|
||||
}
|
||||
}
|
||||
|
||||
DefaultAccessControl = AccessControl(RolesForUser(s))
|
||||
DefaultAccessControl = AccessControl(s)
|
||||
|
||||
DefaultSettings = Settings(ctx, DefaultStore, DefaultLogger, DefaultAccessControl, CurrentSettings)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user