Hook up reworked rbac svc
This commit is contained in:
@@ -220,6 +220,60 @@
|
||||
# Default: <no value>
|
||||
# RBAC_LOG=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Limit the number of resources to keep in the in-memory index.
|
||||
# When set to -1, max size is used.
|
||||
# When set to 0, the in memory index is not used.
|
||||
# Type: int
|
||||
# Default: <no value>
|
||||
# RBAC_MAX_INDEX_SIZE=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Synchronous lets us make all the procedures synchronous for ease of testing
|
||||
# This should always be false in production
|
||||
# Type: bool
|
||||
# Default: <no value>
|
||||
# RBAC_SYNCHRONOUS=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Reindex strategy defines what strategy we should use.
|
||||
# The available options are:
|
||||
#
|
||||
# . `memory`: prioritize memory consumption which reduces performance during reindexing.
|
||||
# . `speed`: prioritize speed during reindexing; memory consumption will be 2n where n is the current index size.
|
||||
#
|
||||
# If you wish to prioritize memory and speed, consider using `speed` with a lower max index size
|
||||
# Type: string
|
||||
# Default:
|
||||
# RBAC_REINDEX_STRATEGY=
|
||||
|
||||
###############################################################################
|
||||
# Decay factor controls how long an item should be kept in the index while not in use.
|
||||
# Type: float64
|
||||
# Default: <no value>
|
||||
# RBAC_DECAY_FACTOR=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Decay interval controls how fast the decay factor is applied to the index key.
|
||||
# Type: time.Duration
|
||||
# Default: <no value>
|
||||
# RBAC_DECAY_INTERVAL=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Cleanup interval controls when unused/low-scored index items should be yanked out of the index counter.
|
||||
# Type: time.Duration
|
||||
# Default: <no value>
|
||||
# RBAC_CLEANUP_INTERVAL=<no value>
|
||||
|
||||
###############################################################################
|
||||
# [IMPORTANT]
|
||||
# ====
|
||||
# Unused, will be added when state preservation is implemented.
|
||||
# ====
|
||||
# Type: time.Duration
|
||||
# Default: <no value>
|
||||
# RBAC_INDEX_FLUSH_INTERVAL=<no value>
|
||||
|
||||
###############################################################################
|
||||
# Type: string
|
||||
# Default: <no value>
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
authService "github.com/cortezaproject/corteza/server/auth"
|
||||
"github.com/cortezaproject/corteza/server/auth/saml"
|
||||
authSettings "github.com/cortezaproject/corteza/server/auth/settings"
|
||||
autService "github.com/cortezaproject/corteza/server/automation/service"
|
||||
cmpService "github.com/cortezaproject/corteza/server/compose/service"
|
||||
cmpEvent "github.com/cortezaproject/corteza/server/compose/service/event"
|
||||
discoveryService "github.com/cortezaproject/corteza/server/discovery/service"
|
||||
fedService "github.com/cortezaproject/corteza/server/federation/service"
|
||||
"github.com/cortezaproject/corteza/server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza/server/pkg/apigw"
|
||||
apigwTypes "github.com/cortezaproject/corteza/server/pkg/apigw/types"
|
||||
"github.com/cortezaproject/corteza/server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza/server/pkg/corredor"
|
||||
"github.com/cortezaproject/corteza/server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza/server/pkg/healthcheck"
|
||||
"github.com/cortezaproject/corteza/server/pkg/http"
|
||||
"github.com/cortezaproject/corteza/server/pkg/id"
|
||||
"github.com/cortezaproject/corteza/server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza/server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza/server/pkg/mail"
|
||||
"github.com/cortezaproject/corteza/server/pkg/messagebus"
|
||||
"github.com/cortezaproject/corteza/server/pkg/monitor"
|
||||
"github.com/cortezaproject/corteza/server/pkg/options"
|
||||
"github.com/cortezaproject/corteza/server/pkg/provision"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/pkg/scheduler"
|
||||
"github.com/cortezaproject/corteza/server/pkg/sentry"
|
||||
"github.com/cortezaproject/corteza/server/pkg/valuestore"
|
||||
"github.com/cortezaproject/corteza/server/pkg/version"
|
||||
"github.com/cortezaproject/corteza/server/pkg/websocket"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/service"
|
||||
sysService "github.com/cortezaproject/corteza/server/system/service"
|
||||
sysEvent "github.com/cortezaproject/corteza/server/system/service/event"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/lestrrat-go/jwx/jwt"
|
||||
"go.uber.org/zap"
|
||||
gomail "gopkg.in/mail.v2"
|
||||
authService "github.com/cortezaproject/corteza/server/auth"
|
||||
"github.com/cortezaproject/corteza/server/auth/saml"
|
||||
authSettings "github.com/cortezaproject/corteza/server/auth/settings"
|
||||
autService "github.com/cortezaproject/corteza/server/automation/service"
|
||||
cmpService "github.com/cortezaproject/corteza/server/compose/service"
|
||||
cmpEvent "github.com/cortezaproject/corteza/server/compose/service/event"
|
||||
discoveryService "github.com/cortezaproject/corteza/server/discovery/service"
|
||||
fedService "github.com/cortezaproject/corteza/server/federation/service"
|
||||
"github.com/cortezaproject/corteza/server/pkg/actionlog"
|
||||
"github.com/cortezaproject/corteza/server/pkg/apigw"
|
||||
apigwTypes "github.com/cortezaproject/corteza/server/pkg/apigw/types"
|
||||
"github.com/cortezaproject/corteza/server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza/server/pkg/corredor"
|
||||
"github.com/cortezaproject/corteza/server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza/server/pkg/healthcheck"
|
||||
"github.com/cortezaproject/corteza/server/pkg/http"
|
||||
"github.com/cortezaproject/corteza/server/pkg/id"
|
||||
"github.com/cortezaproject/corteza/server/pkg/locale"
|
||||
"github.com/cortezaproject/corteza/server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza/server/pkg/mail"
|
||||
"github.com/cortezaproject/corteza/server/pkg/messagebus"
|
||||
"github.com/cortezaproject/corteza/server/pkg/monitor"
|
||||
"github.com/cortezaproject/corteza/server/pkg/options"
|
||||
"github.com/cortezaproject/corteza/server/pkg/provision"
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
"github.com/cortezaproject/corteza/server/pkg/scheduler"
|
||||
"github.com/cortezaproject/corteza/server/pkg/sentry"
|
||||
"github.com/cortezaproject/corteza/server/pkg/valuestore"
|
||||
"github.com/cortezaproject/corteza/server/pkg/version"
|
||||
"github.com/cortezaproject/corteza/server/pkg/websocket"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/service"
|
||||
sysService "github.com/cortezaproject/corteza/server/system/service"
|
||||
sysEvent "github.com/cortezaproject/corteza/server/system/service/event"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
"github.com/lestrrat-go/jwx/jwt"
|
||||
"go.uber.org/zap"
|
||||
gomail "gopkg.in/mail.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -258,15 +258,7 @@ func (app *CortezaApp) Provision(ctx context.Context) (err error) {
|
||||
// @todo envoy should be decoupled from RBAC and import directly into store,
|
||||
// w/o using any access control
|
||||
|
||||
var (
|
||||
ac = rbac.NewService(zap.NewNop(), app.Store)
|
||||
acr = make([]*rbac.Role, 0)
|
||||
)
|
||||
for _, r := range auth.ProvisionUser().Roles() {
|
||||
acr = append(acr, rbac.BypassRole.Make(r, auth.BypassRoleHandle))
|
||||
}
|
||||
ac.UpdateRoles(acr...)
|
||||
rbac.SetGlobal(ac)
|
||||
rbac.SetGlobal(rbac.NoopSvc(rbac.Allow))
|
||||
defer rbac.SetGlobal(nil)
|
||||
}
|
||||
|
||||
@@ -355,10 +347,29 @@ func (app *CortezaApp) InitServices(ctx context.Context) (err error) {
|
||||
}
|
||||
|
||||
// Initialize RBAC subsystem
|
||||
ac := rbac.NewService(log, app.Store)
|
||||
// @todo add state management
|
||||
// @todo potentially add .Activate like other services?
|
||||
ac, err := rbac.NewService(ctx, log, app.Store, rbac.Config{
|
||||
MaxIndexSize: app.Opt.RBAC.MaxIndexSize,
|
||||
Synchronous: app.Opt.RBAC.Synchronous,
|
||||
ReindexStrategy: rbac.ReindexStrategy(app.Opt.RBAC.ReindexStrategy),
|
||||
DecayFactor: app.Opt.RBAC.DecayFactor,
|
||||
DecayInterval: app.Opt.RBAC.DecayInterval,
|
||||
CleanupInterval: app.Opt.RBAC.CleanupInterval,
|
||||
IndexFlushInterval: app.Opt.RBAC.IndexFlushInterval,
|
||||
RuleStorage: app.Store,
|
||||
RoleStorage: app.Store,
|
||||
|
||||
// and (re)load rules from the storage backend
|
||||
ac.Reload(ctx)
|
||||
PullInitialState: func(ctx context.Context, n int) ([]string, error) {
|
||||
return nil, nil
|
||||
},
|
||||
FlushIndexState: func(ctx context.Context, s []string) error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize RBAC service: %w", err)
|
||||
}
|
||||
|
||||
rbac.SetGlobal(ac)
|
||||
}
|
||||
@@ -504,8 +515,6 @@ func (app *CortezaApp) Activate(ctx context.Context) (err error) {
|
||||
|
||||
monitor.Watcher(ctx)
|
||||
|
||||
rbac.Global().Watch(ctx)
|
||||
|
||||
if err = sysService.Activate(ctx); err != nil {
|
||||
return fmt.Errorf("could not activate system services: %w", err)
|
||||
|
||||
@@ -562,9 +571,9 @@ func (app *CortezaApp) Activate(ctx context.Context) (err error) {
|
||||
|
||||
app.AuthService.Watch(ctx)
|
||||
|
||||
updateSassInstallSettings(ctx, sysService.DefaultStylesheet.SassInstalled(), app.Log)
|
||||
updateSassInstallSettings(ctx, sysService.DefaultStylesheet.SassInstalled(), app.Log)
|
||||
//Generate CSS for webapps
|
||||
if err = sysService.DefaultStylesheet.GenerateCSS(sysService.CurrentSettings, app.Opt.Webapp.ScssDirPath, app.Log); err != nil {
|
||||
if err = sysService.DefaultStylesheet.GenerateCSS(sysService.CurrentSettings, app.Opt.Webapp.ScssDirPath, app.Log); err != nil {
|
||||
return fmt.Errorf("could not generate css for webapps: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,75 @@ RBAC: schema.#optionsGroup & {
|
||||
type: "bool"
|
||||
description: "Log RBAC related events and actions"
|
||||
}
|
||||
|
||||
max_index_size: {
|
||||
type: "int"
|
||||
defaultGoExpr: "-1"
|
||||
description: """
|
||||
Limit the number of resources to keep in the in-memory index.
|
||||
When set to -1, max size is used.
|
||||
When set to 0, the in memory index is not used.
|
||||
"""
|
||||
}
|
||||
|
||||
synchronous: {
|
||||
type: "bool"
|
||||
defaultGoExpr: "false"
|
||||
description: """
|
||||
Synchronous lets us make all the procedures synchronous for ease of testing
|
||||
This should always be false in production
|
||||
"""
|
||||
}
|
||||
|
||||
reindex_strategy: {
|
||||
type: "string"
|
||||
defaultValue: ""
|
||||
description: """
|
||||
Reindex strategy defines what strategy we should use.
|
||||
The available options are:
|
||||
|
||||
. `memory`: prioritize memory consumption which reduces performance during reindexing.
|
||||
. `speed`: prioritize speed during reindexing; memory consumption will be 2n where n is the current index size.
|
||||
|
||||
If you wish to prioritize memory and speed, consider using `speed` with a lower max index size
|
||||
"""
|
||||
}
|
||||
|
||||
decay_factor: {
|
||||
type: "float64"
|
||||
defaultGoExpr: "0.9"
|
||||
description: """
|
||||
Decay factor controls how long an item should be kept in the index while not in use.
|
||||
"""
|
||||
}
|
||||
|
||||
decay_interval: {
|
||||
type: "time.Duration"
|
||||
defaultGoExpr: "time.Minute * 30"
|
||||
description: """
|
||||
Decay interval controls how fast the decay factor is applied to the index key.
|
||||
"""
|
||||
}
|
||||
|
||||
cleanup_interval: {
|
||||
type: "time.Duration"
|
||||
defaultGoExpr: "time.Minute * 31"
|
||||
description: """
|
||||
Cleanup interval controls when unused/low-scored index items should be yanked out of the index counter.
|
||||
"""
|
||||
}
|
||||
|
||||
index_flush_interval: {
|
||||
type: "time.Duration"
|
||||
defaultGoExpr: "time.Minute * 35"
|
||||
description: """
|
||||
[IMPORTANT]
|
||||
====
|
||||
Unused, will be added when state preservation is implemented.
|
||||
====
|
||||
"""
|
||||
}
|
||||
|
||||
service_user: {}
|
||||
bypass_roles: {
|
||||
defaultValue: "super-admin"
|
||||
|
||||
13
server/automation/service/access_control.gen.go
generated
13
server/automation/service/access_control.gen.go
generated
@@ -22,9 +22,9 @@ import (
|
||||
type (
|
||||
rbacService interface {
|
||||
Can(rbac.Session, string, rbac.Resource) bool
|
||||
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
|
||||
Trace(rbac.Session, string, rbac.Resource) (*rbac.Trace, error)
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
FindRulesByRoleID(ctx context.Context, roleID uint64) (rr rbac.RuleSet, err error)
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
@@ -120,11 +120,16 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
var auxTrace *rbac.Trace
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
ee = append(ee, svc.rbac.Trace(session, op, res))
|
||||
auxTrace, err = svc.rbac.Trace(session, op, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ee = append(ee, auxTrace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +305,7 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
return svc.rbac.FindRulesByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
// CanReadWorkflow checks if current user can read workflow
|
||||
|
||||
@@ -21,9 +21,9 @@ import (
|
||||
type (
|
||||
rbacService interface {
|
||||
Can(rbac.Session, string, rbac.Resource) bool
|
||||
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
|
||||
Trace(rbac.Session, string, rbac.Resource) (*rbac.Trace, error)
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
FindRulesByRoleID(ctx context.Context, roleID uint64) (rr rbac.RuleSet, err error)
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
@@ -119,11 +119,16 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
var auxTrace *rbac.Trace
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
ee = append(ee, svc.rbac.Trace(session, op, res))
|
||||
auxTrace, err = svc.rbac.Trace(session, op, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ee = append(ee, auxTrace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +250,7 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
return svc.rbac.FindRulesByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
{{- range .operations }}
|
||||
|
||||
@@ -497,7 +497,10 @@ func (ctrl Namespace) exportCompose(ctx context.Context, namespaceID uint64) (re
|
||||
|
||||
func (ctrl Namespace) exportRBAC(ctx context.Context, base envoyx.NodeSet) (resources envoyx.NodeSet, err error) {
|
||||
// Prepare RBAC Rules
|
||||
rawRules := rbac.Global().Rules()
|
||||
rawRules, err := rbac.Global().Rules(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resources, err = envoyx.RBACRulesForNodes(rawRules, base...)
|
||||
if err != nil {
|
||||
|
||||
13
server/compose/service/access_control.gen.go
generated
13
server/compose/service/access_control.gen.go
generated
@@ -22,9 +22,9 @@ import (
|
||||
type (
|
||||
rbacService interface {
|
||||
Can(rbac.Session, string, rbac.Resource) bool
|
||||
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
|
||||
Trace(rbac.Session, string, rbac.Resource) (*rbac.Trace, error)
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
FindRulesByRoleID(ctx context.Context, roleID uint64) (rr rbac.RuleSet, err error)
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
@@ -120,11 +120,16 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
var auxTrace *rbac.Trace
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
ee = append(ee, svc.rbac.Trace(session, op, res))
|
||||
auxTrace, err = svc.rbac.Trace(session, op, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ee = append(ee, auxTrace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +451,7 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
return svc.rbac.FindRulesByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
// CanReadChart checks if current user can read
|
||||
|
||||
@@ -850,8 +850,14 @@ func (svc namespace) reloadServices(ctx context.Context, ns *types.Namespace) (e
|
||||
return
|
||||
}
|
||||
|
||||
// Reload RBAC rules (in case import brought in something new)
|
||||
rbac.Global().Reload(ctx)
|
||||
// Reload some RBAC bits in case things changed
|
||||
//
|
||||
// @note no need to reload rules; just roles for now
|
||||
err = rbac.Global().ReloadRoles(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = locale.Global().ReloadResourceTranslations(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ type (
|
||||
settings *sysTypes.AppSettings
|
||||
|
||||
rbac interface {
|
||||
SignificantRoles(res rbac.Resource, op string) (aRR, dRR []uint64)
|
||||
SignificantRoles(ctx context.Context, res rbac.Resource, op string) (aRR, dRR []uint64, err error)
|
||||
}
|
||||
|
||||
ac interface {
|
||||
@@ -168,7 +168,10 @@ func (d composeResources) Namespaces(ctx context.Context, limit uint, cur string
|
||||
},
|
||||
}
|
||||
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles = d.rbac.SignificantRoles(ns, "read")
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles, err = d.rbac.SignificantRoles(ctx, ns, "read")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Documents[i].Source = doc
|
||||
}
|
||||
@@ -255,7 +258,10 @@ func (d composeResources) Modules(ctx context.Context, namespaceID uint64, limit
|
||||
},
|
||||
}
|
||||
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles = d.rbac.SignificantRoles(mod, "read")
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles, err = d.rbac.SignificantRoles(ctx, mod, "read")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Documents[i].Source = doc
|
||||
}
|
||||
@@ -378,7 +384,10 @@ func (d composeResources) Records(ctx context.Context, namespaceID, moduleID uin
|
||||
// Values and value labels
|
||||
doc.Values, doc.ValueLabels = d.recordValues(ctx, rec, mod.Fields)
|
||||
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles = d.rbac.SignificantRoles(rec, "read")
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles, err = d.rbac.SignificantRoles(ctx, rec, "read")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Documents[i].Source = doc
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ type (
|
||||
settings *types.AppSettings
|
||||
|
||||
rbac interface {
|
||||
SignificantRoles(res rbac.Resource, op string) (aRR, dRR []uint64)
|
||||
SignificantRoles(ctx context.Context, res rbac.Resource, op string) (aRR, dRR []uint64, err error)
|
||||
}
|
||||
|
||||
ac interface {
|
||||
@@ -92,7 +92,10 @@ func (d systemResources) Users(ctx context.Context, limit uint, cur string, user
|
||||
doc.Url = fmt.Sprintf("%s/admin/system/user/edit/%d", d.opt.CortezaDomain, u.ID)
|
||||
}
|
||||
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles = d.rbac.SignificantRoles(u, "read")
|
||||
doc.Security.AllowedRoles, doc.Security.DeniedRoles, err = d.rbac.SignificantRoles(ctx, u, "read")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rsp.Documents[i].ID = u.ID
|
||||
rsp.Documents[i].Source = doc
|
||||
|
||||
@@ -2,12 +2,13 @@ package feed
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/discovery/service"
|
||||
"github.com/cortezaproject/corteza/server/discovery/types"
|
||||
"github.com/cortezaproject/corteza/server/pkg/errors"
|
||||
"github.com/cortezaproject/corteza/server/pkg/filter"
|
||||
"github.com/cortezaproject/corteza/server/pkg/options"
|
||||
"time"
|
||||
|
||||
"github.com/cortezaproject/corteza/server/pkg/rbac"
|
||||
)
|
||||
@@ -17,7 +18,7 @@ type (
|
||||
opt options.DiscoveryOpt
|
||||
|
||||
rbac interface {
|
||||
SignificantRoles(res rbac.Resource, op string) (aRR, dRR []uint64)
|
||||
SignificantRoles(ctx context.Context, res rbac.Resource, op string) (aRR, dRR []uint64, err error)
|
||||
}
|
||||
|
||||
ac interface {
|
||||
|
||||
13
server/federation/service/access_control.gen.go
generated
13
server/federation/service/access_control.gen.go
generated
@@ -22,9 +22,9 @@ import (
|
||||
type (
|
||||
rbacService interface {
|
||||
Can(rbac.Session, string, rbac.Resource) bool
|
||||
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
|
||||
Trace(rbac.Session, string, rbac.Resource) (*rbac.Trace, error)
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
FindRulesByRoleID(ctx context.Context, roleID uint64) (rr rbac.RuleSet, err error)
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
@@ -120,11 +120,16 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
var auxTrace *rbac.Trace
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
ee = append(ee, svc.rbac.Trace(session, op, res))
|
||||
auxTrace, err = svc.rbac.Trace(session, op, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ee = append(ee, auxTrace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +292,7 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
return svc.rbac.FindRulesByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
// CanManageNode checks if current user can manage federation node
|
||||
|
||||
24
server/pkg/options/options.gen.go
generated
24
server/pkg/options/options.gen.go
generated
@@ -52,11 +52,18 @@ type (
|
||||
}
|
||||
|
||||
RbacOpt struct {
|
||||
Log bool `env:"RBAC_LOG"`
|
||||
ServiceUser string `env:"RBAC_SERVICE_USER"`
|
||||
BypassRoles string `env:"RBAC_BYPASS_ROLES"`
|
||||
AuthenticatedRoles string `env:"RBAC_AUTHENTICATED_ROLES"`
|
||||
AnonymousRoles string `env:"RBAC_ANONYMOUS_ROLES"`
|
||||
Log bool `env:"RBAC_LOG"`
|
||||
MaxIndexSize int `env:"RBAC_MAX_INDEX_SIZE"`
|
||||
Synchronous bool `env:"RBAC_SYNCHRONOUS"`
|
||||
ReindexStrategy string `env:"RBAC_REINDEX_STRATEGY"`
|
||||
DecayFactor float64 `env:"RBAC_DECAY_FACTOR"`
|
||||
DecayInterval time.Duration `env:"RBAC_DECAY_INTERVAL"`
|
||||
CleanupInterval time.Duration `env:"RBAC_CLEANUP_INTERVAL"`
|
||||
IndexFlushInterval time.Duration `env:"RBAC_INDEX_FLUSH_INTERVAL"`
|
||||
ServiceUser string `env:"RBAC_SERVICE_USER"`
|
||||
BypassRoles string `env:"RBAC_BYPASS_ROLES"`
|
||||
AuthenticatedRoles string `env:"RBAC_AUTHENTICATED_ROLES"`
|
||||
AnonymousRoles string `env:"RBAC_ANONYMOUS_ROLES"`
|
||||
}
|
||||
|
||||
SCIMOpt struct {
|
||||
@@ -378,6 +385,13 @@ func HttpServer() (o *HttpServerOpt) {
|
||||
// This function is auto-generated
|
||||
func Rbac() (o *RbacOpt) {
|
||||
o = &RbacOpt{
|
||||
MaxIndexSize: -1,
|
||||
Synchronous: false,
|
||||
ReindexStrategy: "",
|
||||
DecayFactor: 0.9,
|
||||
DecayInterval: time.Minute * 30,
|
||||
CleanupInterval: time.Minute * 31,
|
||||
IndexFlushInterval: time.Minute * 35,
|
||||
BypassRoles: "super-admin",
|
||||
AuthenticatedRoles: "authenticated",
|
||||
AnonymousRoles: "anonymous",
|
||||
|
||||
13
server/system/service/access_control.gen.go
generated
13
server/system/service/access_control.gen.go
generated
@@ -22,9 +22,9 @@ import (
|
||||
type (
|
||||
rbacService interface {
|
||||
Can(rbac.Session, string, rbac.Resource) bool
|
||||
Trace(rbac.Session, string, rbac.Resource) *rbac.Trace
|
||||
Trace(rbac.Session, string, rbac.Resource) (*rbac.Trace, error)
|
||||
Grant(context.Context, ...*rbac.Rule) error
|
||||
FindRulesByRoleID(roleID uint64) (rr rbac.RuleSet)
|
||||
FindRulesByRoleID(ctx context.Context, roleID uint64) (rr rbac.RuleSet, err error)
|
||||
}
|
||||
|
||||
accessControl struct {
|
||||
@@ -120,11 +120,16 @@ func (svc accessControl) Trace(ctx context.Context, userID uint64, roles []uint6
|
||||
return nil, fmt.Errorf("no roles specified")
|
||||
}
|
||||
|
||||
var auxTrace *rbac.Trace
|
||||
session := rbac.ParamsToSession(ctx, userID, roles...)
|
||||
for _, res := range resources {
|
||||
r := res.RbacResource()
|
||||
for op := range rbacResourceOperations(r) {
|
||||
ee = append(ee, svc.rbac.Trace(session, op, res))
|
||||
auxTrace, err = svc.rbac.Trace(session, op, res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ee = append(ee, auxTrace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,7 +609,7 @@ func (svc accessControl) FindRulesByRoleID(ctx context.Context, roleID uint64) (
|
||||
return nil, AccessControlErrNotAllowedToSetPermissions()
|
||||
}
|
||||
|
||||
return svc.rbac.FindRulesByRoleID(roleID), nil
|
||||
return svc.rbac.FindRulesByRoleID(ctx, roleID)
|
||||
}
|
||||
|
||||
// CanReadApplication checks if current user can read application
|
||||
|
||||
Reference in New Issue
Block a user