3
0

Add corredor user lookup cache

This commit is contained in:
Denis Arh 2020-05-26 18:42:09 +02:00
parent a0c732f6ff
commit 10d9dbfcbb
2 changed files with 47 additions and 6 deletions

27
pkg/corredor/cache.go Normal file
View File

@ -0,0 +1,27 @@
package corredor
import (
"github.com/cortezaproject/corteza-server/system/types"
)
type (
userLookupCache struct {
err error
user *types.User
}
userLookupCacheMap map[string]userLookupCache
)
func (m userLookupCacheMap) lookup(key string, lookup func() (*types.User, error)) (*types.User, error) {
if c, ok := m[key]; ok {
return c.user, c.err
}
c := userLookupCache{}
c.user, c.err = lookup()
m[key] = c
return c.user, c.err
}

View File

@ -2,6 +2,7 @@ package corredor
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/sentry"
"github.com/go-chi/chi/middleware"
"github.com/pkg/errors"
@ -62,6 +63,9 @@ type (
users userFinder
roles roleFinder
// caching user lookups (w/ errors)
userLookupCache userLookupCacheMap
// set of permission rules, generated from security info of each script
permissions permissions.RuleSet
}
@ -164,6 +168,8 @@ func NewService(logger *zap.Logger, opt options.CorredorOpt) *service {
authTokenMaker: auth.DefaultJwtHandler,
eventRegistry: eventbus.Service(),
permissions: permissions.RuleSet{},
userLookupCache: userLookupCacheMap{},
}
}
@ -434,6 +440,9 @@ func (svc *service) registerServerScripts(ss ...*ServerScript) {
// Reset security
svc.permissions = permissions.RuleSet{}
// reset the cache
svc.userLookupCache = userLookupCacheMap{}
for _, script := range ss {
if nil != svc.sScripts.FindByName(script.Name) {
// Do not allow duplicated scripts
@ -851,7 +860,10 @@ func (svc *service) registerClientScripts(ss ...*ClientScript) {
// processes server script security definition
//
// Checks and preloads sser and roles (if defined)
// Checks and preloads user and roles (if defined)
//
// User and role caches (uc, rc args) hold list of users/roles
// that were already loaded/checked
//
func (svc *service) serverScriptSecurity(script *ServerScript) (sec *ScriptSecurity, rr permissions.RuleSet, err error) {
if script.Security == nil {
@ -886,12 +898,14 @@ func (svc *service) serverScriptSecurity(script *ServerScript) (sec *ScriptSecur
sec = &ScriptSecurity{Security: script.Security}
if sec.RunAs != "" {
// Prefetch run-as user
if _, err = svc.users.FindByAny(sec.RunAs); err != nil {
err = errors.Wrap(err, "could not load security (run-as) user")
_, err = svc.userLookupCache.lookup(
sec.RunAs,
func() (*types.User, error) { return svc.users.FindByAny(sec.RunAs) },
)
if err != nil {
err = fmt.Errorf("could not load security (run-as) user %q: %w", sec.RunAs, err)
return
//} else {
// s.Security.runAs = u.ID
}
}