diff --git a/pkg/corredor/service.go b/pkg/corredor/service.go index 0e73696a0..82794db6d 100644 --- a/pkg/corredor/service.go +++ b/pkg/corredor/service.go @@ -99,11 +99,11 @@ type ( } userFinder interface { - FindByAny(interface{}) (*types.User, error) + FindByAny(context.Context, interface{}) (*types.User, error) } roleFinder interface { - FindByAny(interface{}) (*types.Role, error) + FindByAny(context.Context, interface{}) (*types.Role, error) } authTokenMaker interface { @@ -323,7 +323,7 @@ func (svc service) ExecIterator(ctx context.Context, scriptName string) error { } // Run this iterator as defined user - definer, err := svc.users.FindByAny(runAs) + definer, err := svc.users.FindByAny(ctx, runAs) if err != nil { return err } @@ -432,12 +432,12 @@ func (svc *service) loadServerScripts(ctx context.Context) { if len(rsp.Scripts) > 0 { svc.log.Debug("reloading server scripts") - svc.registerServerScripts(rsp.Scripts...) + svc.registerServerScripts(ctx, rsp.Scripts...) } } // Registers Corredor scripts to eventbus and list of manual scripts -func (svc *service) registerServerScripts(ss ...*ServerScript) { +func (svc *service) registerServerScripts(ctx context.Context, ss ...*ServerScript) { svc.sScripts = make([]*Script, 0, len(ss)) // Remove all previously registered triggers @@ -473,7 +473,7 @@ func (svc *service) registerServerScripts(ss ...*ServerScript) { } if len(s.Errors) == 0 { - if sec, rr, err := svc.serverScriptSecurity(script); err != nil { + if sec, rr, err := svc.serverScriptSecurity(ctx, script); err != nil { s.Errors = append(s.Errors, err.Error()) } else { s.Security = sec @@ -680,7 +680,7 @@ func (svc service) exec(ctx context.Context, script string, runAs string, args S // Resolve/expand invoker user details from the context (if present if i := auth.GetIdentityFromContext(ctx); i.Valid() { - invoker, err = svc.users.FindByAny(i) + invoker, err = svc.users.FindByAny(ctx, i) if err != nil { return err } @@ -704,7 +704,7 @@ func (svc service) exec(ctx context.Context, script string, runAs string, args S // We search for the defined (run-as) user, // assign it to authUser argument and make an // authentication token for it - definer, err = svc.users.FindByAny(runAs) + definer, err = svc.users.FindByAny(ctx, runAs) if err != nil { return err } @@ -882,7 +882,7 @@ func (svc *service) registerClientScripts(ss ...*ClientScript) { // 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) { +func (svc *service) serverScriptSecurity(ctx context.Context, script *ServerScript) (sec *ScriptSecurity, rr permissions.RuleSet, err error) { if script.Security == nil { return } @@ -896,7 +896,7 @@ func (svc *service) serverScriptSecurity(script *ServerScript) (sec *ScriptSecur permRuleGenerator = func(script string, access permissions.Access, roles ...string) (permissions.RuleSet, error) { out := make([]*permissions.Rule, len(roles)) for i, role := range roles { - if r, err := svc.roles.FindByAny(role); err != nil { + if r, err := svc.roles.FindByAny(ctx, role); err != nil { return nil, errors.Wrapf(err, "could not load security role: %s", role) } else { out[i] = &permissions.Rule{ @@ -917,7 +917,7 @@ func (svc *service) serverScriptSecurity(script *ServerScript) (sec *ScriptSecur if sec.RunAs != "" { _, err = svc.userLookupCache.lookup( sec.RunAs, - func() (*types.User, error) { return svc.users.FindByAny(sec.RunAs) }, + func() (*types.User, error) { return svc.users.FindByAny(ctx, sec.RunAs) }, ) if err != nil { diff --git a/pkg/corredor/service_test.go b/pkg/corredor/service_test.go index 21010303f..033d3a6d9 100644 --- a/pkg/corredor/service_test.go +++ b/pkg/corredor/service_test.go @@ -54,11 +54,11 @@ func (e mockEvent) Match(matcher eventbus.ConstraintMatcher) bool { return e.match(matcher) } -func (u *mockUserSvc) FindByAny(interface{}) (*types.User, error) { +func (u *mockUserSvc) FindByAny(context.Context, interface{}) (*types.User, error) { return u.user, u.err } -func (u *mockRoleSvc) FindByAny(interface{}) (*types.Role, error) { +func (u *mockRoleSvc) FindByAny(context.Context, interface{}) (*types.Role, error) { return u.role, u.err } @@ -218,7 +218,7 @@ func TestService_canExec(t *testing.T) { svc.log = zap.NewNop() } - svc.registerServerScripts(script1, script2, script3, script4) + svc.registerServerScripts(ctx, script1, script2, script3, script4) a.Len(svc.sScripts, 3) a.Len(svc.permissions, 3) diff --git a/system/service/role.go b/system/service/role.go index 25a2f791f..809108f3d 100644 --- a/system/service/role.go +++ b/system/service/role.go @@ -49,7 +49,7 @@ type ( FindByID(roleID uint64) (*types.Role, error) FindByName(name string) (*types.Role, error) FindByHandle(handle string) (*types.Role, error) - FindByAny(identifier interface{}) (*types.Role, error) + FindByAny(ctx context.Context, identifier interface{}) (*types.Role, error) Find(types.RoleFilter) (types.RoleSet, types.RoleFilter, error) Create(role *types.Role) (*types.Role, error) @@ -173,16 +173,16 @@ func (svc role) FindByHandle(h string) (r *types.Role, err error) { } // FindByAny finds role by given identifier (id, handle, name) -func (svc role) FindByAny(identifier interface{}) (r *types.Role, err error) { +func (svc role) FindByAny(ctx context.Context, identifier interface{}) (r *types.Role, err error) { if ID, ok := identifier.(uint64); ok { - return svc.FindByID(ID) + return svc.With(ctx).FindByID(ID) } else if strIdentifier, ok := identifier.(string); ok { if ID, _ := strconv.ParseUint(strIdentifier, 10, 64); ID > 0 { - return svc.FindByID(ID) + return svc.With(ctx).FindByID(ID) } else { - r, err = svc.FindByHandle(strIdentifier) + r, err = svc.With(ctx).FindByHandle(strIdentifier) if err == nil && r.ID == 0 { - return svc.FindByName(strIdentifier) + return svc.With(ctx).FindByName(strIdentifier) } return r, err diff --git a/system/service/user.go b/system/service/user.go index 8dd14adbc..8af233ba2 100644 --- a/system/service/user.go +++ b/system/service/user.go @@ -81,7 +81,7 @@ type ( FindByEmail(email string) (*types.User, error) FindByHandle(handle string) (*types.User, error) FindByID(id uint64) (*types.User, error) - FindByAny(identifier interface{}) (*types.User, error) + FindByAny(ctx context.Context, identifier interface{}) (*types.User, error) Find(types.UserFilter) (types.UserSet, types.UserFilter, error) Create(input *types.User) (*types.User, error) @@ -202,22 +202,28 @@ func (svc user) FindByHandle(handle string) (u *types.User, err error) { } // FindByAny finds user by given identifier (context, id, handle, email) -func (svc user) FindByAny(identifier interface{}) (u *types.User, err error) { +// +// This function goes against the context anti (!!!) pattern we're using +// (and trying to get rid of) +// +// Main reason to push ctx here as the 1st arg is allow (simple) interface definition +// in the consumers that reside under the pkg/ +func (svc user) FindByAny(ctx context.Context, identifier interface{}) (u *types.User, err error) { if ctx, ok := identifier.(context.Context); ok { identifier = internalAuth.GetIdentityFromContext(ctx).Identity() } if ID, ok := identifier.(uint64); ok { - u, err = svc.FindByID(ID) + u, err = svc.With(ctx).FindByID(ID) } else if identity, ok := identifier.(internalAuth.Identifiable); ok { - u, err = svc.FindByID(identity.Identity()) + u, err = svc.With(ctx).FindByID(identity.Identity()) } else if strIdentifier, ok := identifier.(string); ok { if ID, _ := strconv.ParseUint(strIdentifier, 10, 64); ID > 0 { - u, err = svc.FindByID(ID) + u, err = svc.With(ctx).FindByID(ID) } else if strings.Contains(strIdentifier, "@") { - u, err = svc.FindByEmail(strIdentifier) + u, err = svc.With(ctx).FindByEmail(strIdentifier) } else { - u, err = svc.FindByHandle(strIdentifier) + u, err = svc.With(ctx).FindByHandle(strIdentifier) } } else { err = UserErrInvalidID() @@ -227,7 +233,7 @@ func (svc user) FindByAny(identifier interface{}) (u *types.User, err error) { return } - rr, _, err := svc.role.Find(types.RoleFilter{MemberID: u.ID}) + rr, _, err := svc.role.With(ctx, svc.db).Find(types.RoleFilter{MemberID: u.ID}) if err != nil { return nil, err }