Add basic automation functions for system

This commit is contained in:
Denis Arh
2021-02-15 10:56:53 +01:00
parent cd2fb4609a
commit 5d86b241d5
12 changed files with 3053 additions and 6 deletions
+395
View File
@@ -0,0 +1,395 @@
package automation
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// system/automation/expr_types.yaml
import (
"context"
"fmt"
. "github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/system/types"
)
var _ = context.Background
var _ = fmt.Errorf
// Role is an expression type, wrapper for *types.Role type
type Role struct{ value *types.Role }
// NewRole creates new instance of Role expression type
func NewRole(val interface{}) (*Role, error) {
if c, err := CastToRole(val); err != nil {
return nil, fmt.Errorf("unable to create Role: %w", err)
} else {
return &Role{value: c}, nil
}
}
// Return underlying value on Role
func (t Role) Get() interface{} { return t.value }
// Return type name
func (Role) Type() string { return "Role" }
// Convert value to *types.Role
func (Role) Cast(val interface{}) (TypedValue, error) {
return NewRole(val)
}
// Assign new value to Role
//
// value is first passed through CastToRole
func (t *Role) Assign(val interface{}) error {
if c, err := CastToRole(val); err != nil {
return err
} else {
t.value = c
return nil
}
}
func (t *Role) AssignFieldValue(key string, val interface{}) error {
return assignToRole(t.value, key, val)
}
// SelectGVal implements gval.Selector requirements
//
// It allows gval lib to access Role's underlying value (*types.Role)
// and it's fields
//
func (t Role) SelectGVal(ctx context.Context, k string) (interface{}, error) {
return roleGValSelector(t.value, k)
}
// Select is field accessor for *types.Role
//
// Similar to SelectGVal but returns typed values
func (t Role) Select(k string) (TypedValue, error) {
return roleTypedValueSelector(t.value, k)
}
func (t Role) Has(k string) bool {
switch k {
case "ID":
return true
case "name":
return true
case "handle":
return true
case "labels":
return true
case "createdAt":
return true
case "updatedAt":
return true
case "archivedAt":
return true
case "deletedAt":
return true
}
return false
}
// roleGValSelector is field accessor for *types.Role
func roleGValSelector(res *types.Role, k string) (interface{}, error) {
switch k {
case "ID":
return res.ID, nil
case "name":
return res.Name, nil
case "handle":
return res.Handle, nil
case "labels":
return res.Labels, nil
case "createdAt":
return res.CreatedAt, nil
case "updatedAt":
return res.UpdatedAt, nil
case "archivedAt":
return res.ArchivedAt, nil
case "deletedAt":
return res.DeletedAt, nil
}
return nil, fmt.Errorf("unknown field '%s'", k)
}
// roleTypedValueSelector is field accessor for *types.Role
func roleTypedValueSelector(res *types.Role, k string) (TypedValue, error) {
switch k {
case "ID":
return NewID(res.ID)
case "name":
return NewString(res.Name)
case "handle":
return NewHandle(res.Handle)
case "labels":
return NewKV(res.Labels)
case "createdAt":
return NewDateTime(res.CreatedAt)
case "updatedAt":
return NewDateTime(res.UpdatedAt)
case "archivedAt":
return NewDateTime(res.ArchivedAt)
case "deletedAt":
return NewDateTime(res.DeletedAt)
}
return nil, fmt.Errorf("unknown field '%s'", k)
}
// assignToRole is field value setter for *types.Role
func assignToRole(res *types.Role, k string, val interface{}) error {
switch k {
case "ID":
return fmt.Errorf("field '%s' is read-only", k)
case "name":
aux, err := CastToString(val)
if err != nil {
return err
}
res.Name = aux
return nil
case "handle":
aux, err := CastToHandle(val)
if err != nil {
return err
}
res.Handle = aux
return nil
case "labels":
aux, err := CastToKV(val)
if err != nil {
return err
}
res.Labels = aux
return nil
case "createdAt":
return fmt.Errorf("field '%s' is read-only", k)
case "updatedAt":
return fmt.Errorf("field '%s' is read-only", k)
case "archivedAt":
return fmt.Errorf("field '%s' is read-only", k)
case "deletedAt":
return fmt.Errorf("field '%s' is read-only", k)
}
return fmt.Errorf("unknown field '%s'", k)
}
// User is an expression type, wrapper for *types.User type
type User struct{ value *types.User }
// NewUser creates new instance of User expression type
func NewUser(val interface{}) (*User, error) {
if c, err := CastToUser(val); err != nil {
return nil, fmt.Errorf("unable to create User: %w", err)
} else {
return &User{value: c}, nil
}
}
// Return underlying value on User
func (t User) Get() interface{} { return t.value }
// Return type name
func (User) Type() string { return "User" }
// Convert value to *types.User
func (User) Cast(val interface{}) (TypedValue, error) {
return NewUser(val)
}
// Assign new value to User
//
// value is first passed through CastToUser
func (t *User) Assign(val interface{}) error {
if c, err := CastToUser(val); err != nil {
return err
} else {
t.value = c
return nil
}
}
func (t *User) AssignFieldValue(key string, val interface{}) error {
return assignToUser(t.value, key, val)
}
// SelectGVal implements gval.Selector requirements
//
// It allows gval lib to access User's underlying value (*types.User)
// and it's fields
//
func (t User) SelectGVal(ctx context.Context, k string) (interface{}, error) {
return userGValSelector(t.value, k)
}
// Select is field accessor for *types.User
//
// Similar to SelectGVal but returns typed values
func (t User) Select(k string) (TypedValue, error) {
return userTypedValueSelector(t.value, k)
}
func (t User) Has(k string) bool {
switch k {
case "ID":
return true
case "username":
return true
case "email":
return true
case "name":
return true
case "handle":
return true
case "emailConfirmed":
return true
case "labels":
return true
case "createdAt":
return true
case "updatedAt":
return true
case "suspendedAt":
return true
case "deletedAt":
return true
}
return false
}
// userGValSelector is field accessor for *types.User
func userGValSelector(res *types.User, k string) (interface{}, error) {
switch k {
case "ID":
return res.ID, nil
case "username":
return res.Username, nil
case "email":
return res.Email, nil
case "name":
return res.Name, nil
case "handle":
return res.Handle, nil
case "emailConfirmed":
return res.EmailConfirmed, nil
case "labels":
return res.Labels, nil
case "createdAt":
return res.CreatedAt, nil
case "updatedAt":
return res.UpdatedAt, nil
case "suspendedAt":
return res.SuspendedAt, nil
case "deletedAt":
return res.DeletedAt, nil
}
return nil, fmt.Errorf("unknown field '%s'", k)
}
// userTypedValueSelector is field accessor for *types.User
func userTypedValueSelector(res *types.User, k string) (TypedValue, error) {
switch k {
case "ID":
return NewID(res.ID)
case "username":
return NewString(res.Username)
case "email":
return NewString(res.Email)
case "name":
return NewString(res.Name)
case "handle":
return NewHandle(res.Handle)
case "emailConfirmed":
return NewBoolean(res.EmailConfirmed)
case "labels":
return NewKV(res.Labels)
case "createdAt":
return NewDateTime(res.CreatedAt)
case "updatedAt":
return NewDateTime(res.UpdatedAt)
case "suspendedAt":
return NewDateTime(res.SuspendedAt)
case "deletedAt":
return NewDateTime(res.DeletedAt)
}
return nil, fmt.Errorf("unknown field '%s'", k)
}
// assignToUser is field value setter for *types.User
func assignToUser(res *types.User, k string, val interface{}) error {
switch k {
case "ID":
return fmt.Errorf("field '%s' is read-only", k)
case "username":
aux, err := CastToString(val)
if err != nil {
return err
}
res.Username = aux
return nil
case "email":
aux, err := CastToString(val)
if err != nil {
return err
}
res.Email = aux
return nil
case "name":
aux, err := CastToString(val)
if err != nil {
return err
}
res.Name = aux
return nil
case "handle":
aux, err := CastToHandle(val)
if err != nil {
return err
}
res.Handle = aux
return nil
case "emailConfirmed":
aux, err := CastToBoolean(val)
if err != nil {
return err
}
res.EmailConfirmed = aux
return nil
case "labels":
aux, err := CastToKV(val)
if err != nil {
return err
}
res.Labels = aux
return nil
case "createdAt":
return fmt.Errorf("field '%s' is read-only", k)
case "updatedAt":
return fmt.Errorf("field '%s' is read-only", k)
case "suspendedAt":
return fmt.Errorf("field '%s' is read-only", k)
case "deletedAt":
return fmt.Errorf("field '%s' is read-only", k)
}
return fmt.Errorf("unknown field '%s'", k)
}
+41
View File
@@ -0,0 +1,41 @@
package automation
import (
"fmt"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/system/types"
)
func CastToUser(val interface{}) (out *types.User, err error) {
switch val := val.(type) {
case expr.Iterator:
out = &types.User{}
return out, val.Each(func(k string, v expr.TypedValue) error {
return assignToUser(out, k, v)
})
}
switch val := expr.UntypedValue(val).(type) {
case *types.User:
return val, nil
default:
return nil, fmt.Errorf("unable to cast type %T to %T", val, out)
}
}
func CastToRole(val interface{}) (out *types.Role, err error) {
switch val := val.(type) {
case expr.Iterator:
out = &types.Role{}
return out, val.Each(func(k string, v expr.TypedValue) error {
return assignToRole(out, k, v)
})
}
switch val := expr.UntypedValue(val).(type) {
case *types.Role:
return val, nil
default:
return nil, fmt.Errorf("unable to cast type %T to %T", val, out)
}
}
+30
View File
@@ -0,0 +1,30 @@
package: automation
imports:
- github.com/cortezaproject/corteza-server/system/types
types:
User:
as: '*types.User'
struct:
- { name: 'ID', exprType: 'ID', goType: 'uint64', mode: ro }
- { name: 'username', exprType: 'String', goType: 'string' }
- { name: 'email', exprType: 'String', goType: 'string' }
- { name: 'name', exprType: 'String', goType: 'string' }
- { name: 'handle', exprType: 'Handle', goType: 'string' }
- { name: 'emailConfirmed', exprType: 'Boolean', goType: 'bool' }
- { name: 'labels', exprType: 'KV', goType: 'map[string]string' }
- { name: 'createdAt', exprType: 'DateTime', goType: 'time.Time', mode: ro}
- { name: 'updatedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
- { name: 'suspendedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
- { name: 'deletedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
Role:
as: '*types.Role'
struct:
- { name: 'ID', exprType: 'ID', goType: 'uint64', mode: ro }
- { name: 'name', exprType: 'String', goType: 'string' }
- { name: 'handle', exprType: 'Handle', goType: 'string' }
- { name: 'labels', exprType: 'KV', goType: 'map[string]''string' }
- { name: 'createdAt', exprType: 'DateTime', goType: 'time.Time', mode: ro}
- { name: 'updatedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
- { name: 'archivedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
- { name: 'deletedAt', exprType: 'DateTime', goType: '*time.Time', mode: ro }
+39
View File
@@ -0,0 +1,39 @@
package automation
import (
"context"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/stretchr/testify/require"
"testing"
)
func TestUser(t *testing.T) {
var (
req = require.New(t)
u, err = NewUser(&types.User{Handle: "handle"})
)
req.NoError(err)
req.Equal("handle", u.value.Handle)
req.Error(u.AssignFieldValue("some-unexisting-field", nil))
req.NoError(u.AssignFieldValue("email", "dummy@domain.tpl"))
req.Equal("dummy@domain.tpl", u.value.Email)
}
func TestUser_Expr(t *testing.T) {
var (
req = require.New(t)
u, err = NewUser(&types.User{Handle: "hendl"})
)
req.NoError(err)
eval, err := expr.NewParser().Parse("user.handle")
req.NoError(err)
res, err := eval.Eval(context.Background(), expr.RVars{"user": u}.Vars())
req.NoError(err)
req.Equal("hendl", res.(string))
}
+904
View File
@@ -0,0 +1,904 @@
package automation
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// system/automation/roles_handler.yaml
import (
"context"
atypes "github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
"github.com/cortezaproject/corteza-server/system/types"
)
var _ wfexec.ExecResponse
type (
rolesHandlerRegistry interface {
AddFunctions(ff ...*atypes.Function)
Type(ref string) expr.Type
}
)
func (h rolesHandler) register() {
h.reg.AddFunctions(
h.Lookup(),
h.Search(),
h.Each(),
h.Create(),
h.Update(),
h.Delete(),
h.Recover(),
h.Archive(),
h.Unarchive(),
)
}
type (
rolesLookupArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupRes *types.Role
}
rolesLookupResults struct {
Role *types.Role
}
)
func (a rolesLookupArgs) GetLookup() (bool, uint64, string, *types.Role) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
}
// Lookup function Looks-up for role by ID
//
// expects implementation of lookup function:
// func (h rolesHandler) lookup(ctx context.Context, args *rolesLookupArgs) (results *rolesLookupResults, err error) {
// return
// }
func (h rolesHandler) Lookup() *atypes.Function {
return &atypes.Function{
Ref: "rolesLookup",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Looks-up for role by ID",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "Role"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesLookupArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("Role").Type():
args.lookupRes = aux.Get().(*types.Role)
}
}
var results *rolesLookupResults
if results, err = h.lookup(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.Role (*types.Role) to Role
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Role").Cast(results.Role); err != nil {
return
} else if err = expr.Assign(out, "role", tval); err != nil {
return
}
}
return
},
}
}
type (
rolesSearchArgs struct {
hasQuery bool
Query string
hasMemberID bool
MemberID uint64
hasHandle bool
Handle string
hasName bool
Name string
hasLabels bool
Labels map[string]string
hasDeleted bool
Deleted uint64
hasArchived bool
Archived uint64
hasSort bool
Sort string
hasLimit bool
Limit uint64
hasIncTotal bool
IncTotal bool
hasIncPageNavigation bool
IncPageNavigation bool
hasPageCursor bool
PageCursor string
}
rolesSearchResults struct {
Roles []*types.Role
Total uint64
PageCursor string
}
)
// Search function Searches for roles and returns them
//
// expects implementation of search function:
// func (h rolesHandler) search(ctx context.Context, args *rolesSearchArgs) (results *rolesSearchResults, err error) {
// return
// }
func (h rolesHandler) Search() *atypes.Function {
return &atypes.Function{
Ref: "rolesSearch",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Searches for roles and returns them",
},
Parameters: []*atypes.Param{
{
Name: "query",
Types: []string{"String"},
},
{
Name: "memberID",
Types: []string{"ID"},
},
{
Name: "handle",
Types: []string{"String"},
},
{
Name: "name",
Types: []string{"String"},
},
{
Name: "labels",
Types: []string{"KV"},
},
{
Name: "deleted",
Types: []string{"UnsignedInteger"},
},
{
Name: "archived",
Types: []string{"UnsignedInteger"},
},
{
Name: "sort",
Types: []string{"String"},
},
{
Name: "limit",
Types: []string{"UnsignedInteger"},
},
{
Name: "incTotal",
Types: []string{"Boolean"},
},
{
Name: "incPageNavigation",
Types: []string{"Boolean"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Results: []*atypes.Param{
{
Name: "roles",
Types: []string{"Role"},
IsArray: true,
},
{
Name: "total",
Types: []string{"UnsignedInteger"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesSearchArgs{
hasQuery: in.Has("query"),
hasMemberID: in.Has("memberID"),
hasHandle: in.Has("handle"),
hasName: in.Has("name"),
hasLabels: in.Has("labels"),
hasDeleted: in.Has("deleted"),
hasArchived: in.Has("archived"),
hasSort: in.Has("sort"),
hasLimit: in.Has("limit"),
hasIncTotal: in.Has("incTotal"),
hasIncPageNavigation: in.Has("incPageNavigation"),
hasPageCursor: in.Has("pageCursor"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *rolesSearchResults
if results, err = h.search(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.Roles (*types.Role) to Array (of Role)
var (
tval expr.TypedValue
tarr = make([]expr.TypedValue, len(results.Roles))
)
for i := range results.Roles {
if tarr[i], err = h.reg.Type("Role").Cast(results.Roles[i]); err != nil {
return
}
}
if tval, err = expr.NewArray(tarr); err != nil {
return
} else if err = expr.Assign(out, "roles", tval); err != nil {
return
}
}
{
// converting results.Total (uint64) to UnsignedInteger
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("UnsignedInteger").Cast(results.Total); err != nil {
return
} else if err = expr.Assign(out, "total", tval); err != nil {
return
}
}
{
// converting results.PageCursor (string) to String
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("String").Cast(results.PageCursor); err != nil {
return
} else if err = expr.Assign(out, "pageCursor", tval); err != nil {
return
}
}
return
},
}
}
type (
rolesEachArgs struct {
hasQuery bool
Query string
hasMemberID bool
MemberID uint64
hasHandle bool
Handle string
hasName bool
Name string
hasLabels bool
Labels map[string]string
hasDeleted bool
Deleted uint64
hasArchived bool
Archived uint64
hasSort bool
Sort string
hasLimit bool
Limit uint64
hasIncTotal bool
IncTotal bool
hasIncPageNavigation bool
IncPageNavigation bool
hasPageCursor bool
PageCursor string
}
rolesEachResults struct {
Role *types.Role
Total uint64
}
)
// Each function Searches for roles and iterates over results
//
// expects implementation of each function:
// func (h rolesHandler) each(ctx context.Context, args *rolesEachArgs) (results *rolesEachResults, err error) {
// return
// }
func (h rolesHandler) Each() *atypes.Function {
return &atypes.Function{
Ref: "rolesEach",
Kind: "iterator",
Meta: &atypes.FunctionMeta{
Short: "Searches for roles and iterates over results",
},
Parameters: []*atypes.Param{
{
Name: "query",
Types: []string{"String"},
},
{
Name: "memberID",
Types: []string{"ID"},
},
{
Name: "handle",
Types: []string{"String"},
},
{
Name: "name",
Types: []string{"String"},
},
{
Name: "labels",
Types: []string{"KV"},
},
{
Name: "deleted",
Types: []string{"UnsignedInteger"},
},
{
Name: "archived",
Types: []string{"UnsignedInteger"},
},
{
Name: "sort",
Types: []string{"String"},
},
{
Name: "limit",
Types: []string{"UnsignedInteger"},
},
{
Name: "incTotal",
Types: []string{"Boolean"},
},
{
Name: "incPageNavigation",
Types: []string{"Boolean"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Results: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"},
},
{
Name: "total",
Types: []string{"UnsignedInteger"},
},
},
Iterator: func(ctx context.Context, in *expr.Vars) (out wfexec.IteratorHandler, err error) {
var (
args = &rolesEachArgs{
hasQuery: in.Has("query"),
hasMemberID: in.Has("memberID"),
hasHandle: in.Has("handle"),
hasName: in.Has("name"),
hasLabels: in.Has("labels"),
hasDeleted: in.Has("deleted"),
hasArchived: in.Has("archived"),
hasSort: in.Has("sort"),
hasLimit: in.Has("limit"),
hasIncTotal: in.Has("incTotal"),
hasIncPageNavigation: in.Has("incPageNavigation"),
hasPageCursor: in.Has("pageCursor"),
}
)
if err = in.Decode(args); err != nil {
return
}
return h.each(ctx, args)
},
}
}
type (
rolesCreateArgs struct {
hasRole bool
Role *types.Role
}
rolesCreateResults struct {
Role *types.Role
}
)
// Create function Creates new role
//
// expects implementation of create function:
// func (h rolesHandler) create(ctx context.Context, args *rolesCreateArgs) (results *rolesCreateResults, err error) {
// return
// }
func (h rolesHandler) Create() *atypes.Function {
return &atypes.Function{
Ref: "rolesCreate",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Creates new role",
},
Parameters: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesCreateArgs{
hasRole: in.Has("role"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *rolesCreateResults
if results, err = h.create(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.Role (*types.Role) to Role
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Role").Cast(results.Role); err != nil {
return
} else if err = expr.Assign(out, "role", tval); err != nil {
return
}
}
return
},
}
}
type (
rolesUpdateArgs struct {
hasRole bool
Role *types.Role
}
rolesUpdateResults struct {
Role *types.Role
}
)
// Update function Updates exiting role
//
// expects implementation of update function:
// func (h rolesHandler) update(ctx context.Context, args *rolesUpdateArgs) (results *rolesUpdateResults, err error) {
// return
// }
func (h rolesHandler) Update() *atypes.Function {
return &atypes.Function{
Ref: "rolesUpdate",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Updates exiting role",
},
Parameters: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "role",
Types: []string{"Role"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesUpdateArgs{
hasRole: in.Has("role"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *rolesUpdateResults
if results, err = h.update(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.Role (*types.Role) to Role
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Role").Cast(results.Role); err != nil {
return
} else if err = expr.Assign(out, "role", tval); err != nil {
return
}
}
return
},
}
}
type (
rolesDeleteArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupRes *types.Role
}
)
func (a rolesDeleteArgs) GetLookup() (bool, uint64, string, *types.Role) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
}
// Delete function Deletes the role
//
// expects implementation of delete function:
// func (h rolesHandler) delete(ctx context.Context, args *rolesDeleteArgs) (err error) {
// return
// }
func (h rolesHandler) Delete() *atypes.Function {
return &atypes.Function{
Ref: "rolesDelete",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Deletes the role",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "Role"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesDeleteArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("Role").Type():
args.lookupRes = aux.Get().(*types.Role)
}
}
return out, h.delete(ctx, args)
},
}
}
type (
rolesRecoverArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupRes *types.Role
}
)
func (a rolesRecoverArgs) GetLookup() (bool, uint64, string, *types.Role) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
}
// Recover function Recovers deleted role
//
// expects implementation of recover function:
// func (h rolesHandler) recover(ctx context.Context, args *rolesRecoverArgs) (err error) {
// return
// }
func (h rolesHandler) Recover() *atypes.Function {
return &atypes.Function{
Ref: "rolesRecover",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Recovers deleted role",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "Role"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesRecoverArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("Role").Type():
args.lookupRes = aux.Get().(*types.Role)
}
}
return out, h.recover(ctx, args)
},
}
}
type (
rolesArchiveArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupRes *types.Role
}
)
func (a rolesArchiveArgs) GetLookup() (bool, uint64, string, *types.Role) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
}
// Archive function Archives the role
//
// expects implementation of archive function:
// func (h rolesHandler) archive(ctx context.Context, args *rolesArchiveArgs) (err error) {
// return
// }
func (h rolesHandler) Archive() *atypes.Function {
return &atypes.Function{
Ref: "rolesArchive",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Archives the role",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "Role"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesArchiveArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("Role").Type():
args.lookupRes = aux.Get().(*types.Role)
}
}
return out, h.archive(ctx, args)
},
}
}
type (
rolesUnarchiveArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupRes *types.Role
}
)
func (a rolesUnarchiveArgs) GetLookup() (bool, uint64, string, *types.Role) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
}
// Unarchive function Unarchives the role
//
// expects implementation of unarchive function:
// func (h rolesHandler) unarchive(ctx context.Context, args *rolesUnarchiveArgs) (err error) {
// return
// }
func (h rolesHandler) Unarchive() *atypes.Function {
return &atypes.Function{
Ref: "rolesUnarchive",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Unarchives the role",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "Role"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &rolesUnarchiveArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("Role").Type():
args.lookupRes = aux.Get().(*types.Role)
}
}
return out, h.unarchive(ctx, args)
},
}
}
+225
View File
@@ -0,0 +1,225 @@
package automation
import (
"context"
"fmt"
. "github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
"github.com/cortezaproject/corteza-server/system/types"
)
type (
roleService interface {
FindByID(ctx context.Context, roleID uint64) (*types.Role, error)
FindByHandle(ctx context.Context, handle string) (*types.Role, error)
Find(ctx context.Context, filter types.RoleFilter) (set types.RoleSet, f types.RoleFilter, err error)
Create(ctx context.Context, role *types.Role) (*types.Role, error)
Update(ctx context.Context, role *types.Role) (*types.Role, error)
Delete(ctx context.Context, id uint64) error
Archive(ctx context.Context, id uint64) error
Unarchive(ctx context.Context, id uint64) error
Undelete(ctx context.Context, id uint64) error
}
rolesHandler struct {
reg rolesHandlerRegistry
rSvc roleService
}
roleSetIterator struct {
ptr int
set types.RoleSet
filter types.RoleFilter
}
roleLookup interface {
GetLookup() (bool, uint64, string, *types.Role)
}
)
func RolesHandler(reg rolesHandlerRegistry, rSvc roleService) *rolesHandler {
h := &rolesHandler{
reg: reg,
rSvc: rSvc,
}
h.register()
return h
}
func (h rolesHandler) lookup(ctx context.Context, args *rolesLookupArgs) (results *rolesLookupResults, err error) {
results = &rolesLookupResults{}
results.Role, err = lookupRole(ctx, h.rSvc, args)
return
}
func (h rolesHandler) search(ctx context.Context, args *rolesSearchArgs) (results *rolesSearchResults, err error) {
results = &rolesSearchResults{}
var (
f = types.RoleFilter{
Query: args.Query,
MemberID: args.MemberID,
Name: args.Name,
Handle: args.Handle,
Labels: args.Labels,
Deleted: filter.State(args.Deleted),
Archived: filter.State(args.Archived),
}
)
if args.hasSort {
if err = f.Sort.Set(args.Sort); err != nil {
return
}
}
if args.hasPageCursor {
if err = f.PageCursor.Decode(args.PageCursor); err != nil {
return
}
}
if args.hasLabels {
f.Labels = args.Labels
}
if args.hasLimit {
f.Limit = uint(args.Limit)
}
results.Roles, _, err = h.rSvc.Find(ctx, f)
return
}
func (h rolesHandler) each(ctx context.Context, args *rolesEachArgs) (out wfexec.IteratorHandler, err error) {
var (
i = &roleSetIterator{}
f = types.RoleFilter{
Query: args.Query,
MemberID: args.MemberID,
Name: args.Name,
Handle: args.Handle,
Labels: args.Labels,
Deleted: filter.State(args.Deleted),
Archived: filter.State(args.Archived),
}
)
if args.hasSort {
if err = f.Sort.Set(args.Sort); err != nil {
return
}
}
if args.hasPageCursor {
if err = f.PageCursor.Decode(args.PageCursor); err != nil {
return
}
}
if args.hasLabels {
f.Labels = args.Labels
}
if args.hasLimit {
f.Limit = uint(args.Limit)
}
i.set, i.filter, err = h.rSvc.Find(ctx, f)
return i, err
}
func (h rolesHandler) create(ctx context.Context, args *rolesCreateArgs) (results *rolesCreateResults, err error) {
results = &rolesCreateResults{}
results.Role, err = h.rSvc.Create(ctx, args.Role)
return
}
func (h rolesHandler) update(ctx context.Context, args *rolesUpdateArgs) (results *rolesUpdateResults, err error) {
results = &rolesUpdateResults{}
results.Role, err = h.rSvc.Update(ctx, args.Role)
return
}
func (h rolesHandler) delete(ctx context.Context, args *rolesDeleteArgs) error {
if id, err := getRoleID(ctx, h.rSvc, args); err != nil {
return err
} else {
return h.rSvc.Delete(ctx, id)
}
}
func (h rolesHandler) recover(ctx context.Context, args *rolesRecoverArgs) error {
if id, err := getRoleID(ctx, h.rSvc, args); err != nil {
return err
} else {
return h.rSvc.Undelete(ctx, id)
}
}
func (h rolesHandler) archive(ctx context.Context, args *rolesArchiveArgs) error {
if id, err := getRoleID(ctx, h.rSvc, args); err != nil {
return err
} else {
return h.rSvc.Archive(ctx, id)
}
}
func (h rolesHandler) unarchive(ctx context.Context, args *rolesUnarchiveArgs) error {
if id, err := getRoleID(ctx, h.rSvc, args); err != nil {
return err
} else {
return h.rSvc.Unarchive(ctx, id)
}
}
func getRoleID(ctx context.Context, svc roleService, args roleLookup) (uint64, error) {
_, ID, _, _ := args.GetLookup()
if ID > 0 {
return ID, nil
}
role, err := lookupRole(ctx, svc, args)
if err != nil {
return 0, err
}
return role.ID, nil
}
func lookupRole(ctx context.Context, svc roleService, args roleLookup) (*types.Role, error) {
_, ID, handle, role := args.GetLookup()
switch {
case role != nil:
return role, nil
case ID > 0:
return svc.FindByID(ctx, ID)
case len(handle) > 0:
return svc.FindByHandle(ctx, handle)
}
return nil, fmt.Errorf("empty lookup params")
}
func (i *roleSetIterator) More(context.Context, *Vars) (bool, error) {
return i.ptr < len(i.set), nil
}
func (i *roleSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
func (i *roleSetIterator) Next(context.Context, *Vars) (*Vars, error) {
out := RVars{
"role": Must(NewRole(i.set[i.ptr])),
"total": Must(NewUnsignedInteger(i.filter.Total)),
}
i.ptr++
return out.Vars(), nil
}
+135
View File
@@ -0,0 +1,135 @@
imports:
- github.com/cortezaproject/corteza-server/system/types
params:
lookup: &lookup
required: true
types:
- { wf: ID, }
- { wf: Handle, }
- { wf: Role, suffix: res }
role: &role
types:
- { wf: Role }
rvRole: &rvRole
wf: Role
rvTotal: &rvTotal
wf: UnsignedInteger
rvPageCursor: &rvPageCursor
wf: String
filterParams: &filterParams
query:
types:
- { wf: String }
memberID:
types:
- { wf: ID }
handle:
types:
- { wf: String }
name:
types:
- { wf: String }
labels:
types:
- { wf: KV }
deleted:
types:
- { wf: UnsignedInteger }
archived:
types:
- { wf: UnsignedInteger }
sort:
types:
- { wf: String }
limit:
types:
- { wf: UnsignedInteger }
incTotal:
types:
- { wf: Boolean }
incPageNavigation:
types:
- { wf: Boolean }
pageCursor:
types:
- { wf: String }
functions:
lookup:
meta:
short: Looks-up for role by ID
params:
lookup: *lookup
results:
role: *rvRole
search:
meta:
short: Searches for roles and returns them
params: *filterParams
results:
roles:
<<: *rvRole
isArray: true
total: *rvTotal
pageCursor: *rvPageCursor
each:
kind: iterator
meta:
short: Searches for roles and iterates over results
params: *filterParams
results:
role: *rvRole
total: *rvTotal
create:
meta:
short: Creates new role
params:
role:
<<: *role
required: true
results:
role: *rvRole
update:
meta:
short: Updates exiting role
params:
role:
<<: *role
required: true
results:
role: *rvRole
delete:
meta:
short: Deletes the role
params:
lookup: *lookup
recover:
meta:
short: Recovers deleted role
params:
lookup: *lookup
archive:
meta:
short: Archives the role
params:
lookup: *lookup
unarchive:
meta:
short: Unarchives the role
params:
lookup: *lookup
+903
View File
@@ -0,0 +1,903 @@
package automation
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// system/automation/users_handler.yaml
import (
"context"
atypes "github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
"github.com/cortezaproject/corteza-server/system/types"
)
var _ wfexec.ExecResponse
type (
usersHandlerRegistry interface {
AddFunctions(ff ...*atypes.Function)
Type(ref string) expr.Type
}
)
func (h usersHandler) register() {
h.reg.AddFunctions(
h.Lookup(),
h.Search(),
h.Each(),
h.Create(),
h.Update(),
h.Delete(),
h.Recover(),
h.Suspend(),
h.Unsuspend(),
)
}
type (
usersLookupArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupEmail string
lookupRes *types.User
}
usersLookupResults struct {
User *types.User
}
)
func (a usersLookupArgs) GetLookup() (bool, uint64, string, string, *types.User) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
}
// Lookup function Looks-up for user by ID
//
// expects implementation of lookup function:
// func (h usersHandler) lookup(ctx context.Context, args *usersLookupArgs) (results *usersLookupResults, err error) {
// return
// }
func (h usersHandler) Lookup() *atypes.Function {
return &atypes.Function{
Ref: "usersLookup",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Looks-up for user by ID",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "user",
Types: []string{"User"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersLookupArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("String").Type():
args.lookupEmail = aux.Get().(string)
case h.reg.Type("User").Type():
args.lookupRes = aux.Get().(*types.User)
}
}
var results *usersLookupResults
if results, err = h.lookup(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.User (*types.User) to User
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("User").Cast(results.User); err != nil {
return
} else if err = expr.Assign(out, "user", tval); err != nil {
return
}
}
return
},
}
}
type (
usersSearchArgs struct {
hasQuery bool
Query string
hasEmail bool
Email string
hasHandle bool
Handle string
hasLabels bool
Labels map[string]string
hasDeleted bool
Deleted uint64
hasSuspended bool
Suspended uint64
hasSort bool
Sort string
hasLimit bool
Limit uint64
hasIncTotal bool
IncTotal bool
hasIncPageNavigation bool
IncPageNavigation bool
hasPageCursor bool
PageCursor string
}
usersSearchResults struct {
Users []*types.User
Total uint64
PageCursor string
}
)
// Search function Searches for users and returns them
//
// expects implementation of search function:
// func (h usersHandler) search(ctx context.Context, args *usersSearchArgs) (results *usersSearchResults, err error) {
// return
// }
func (h usersHandler) Search() *atypes.Function {
return &atypes.Function{
Ref: "usersSearch",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Searches for users and returns them",
},
Parameters: []*atypes.Param{
{
Name: "query",
Types: []string{"String"},
},
{
Name: "email",
Types: []string{"String"},
},
{
Name: "handle",
Types: []string{"String"},
},
{
Name: "labels",
Types: []string{"KV"},
},
{
Name: "deleted",
Types: []string{"UnsignedInteger"},
},
{
Name: "suspended",
Types: []string{"UnsignedInteger"},
},
{
Name: "sort",
Types: []string{"String"},
},
{
Name: "limit",
Types: []string{"UnsignedInteger"},
},
{
Name: "incTotal",
Types: []string{"Boolean"},
},
{
Name: "incPageNavigation",
Types: []string{"Boolean"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Results: []*atypes.Param{
{
Name: "users",
Types: []string{"User"},
IsArray: true,
},
{
Name: "total",
Types: []string{"UnsignedInteger"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersSearchArgs{
hasQuery: in.Has("query"),
hasEmail: in.Has("email"),
hasHandle: in.Has("handle"),
hasLabels: in.Has("labels"),
hasDeleted: in.Has("deleted"),
hasSuspended: in.Has("suspended"),
hasSort: in.Has("sort"),
hasLimit: in.Has("limit"),
hasIncTotal: in.Has("incTotal"),
hasIncPageNavigation: in.Has("incPageNavigation"),
hasPageCursor: in.Has("pageCursor"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *usersSearchResults
if results, err = h.search(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.Users (*types.User) to Array (of User)
var (
tval expr.TypedValue
tarr = make([]expr.TypedValue, len(results.Users))
)
for i := range results.Users {
if tarr[i], err = h.reg.Type("User").Cast(results.Users[i]); err != nil {
return
}
}
if tval, err = expr.NewArray(tarr); err != nil {
return
} else if err = expr.Assign(out, "users", tval); err != nil {
return
}
}
{
// converting results.Total (uint64) to UnsignedInteger
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("UnsignedInteger").Cast(results.Total); err != nil {
return
} else if err = expr.Assign(out, "total", tval); err != nil {
return
}
}
{
// converting results.PageCursor (string) to String
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("String").Cast(results.PageCursor); err != nil {
return
} else if err = expr.Assign(out, "pageCursor", tval); err != nil {
return
}
}
return
},
}
}
type (
usersEachArgs struct {
hasQuery bool
Query string
hasEmail bool
Email string
hasHandle bool
Handle string
hasLabels bool
Labels map[string]string
hasDeleted bool
Deleted uint64
hasSuspended bool
Suspended uint64
hasSort bool
Sort string
hasLimit bool
Limit uint64
hasIncTotal bool
IncTotal bool
hasIncPageNavigation bool
IncPageNavigation bool
hasPageCursor bool
PageCursor string
}
usersEachResults struct {
User *types.User
Total uint64
}
)
// Each function Searches for users and iterates over results
//
// expects implementation of each function:
// func (h usersHandler) each(ctx context.Context, args *usersEachArgs) (results *usersEachResults, err error) {
// return
// }
func (h usersHandler) Each() *atypes.Function {
return &atypes.Function{
Ref: "usersEach",
Kind: "iterator",
Meta: &atypes.FunctionMeta{
Short: "Searches for users and iterates over results",
},
Parameters: []*atypes.Param{
{
Name: "query",
Types: []string{"String"},
},
{
Name: "email",
Types: []string{"String"},
},
{
Name: "handle",
Types: []string{"String"},
},
{
Name: "labels",
Types: []string{"KV"},
},
{
Name: "deleted",
Types: []string{"UnsignedInteger"},
},
{
Name: "suspended",
Types: []string{"UnsignedInteger"},
},
{
Name: "sort",
Types: []string{"String"},
},
{
Name: "limit",
Types: []string{"UnsignedInteger"},
},
{
Name: "incTotal",
Types: []string{"Boolean"},
},
{
Name: "incPageNavigation",
Types: []string{"Boolean"},
},
{
Name: "pageCursor",
Types: []string{"String"},
},
},
Results: []*atypes.Param{
{
Name: "user",
Types: []string{"User"},
},
{
Name: "total",
Types: []string{"UnsignedInteger"},
},
},
Iterator: func(ctx context.Context, in *expr.Vars) (out wfexec.IteratorHandler, err error) {
var (
args = &usersEachArgs{
hasQuery: in.Has("query"),
hasEmail: in.Has("email"),
hasHandle: in.Has("handle"),
hasLabels: in.Has("labels"),
hasDeleted: in.Has("deleted"),
hasSuspended: in.Has("suspended"),
hasSort: in.Has("sort"),
hasLimit: in.Has("limit"),
hasIncTotal: in.Has("incTotal"),
hasIncPageNavigation: in.Has("incPageNavigation"),
hasPageCursor: in.Has("pageCursor"),
}
)
if err = in.Decode(args); err != nil {
return
}
return h.each(ctx, args)
},
}
}
type (
usersCreateArgs struct {
hasUser bool
User *types.User
}
usersCreateResults struct {
User *types.User
}
)
// Create function Creates new user
//
// expects implementation of create function:
// func (h usersHandler) create(ctx context.Context, args *usersCreateArgs) (results *usersCreateResults, err error) {
// return
// }
func (h usersHandler) Create() *atypes.Function {
return &atypes.Function{
Ref: "usersCreate",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Creates new user",
},
Parameters: []*atypes.Param{
{
Name: "user",
Types: []string{"User"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "user",
Types: []string{"User"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersCreateArgs{
hasUser: in.Has("user"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *usersCreateResults
if results, err = h.create(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.User (*types.User) to User
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("User").Cast(results.User); err != nil {
return
} else if err = expr.Assign(out, "user", tval); err != nil {
return
}
}
return
},
}
}
type (
usersUpdateArgs struct {
hasUser bool
User *types.User
}
usersUpdateResults struct {
User *types.User
}
)
// Update function Updates exiting user
//
// expects implementation of update function:
// func (h usersHandler) update(ctx context.Context, args *usersUpdateArgs) (results *usersUpdateResults, err error) {
// return
// }
func (h usersHandler) Update() *atypes.Function {
return &atypes.Function{
Ref: "usersUpdate",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Updates exiting user",
},
Parameters: []*atypes.Param{
{
Name: "user",
Types: []string{"User"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "user",
Types: []string{"User"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersUpdateArgs{
hasUser: in.Has("user"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *usersUpdateResults
if results, err = h.update(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.User (*types.User) to User
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("User").Cast(results.User); err != nil {
return
} else if err = expr.Assign(out, "user", tval); err != nil {
return
}
}
return
},
}
}
type (
usersDeleteArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupEmail string
lookupRes *types.User
}
)
func (a usersDeleteArgs) GetLookup() (bool, uint64, string, string, *types.User) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
}
// Delete function Deletes user
//
// expects implementation of delete function:
// func (h usersHandler) delete(ctx context.Context, args *usersDeleteArgs) (err error) {
// return
// }
func (h usersHandler) Delete() *atypes.Function {
return &atypes.Function{
Ref: "usersDelete",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Deletes user",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersDeleteArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("String").Type():
args.lookupEmail = aux.Get().(string)
case h.reg.Type("User").Type():
args.lookupRes = aux.Get().(*types.User)
}
}
return out, h.delete(ctx, args)
},
}
}
type (
usersRecoverArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupEmail string
lookupRes *types.User
}
)
func (a usersRecoverArgs) GetLookup() (bool, uint64, string, string, *types.User) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
}
// Recover function Recovers deleted user
//
// expects implementation of recover function:
// func (h usersHandler) recover(ctx context.Context, args *usersRecoverArgs) (err error) {
// return
// }
func (h usersHandler) Recover() *atypes.Function {
return &atypes.Function{
Ref: "usersRecover",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Recovers deleted user",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersRecoverArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("String").Type():
args.lookupEmail = aux.Get().(string)
case h.reg.Type("User").Type():
args.lookupRes = aux.Get().(*types.User)
}
}
return out, h.recover(ctx, args)
},
}
}
type (
usersSuspendArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupEmail string
lookupRes *types.User
}
)
func (a usersSuspendArgs) GetLookup() (bool, uint64, string, string, *types.User) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
}
// Suspend function Suspends user
//
// expects implementation of suspend function:
// func (h usersHandler) suspend(ctx context.Context, args *usersSuspendArgs) (err error) {
// return
// }
func (h usersHandler) Suspend() *atypes.Function {
return &atypes.Function{
Ref: "usersSuspend",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Suspends user",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersSuspendArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("String").Type():
args.lookupEmail = aux.Get().(string)
case h.reg.Type("User").Type():
args.lookupRes = aux.Get().(*types.User)
}
}
return out, h.suspend(ctx, args)
},
}
}
type (
usersUnsuspendArgs struct {
hasLookup bool
Lookup interface{}
lookupID uint64
lookupHandle string
lookupEmail string
lookupRes *types.User
}
)
func (a usersUnsuspendArgs) GetLookup() (bool, uint64, string, string, *types.User) {
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
}
// Unsuspend function Unsuspends user
//
// expects implementation of unsuspend function:
// func (h usersHandler) unsuspend(ctx context.Context, args *usersUnsuspendArgs) (err error) {
// return
// }
func (h usersHandler) Unsuspend() *atypes.Function {
return &atypes.Function{
Ref: "usersUnsuspend",
Kind: "function",
Meta: &atypes.FunctionMeta{
Short: "Unsuspends user",
},
Parameters: []*atypes.Param{
{
Name: "lookup",
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &usersUnsuspendArgs{
hasLookup: in.Has("lookup"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Lookup argument
if args.hasLookup {
aux := expr.Must(expr.Select(in, "lookup"))
switch aux.Type() {
case h.reg.Type("ID").Type():
args.lookupID = aux.Get().(uint64)
case h.reg.Type("Handle").Type():
args.lookupHandle = aux.Get().(string)
case h.reg.Type("String").Type():
args.lookupEmail = aux.Get().(string)
case h.reg.Type("User").Type():
args.lookupRes = aux.Get().(*types.User)
}
}
return out, h.unsuspend(ctx, args)
},
}
}
+226
View File
@@ -0,0 +1,226 @@
package automation
import (
"context"
"fmt"
. "github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
"github.com/cortezaproject/corteza-server/system/types"
)
type (
userService interface {
FindByID(ctx context.Context, userID uint64) (*types.User, error)
FindByHandle(ctx context.Context, handle string) (*types.User, error)
FindByEmail(ctx context.Context, email string) (*types.User, error)
Find(ctx context.Context, filter types.UserFilter) (set types.UserSet, f types.UserFilter, err error)
Create(ctx context.Context, user *types.User) (*types.User, error)
Update(ctx context.Context, user *types.User) (*types.User, error)
Delete(ctx context.Context, id uint64) error
Suspend(ctx context.Context, id uint64) error
Unsuspend(ctx context.Context, id uint64) error
Undelete(ctx context.Context, id uint64) error
}
usersHandler struct {
reg usersHandlerRegistry
uSvc userService
}
userSetIterator struct {
ptr int
set types.UserSet
filter types.UserFilter
}
userLookup interface {
GetLookup() (bool, uint64, string, string, *types.User)
}
)
func UsersHandler(reg usersHandlerRegistry, uSvc userService) *usersHandler {
h := &usersHandler{
reg: reg,
uSvc: uSvc,
}
h.register()
return h
}
func (h usersHandler) lookup(ctx context.Context, args *usersLookupArgs) (results *usersLookupResults, err error) {
results = &usersLookupResults{}
results.User, err = lookupUser(ctx, h.uSvc, args)
return
}
func (h usersHandler) search(ctx context.Context, args *usersSearchArgs) (results *usersSearchResults, err error) {
results = &usersSearchResults{}
var (
f = types.UserFilter{
Query: args.Query,
Email: args.Email,
Handle: args.Handle,
Labels: args.Labels,
Deleted: filter.State(args.Deleted),
Suspended: filter.State(args.Suspended),
}
)
if args.hasSort {
if err = f.Sort.Set(args.Sort); err != nil {
return
}
}
if args.hasPageCursor {
if err = f.PageCursor.Decode(args.PageCursor); err != nil {
return
}
}
if args.hasLabels {
f.Labels = args.Labels
}
if args.hasLimit {
f.Limit = uint(args.Limit)
}
results.Users, _, err = h.uSvc.Find(ctx, f)
return
}
func (h usersHandler) each(ctx context.Context, args *usersEachArgs) (out wfexec.IteratorHandler, err error) {
var (
i = &userSetIterator{}
f = types.UserFilter{
Query: args.Query,
Email: args.Email,
Handle: args.Handle,
Labels: args.Labels,
Deleted: filter.State(args.Deleted),
Suspended: filter.State(args.Suspended),
}
)
if args.hasSort {
if err = f.Sort.Set(args.Sort); err != nil {
return
}
}
if args.hasPageCursor {
if err = f.PageCursor.Decode(args.PageCursor); err != nil {
return
}
}
if args.hasLabels {
f.Labels = args.Labels
}
if args.hasLimit {
f.Limit = uint(args.Limit)
}
i.set, i.filter, err = h.uSvc.Find(ctx, f)
return i, err
}
func (h usersHandler) create(ctx context.Context, args *usersCreateArgs) (results *usersCreateResults, err error) {
results = &usersCreateResults{}
results.User, err = h.uSvc.Create(ctx, args.User)
return
}
func (h usersHandler) update(ctx context.Context, args *usersUpdateArgs) (results *usersUpdateResults, err error) {
results = &usersUpdateResults{}
results.User, err = h.uSvc.Update(ctx, args.User)
return
}
func (h usersHandler) delete(ctx context.Context, args *usersDeleteArgs) error {
if id, err := getUserID(ctx, h.uSvc, args); err != nil {
return err
} else {
return h.uSvc.Delete(ctx, id)
}
}
func (h usersHandler) recover(ctx context.Context, args *usersRecoverArgs) error {
if id, err := getUserID(ctx, h.uSvc, args); err != nil {
return err
} else {
return h.uSvc.Undelete(ctx, id)
}
}
func (h usersHandler) suspend(ctx context.Context, args *usersSuspendArgs) error {
if id, err := getUserID(ctx, h.uSvc, args); err != nil {
return err
} else {
return h.uSvc.Suspend(ctx, id)
}
}
func (h usersHandler) unsuspend(ctx context.Context, args *usersUnsuspendArgs) error {
if id, err := getUserID(ctx, h.uSvc, args); err != nil {
return err
} else {
return h.uSvc.Unsuspend(ctx, id)
}
}
func getUserID(ctx context.Context, svc userService, args userLookup) (uint64, error) {
_, ID, _, _, _ := args.GetLookup()
if ID > 0 {
return ID, nil
}
user, err := lookupUser(ctx, svc, args)
if err != nil {
return 0, err
}
return user.ID, nil
}
func lookupUser(ctx context.Context, svc userService, args userLookup) (*types.User, error) {
_, ID, handle, email, user := args.GetLookup()
switch {
case user != nil:
return user, nil
case ID > 0:
return svc.FindByID(ctx, ID)
case len(email) > 0:
return svc.FindByEmail(ctx, email)
case len(handle) > 0:
return svc.FindByHandle(ctx, handle)
}
return nil, fmt.Errorf("empty lookup params")
}
func (i *userSetIterator) More(context.Context, *Vars) (bool, error) {
return i.ptr < len(i.set), nil
}
func (i *userSetIterator) Start(context.Context, *Vars) error { i.ptr = 0; return nil }
func (i *userSetIterator) Next(context.Context, *Vars) (*Vars, error) {
out := RVars{
"user": Must(NewUser(i.set[i.ptr])),
"total": Must(NewUnsignedInteger(i.filter.Total)),
}
i.ptr++
return out.Vars(), nil
}
+132
View File
@@ -0,0 +1,132 @@
imports:
- github.com/cortezaproject/corteza-server/system/types
snippets:
lookup: &lookup
required: true
types:
- { wf: ID }
- { wf: Handle }
- { wf: String, suffix: email }
- { wf: User, suffix: res }
user: &user
types:
- { wf: User }
rvUser: &rvUser
wf: User
rvTotal: &rvTotal
wf: UnsignedInteger
rvPageCursor: &rvPageCursor
wf: String
filterParams: &filterParams
query:
types:
- { wf: String }
email:
types:
- { wf: String }
handle:
types:
- { wf: String }
labels:
types:
- { wf: KV }
deleted:
types:
- { wf: UnsignedInteger }
suspended:
types:
- { wf: UnsignedInteger }
sort:
types:
- { wf: String }
limit:
types:
- { wf: UnsignedInteger }
incTotal:
types:
- { wf: Boolean }
incPageNavigation:
types:
- { wf: Boolean }
pageCursor:
types:
- { wf: String }
functions:
lookup:
meta:
short: Looks-up for user by ID
params:
lookup: *lookup
results:
user: *rvUser
search:
meta:
short: Searches for users and returns them
params: *filterParams
results:
users:
<<: *rvUser
isArray: true
total: *rvTotal
pageCursor: *rvPageCursor
each:
kind: iterator
meta:
short: Searches for users and iterates over results
params: *filterParams
results:
user: *rvUser
total: *rvTotal
create:
meta:
short: Creates new user
params:
user:
<<: *user
required: true
results:
user: *rvUser
update:
meta:
short: Updates exiting user
params:
user:
<<: *user
required: true
results:
user: *rvUser
delete:
meta:
short: Deletes user
params:
lookup: *lookup
recover:
meta:
short: Recovers deleted user
params:
lookup: *lookup
suspend:
meta:
short: Suspends user
params:
lookup: *lookup
unsuspend:
meta:
short: Unsuspends user
params:
lookup: *lookup
+21 -4
View File
@@ -3,23 +3,23 @@ package service
import (
"context"
"errors"
"time"
"github.com/cortezaproject/corteza-server/pkg/logger"
automationService "github.com/cortezaproject/corteza-server/automation/service"
"github.com/cortezaproject/corteza-server/pkg/actionlog"
intAuth "github.com/cortezaproject/corteza-server/pkg/auth"
"github.com/cortezaproject/corteza-server/pkg/eventbus"
"github.com/cortezaproject/corteza-server/pkg/healthcheck"
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/pkg/objstore"
"github.com/cortezaproject/corteza-server/pkg/objstore/minio"
"github.com/cortezaproject/corteza-server/pkg/objstore/plain"
"github.com/cortezaproject/corteza-server/pkg/options"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/automation"
"github.com/cortezaproject/corteza-server/system/types"
"go.uber.org/zap"
"time"
)
type (
@@ -181,6 +181,23 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, c Config)
DefaultAttachment = Attachment(DefaultObjectStore)
DefaultRenderer = Renderer(c.Template)
automationService.DefaultUser = DefaultUser
automationService.Registry().AddTypes(
automation.User{},
automation.Role{},
)
automation.UsersHandler(
automationService.Registry(),
DefaultUser,
)
automation.RolesHandler(
automationService.Registry(),
DefaultRole,
)
return
}
+2 -2
View File
@@ -91,7 +91,7 @@ type (
)
func User(ctx context.Context) UserService {
return (&user{
return &user{
eventbus: eventbus.Service(),
ac: DefaultAccessControl,
settings: CurrentSettings,
@@ -102,7 +102,7 @@ func User(ctx context.Context) UserService {
actionlog: DefaultActionlog,
subscription: CurrentSubscription,
})
}
}
func (svc user) FindByID(ctx context.Context, userID uint64) (u *types.User, err error) {