Add role membership workflow handlers
This commit is contained in:
404
system/automation/roles_handler.gen.go
generated
404
system/automation/roles_handler.gen.go
generated
@@ -28,6 +28,10 @@ type (
|
||||
func (h rolesHandler) register() {
|
||||
h.reg.AddFunctions(
|
||||
h.Lookup(),
|
||||
h.SearchMembers(),
|
||||
h.EachMember(),
|
||||
h.AddMember(),
|
||||
h.RemoveMember(),
|
||||
h.Search(),
|
||||
h.Each(),
|
||||
h.Create(),
|
||||
@@ -137,6 +141,406 @@ func (h rolesHandler) Lookup() *atypes.Function {
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
rolesSearchMembersArgs struct {
|
||||
hasLookup bool
|
||||
Lookup interface{}
|
||||
lookupID uint64
|
||||
lookupHandle string
|
||||
lookupRes *types.Role
|
||||
}
|
||||
|
||||
rolesSearchMembersResults struct {
|
||||
Users []*types.User
|
||||
Total uint64
|
||||
}
|
||||
)
|
||||
|
||||
func (a rolesSearchMembersArgs) GetLookup() (bool, uint64, string, *types.Role) {
|
||||
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
|
||||
}
|
||||
|
||||
// SearchMembers function Role members search
|
||||
//
|
||||
// expects implementation of searchMembers function:
|
||||
// func (h rolesHandler) searchMembers(ctx context.Context, args *rolesSearchMembersArgs) (results *rolesSearchMembersResults, err error) {
|
||||
// return
|
||||
// }
|
||||
func (h rolesHandler) SearchMembers() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "rolesSearchMembers",
|
||||
Kind: "function",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "Role members search",
|
||||
Description: "Find members for a specific roleby ID or handle",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "lookup",
|
||||
Types: []string{"ID", "Handle", "Role"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Results: []*atypes.Param{
|
||||
|
||||
{
|
||||
Name: "users",
|
||||
Types: []string{"User"},
|
||||
IsArray: true,
|
||||
},
|
||||
|
||||
{
|
||||
Name: "total",
|
||||
Types: []string{"UnsignedInteger"},
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &rolesSearchMembersArgs{
|
||||
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 *rolesSearchMembersResults
|
||||
if results, err = h.searchMembers(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
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
rolesEachMemberArgs struct {
|
||||
hasLookup bool
|
||||
Lookup interface{}
|
||||
lookupID uint64
|
||||
lookupHandle string
|
||||
lookupRes *types.Role
|
||||
}
|
||||
|
||||
rolesEachMemberResults struct {
|
||||
User *types.User
|
||||
Total uint64
|
||||
}
|
||||
)
|
||||
|
||||
func (a rolesEachMemberArgs) GetLookup() (bool, uint64, string, *types.Role) {
|
||||
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupRes
|
||||
}
|
||||
|
||||
// EachMember function Iterate over role members
|
||||
//
|
||||
// expects implementation of eachMember function:
|
||||
// func (h rolesHandler) eachMember(ctx context.Context, args *rolesEachMemberArgs) (results *rolesEachMemberResults, err error) {
|
||||
// return
|
||||
// }
|
||||
func (h rolesHandler) EachMember() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "rolesEachMember",
|
||||
Kind: "iterator",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "Iterate over role members",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "lookup",
|
||||
Types: []string{"ID", "Handle", "Role"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
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 = &rolesEachMemberArgs{
|
||||
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 h.eachMember(ctx, args)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
rolesAddMemberArgs struct {
|
||||
hasRole bool
|
||||
Role interface{}
|
||||
roleID uint64
|
||||
roleHandle string
|
||||
roleRes *types.Role
|
||||
|
||||
hasUser bool
|
||||
User interface{}
|
||||
userID uint64
|
||||
userHandle string
|
||||
userEmail string
|
||||
userRes *types.User
|
||||
}
|
||||
)
|
||||
|
||||
func (a rolesAddMemberArgs) GetRole() (bool, uint64, string, *types.Role) {
|
||||
return a.hasRole, a.roleID, a.roleHandle, a.roleRes
|
||||
}
|
||||
|
||||
func (a rolesAddMemberArgs) GetUser() (bool, uint64, string, string, *types.User) {
|
||||
return a.hasUser, a.userID, a.userHandle, a.userEmail, a.userRes
|
||||
}
|
||||
|
||||
// AddMember function Role membership add
|
||||
//
|
||||
// expects implementation of addMember function:
|
||||
// func (h rolesHandler) addMember(ctx context.Context, args *rolesAddMemberArgs) (err error) {
|
||||
// return
|
||||
// }
|
||||
func (h rolesHandler) AddMember() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "rolesAddMember",
|
||||
Kind: "function",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "Role membership add",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "role",
|
||||
Types: []string{"ID", "Handle", "Role"}, Required: true,
|
||||
},
|
||||
{
|
||||
Name: "user",
|
||||
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &rolesAddMemberArgs{
|
||||
hasRole: in.Has("role"),
|
||||
hasUser: in.Has("user"),
|
||||
}
|
||||
)
|
||||
|
||||
if err = in.Decode(args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Converting Role argument
|
||||
if args.hasRole {
|
||||
aux := expr.Must(expr.Select(in, "role"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.roleID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.roleHandle = aux.Get().(string)
|
||||
case h.reg.Type("Role").Type():
|
||||
args.roleRes = aux.Get().(*types.Role)
|
||||
}
|
||||
}
|
||||
|
||||
// Converting User argument
|
||||
if args.hasUser {
|
||||
aux := expr.Must(expr.Select(in, "user"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.userID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.userHandle = aux.Get().(string)
|
||||
case h.reg.Type("String").Type():
|
||||
args.userEmail = aux.Get().(string)
|
||||
case h.reg.Type("User").Type():
|
||||
args.userRes = aux.Get().(*types.User)
|
||||
}
|
||||
}
|
||||
|
||||
return out, h.addMember(ctx, args)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
rolesRemoveMemberArgs struct {
|
||||
hasRole bool
|
||||
Role interface{}
|
||||
roleID uint64
|
||||
roleHandle string
|
||||
roleRes *types.Role
|
||||
|
||||
hasUser bool
|
||||
User interface{}
|
||||
userID uint64
|
||||
userHandle string
|
||||
userEmail string
|
||||
userRes *types.User
|
||||
}
|
||||
)
|
||||
|
||||
func (a rolesRemoveMemberArgs) GetRole() (bool, uint64, string, *types.Role) {
|
||||
return a.hasRole, a.roleID, a.roleHandle, a.roleRes
|
||||
}
|
||||
|
||||
func (a rolesRemoveMemberArgs) GetUser() (bool, uint64, string, string, *types.User) {
|
||||
return a.hasUser, a.userID, a.userHandle, a.userEmail, a.userRes
|
||||
}
|
||||
|
||||
// RemoveMember function Role membership remove
|
||||
//
|
||||
// expects implementation of removeMember function:
|
||||
// func (h rolesHandler) removeMember(ctx context.Context, args *rolesRemoveMemberArgs) (err error) {
|
||||
// return
|
||||
// }
|
||||
func (h rolesHandler) RemoveMember() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "rolesRemoveMember",
|
||||
Kind: "function",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "Role membership remove",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "role",
|
||||
Types: []string{"ID", "Handle", "Role"}, Required: true,
|
||||
},
|
||||
{
|
||||
Name: "user",
|
||||
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &rolesRemoveMemberArgs{
|
||||
hasRole: in.Has("role"),
|
||||
hasUser: in.Has("user"),
|
||||
}
|
||||
)
|
||||
|
||||
if err = in.Decode(args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Converting Role argument
|
||||
if args.hasRole {
|
||||
aux := expr.Must(expr.Select(in, "role"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.roleID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.roleHandle = aux.Get().(string)
|
||||
case h.reg.Type("Role").Type():
|
||||
args.roleRes = aux.Get().(*types.Role)
|
||||
}
|
||||
}
|
||||
|
||||
// Converting User argument
|
||||
if args.hasUser {
|
||||
aux := expr.Must(expr.Select(in, "user"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.userID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.userHandle = aux.Get().(string)
|
||||
case h.reg.Type("String").Type():
|
||||
args.userEmail = aux.Get().(string)
|
||||
case h.reg.Type("User").Type():
|
||||
args.userRes = aux.Get().(*types.User)
|
||||
}
|
||||
}
|
||||
|
||||
return out, h.removeMember(ctx, args)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
rolesSearchArgs struct {
|
||||
hasQuery bool
|
||||
|
||||
@@ -2,6 +2,7 @@ package automation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
. "github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
@@ -23,11 +24,17 @@ type (
|
||||
Archive(ctx context.Context, id uint64) error
|
||||
Unarchive(ctx context.Context, id uint64) error
|
||||
Undelete(ctx context.Context, id uint64) error
|
||||
|
||||
Membership(ctx context.Context, userID uint64) (types.RoleMemberSet, error)
|
||||
MemberList(ctx context.Context, roleID uint64) (types.RoleMemberSet, error)
|
||||
MemberAdd(ctx context.Context, roleID, userID uint64) error
|
||||
MemberRemove(ctx context.Context, roleID, userID uint64) error
|
||||
}
|
||||
|
||||
rolesHandler struct {
|
||||
reg rolesHandlerRegistry
|
||||
rSvc roleService
|
||||
uSvc userService
|
||||
}
|
||||
|
||||
roleSetIterator struct {
|
||||
@@ -41,10 +48,11 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func RolesHandler(reg rolesHandlerRegistry, rSvc roleService) *rolesHandler {
|
||||
func RolesHandler(reg rolesHandlerRegistry, rSvc roleService, uSvc userService) *rolesHandler {
|
||||
h := &rolesHandler{
|
||||
reg: reg,
|
||||
rSvc: rSvc,
|
||||
uSvc: uSvc,
|
||||
}
|
||||
|
||||
h.register()
|
||||
@@ -57,6 +65,143 @@ func (h rolesHandler) lookup(ctx context.Context, args *rolesLookupArgs) (result
|
||||
return
|
||||
}
|
||||
|
||||
func (h rolesHandler) searchMembers(ctx context.Context, args *rolesSearchMembersArgs) (results *rolesSearchMembersResults, err error) {
|
||||
results = &rolesSearchMembersResults{}
|
||||
|
||||
rl, err := lookupRole(ctx, h.rSvc, args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if rl == nil {
|
||||
return nil, errors.New("role not found")
|
||||
}
|
||||
|
||||
// Get membership info
|
||||
mm, err := h.rSvc.MemberList(ctx, rl.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(mm) == 0 {
|
||||
results.Users = []*types.User{}
|
||||
return
|
||||
}
|
||||
|
||||
// Get actual users
|
||||
uu := make([]uint64, len(mm))
|
||||
for i, m := range mm {
|
||||
uu[i] = m.UserID
|
||||
}
|
||||
results.Users, _, err = h.uSvc.Find(ctx, types.UserFilter{
|
||||
UserID: uu,
|
||||
})
|
||||
results.Total = uint64(len(results.Users))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (h rolesHandler) eachMember(ctx context.Context, args *rolesEachMemberArgs) (out wfexec.IteratorHandler, err error) {
|
||||
var (
|
||||
i = &userSetIterator{}
|
||||
)
|
||||
|
||||
rl, err := lookupRole(ctx, h.rSvc, args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if rl == nil {
|
||||
return nil, errors.New("role not found")
|
||||
}
|
||||
|
||||
// Get membership info
|
||||
mm, err := h.rSvc.MemberList(ctx, rl.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(mm) == 0 {
|
||||
i.set = []*types.User{}
|
||||
i.filter = types.UserFilter{}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// Get actual users
|
||||
uu := make([]uint64, len(mm))
|
||||
for i, m := range mm {
|
||||
uu[i] = m.UserID
|
||||
}
|
||||
i.set, i.filter, err = h.uSvc.Find(ctx, types.UserFilter{
|
||||
UserID: uu,
|
||||
})
|
||||
return i, err
|
||||
}
|
||||
|
||||
func (h rolesHandler) addMember(ctx context.Context, args *rolesAddMemberArgs) (err error) {
|
||||
role, err := lookupRole(ctx, h.rSvc, &rolesLookupArgs{
|
||||
hasLookup: args.hasRole,
|
||||
Lookup: args.Role,
|
||||
lookupID: args.roleID,
|
||||
lookupHandle: args.roleHandle,
|
||||
lookupRes: args.roleRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if role == nil {
|
||||
return errors.New("role not found")
|
||||
}
|
||||
|
||||
user, err := lookupUser(ctx, h.uSvc, &usersLookupArgs{
|
||||
hasLookup: args.hasUser,
|
||||
Lookup: args.User,
|
||||
lookupID: args.userID,
|
||||
lookupHandle: args.userHandle,
|
||||
lookupEmail: args.userEmail,
|
||||
lookupRes: args.userRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if role == nil {
|
||||
return errors.New("user not found")
|
||||
}
|
||||
|
||||
return h.rSvc.MemberAdd(ctx, role.ID, user.ID)
|
||||
}
|
||||
|
||||
func (h rolesHandler) removeMember(ctx context.Context, args *rolesRemoveMemberArgs) (err error) {
|
||||
role, err := lookupRole(ctx, h.rSvc, &rolesLookupArgs{
|
||||
hasLookup: args.hasRole,
|
||||
Lookup: args.Role,
|
||||
lookupID: args.roleID,
|
||||
lookupHandle: args.roleHandle,
|
||||
lookupRes: args.roleRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if role == nil {
|
||||
return errors.New("role not found")
|
||||
}
|
||||
|
||||
user, err := lookupUser(ctx, h.uSvc, &usersLookupArgs{
|
||||
hasLookup: args.hasUser,
|
||||
Lookup: args.User,
|
||||
lookupID: args.userID,
|
||||
lookupHandle: args.userHandle,
|
||||
lookupEmail: args.userEmail,
|
||||
lookupRes: args.userRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if role == nil {
|
||||
return errors.New("user not found")
|
||||
}
|
||||
|
||||
return h.rSvc.MemberRemove(ctx, role.ID, user.ID)
|
||||
}
|
||||
|
||||
func (h rolesHandler) search(ctx context.Context, args *rolesSearchArgs) (results *rolesSearchResults, err error) {
|
||||
results = &rolesSearchResults{}
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ params:
|
||||
rvRole: &rvRole
|
||||
wf: Role
|
||||
|
||||
rvUser: &rvUser
|
||||
wf: User
|
||||
|
||||
rvTotal: &rvTotal
|
||||
wf: UnsignedInteger
|
||||
@@ -23,6 +25,14 @@ params:
|
||||
rvPageCursor: &rvPageCursor
|
||||
wf: String
|
||||
|
||||
lookupUser: &lookupUser
|
||||
required: true
|
||||
types:
|
||||
- { wf: ID }
|
||||
- { wf: Handle }
|
||||
- { wf: String, suffix: email }
|
||||
- { wf: User, suffix: res }
|
||||
|
||||
filterParams: &filterParams
|
||||
query:
|
||||
types:
|
||||
@@ -76,6 +86,50 @@ functions:
|
||||
results:
|
||||
role: *rvRole
|
||||
|
||||
searchMembers:
|
||||
meta:
|
||||
short: Role members search
|
||||
description: Find members for a specific roleby ID or handle
|
||||
labels:
|
||||
<<: *labels
|
||||
params:
|
||||
lookup: *lookup
|
||||
results:
|
||||
users:
|
||||
<<: *rvUser
|
||||
isArray: true
|
||||
total: *rvTotal
|
||||
|
||||
eachMember:
|
||||
kind: iterator
|
||||
meta:
|
||||
short: Iterate over role members
|
||||
labels:
|
||||
<<: *labels
|
||||
params:
|
||||
lookup: *lookup
|
||||
results:
|
||||
user: *rvUser
|
||||
total: *rvTotal
|
||||
|
||||
addMember:
|
||||
meta:
|
||||
short: Role membership add
|
||||
labels:
|
||||
<<: *labels
|
||||
params:
|
||||
role: *lookup
|
||||
user: *lookupUser
|
||||
|
||||
removeMember:
|
||||
meta:
|
||||
short: Role membership remove
|
||||
labels:
|
||||
<<: *labels
|
||||
params:
|
||||
role: *lookup
|
||||
user: *lookupUser
|
||||
|
||||
search:
|
||||
meta:
|
||||
short: Roles search
|
||||
|
||||
259
system/automation/users_handler.gen.go
generated
259
system/automation/users_handler.gen.go
generated
@@ -28,6 +28,8 @@ type (
|
||||
func (h usersHandler) register() {
|
||||
h.reg.AddFunctions(
|
||||
h.Lookup(),
|
||||
h.SearchMembership(),
|
||||
h.CheckMembership(),
|
||||
h.Search(),
|
||||
h.Each(),
|
||||
h.Create(),
|
||||
@@ -140,6 +142,263 @@ func (h usersHandler) Lookup() *atypes.Function {
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
usersSearchMembershipArgs struct {
|
||||
hasLookup bool
|
||||
Lookup interface{}
|
||||
lookupID uint64
|
||||
lookupHandle string
|
||||
lookupEmail string
|
||||
lookupRes *types.User
|
||||
}
|
||||
|
||||
usersSearchMembershipResults struct {
|
||||
Roles []*types.Role
|
||||
Total uint64
|
||||
}
|
||||
)
|
||||
|
||||
func (a usersSearchMembershipArgs) GetLookup() (bool, uint64, string, string, *types.User) {
|
||||
return a.hasLookup, a.lookupID, a.lookupHandle, a.lookupEmail, a.lookupRes
|
||||
}
|
||||
|
||||
// SearchMembership function User role search
|
||||
//
|
||||
// expects implementation of searchMembership function:
|
||||
// func (h usersHandler) searchMembership(ctx context.Context, args *usersSearchMembershipArgs) (results *usersSearchMembershipResults, err error) {
|
||||
// return
|
||||
// }
|
||||
func (h usersHandler) SearchMembership() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "usersSearchMembership",
|
||||
Kind: "function",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "User role search",
|
||||
Description: "Search user role membership by ID, handle or string",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "lookup",
|
||||
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Results: []*atypes.Param{
|
||||
|
||||
{
|
||||
Name: "roles",
|
||||
Types: []string{"Role"},
|
||||
IsArray: true,
|
||||
},
|
||||
|
||||
{
|
||||
Name: "total",
|
||||
Types: []string{"UnsignedInteger"},
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &usersSearchMembershipArgs{
|
||||
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 *usersSearchMembershipResults
|
||||
if results, err = h.searchMembership(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
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
usersCheckMembershipArgs struct {
|
||||
hasUser bool
|
||||
User interface{}
|
||||
userID uint64
|
||||
userHandle string
|
||||
userEmail string
|
||||
userRes *types.User
|
||||
|
||||
hasRole bool
|
||||
Role interface{}
|
||||
roleID uint64
|
||||
roleHandle string
|
||||
roleRes *types.Role
|
||||
}
|
||||
|
||||
usersCheckMembershipResults struct {
|
||||
Member bool
|
||||
}
|
||||
)
|
||||
|
||||
func (a usersCheckMembershipArgs) GetUser() (bool, uint64, string, string, *types.User) {
|
||||
return a.hasUser, a.userID, a.userHandle, a.userEmail, a.userRes
|
||||
}
|
||||
|
||||
func (a usersCheckMembershipArgs) GetRole() (bool, uint64, string, *types.Role) {
|
||||
return a.hasRole, a.roleID, a.roleHandle, a.roleRes
|
||||
}
|
||||
|
||||
// CheckMembership function User membership check
|
||||
//
|
||||
// expects implementation of checkMembership function:
|
||||
// func (h usersHandler) checkMembership(ctx context.Context, args *usersCheckMembershipArgs) (results *usersCheckMembershipResults, err error) {
|
||||
// return
|
||||
// }
|
||||
func (h usersHandler) CheckMembership() *atypes.Function {
|
||||
return &atypes.Function{
|
||||
Ref: "usersCheckMembership",
|
||||
Kind: "function",
|
||||
Labels: map[string]string{"users": "step,workflow"},
|
||||
Meta: &atypes.FunctionMeta{
|
||||
Short: "User membership check",
|
||||
Description: "Find user role membership by ID, handle or string",
|
||||
},
|
||||
|
||||
Parameters: []*atypes.Param{
|
||||
{
|
||||
Name: "user",
|
||||
Types: []string{"ID", "Handle", "String", "User"}, Required: true,
|
||||
},
|
||||
{
|
||||
Name: "role",
|
||||
Types: []string{"ID", "Handle", "Role"}, Required: true,
|
||||
},
|
||||
},
|
||||
|
||||
Results: []*atypes.Param{
|
||||
|
||||
{
|
||||
Name: "member",
|
||||
Types: []string{"Boolean"},
|
||||
},
|
||||
},
|
||||
|
||||
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
|
||||
var (
|
||||
args = &usersCheckMembershipArgs{
|
||||
hasUser: in.Has("user"),
|
||||
hasRole: in.Has("role"),
|
||||
}
|
||||
)
|
||||
|
||||
if err = in.Decode(args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Converting User argument
|
||||
if args.hasUser {
|
||||
aux := expr.Must(expr.Select(in, "user"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.userID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.userHandle = aux.Get().(string)
|
||||
case h.reg.Type("String").Type():
|
||||
args.userEmail = aux.Get().(string)
|
||||
case h.reg.Type("User").Type():
|
||||
args.userRes = aux.Get().(*types.User)
|
||||
}
|
||||
}
|
||||
|
||||
// Converting Role argument
|
||||
if args.hasRole {
|
||||
aux := expr.Must(expr.Select(in, "role"))
|
||||
switch aux.Type() {
|
||||
case h.reg.Type("ID").Type():
|
||||
args.roleID = aux.Get().(uint64)
|
||||
case h.reg.Type("Handle").Type():
|
||||
args.roleHandle = aux.Get().(string)
|
||||
case h.reg.Type("Role").Type():
|
||||
args.roleRes = aux.Get().(*types.Role)
|
||||
}
|
||||
}
|
||||
|
||||
var results *usersCheckMembershipResults
|
||||
if results, err = h.checkMembership(ctx, args); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
out = &expr.Vars{}
|
||||
|
||||
{
|
||||
// converting results.Member (bool) to Boolean
|
||||
var (
|
||||
tval expr.TypedValue
|
||||
)
|
||||
|
||||
if tval, err = h.reg.Type("Boolean").Cast(results.Member); err != nil {
|
||||
return
|
||||
} else if err = expr.Assign(out, "member", tval); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
usersSearchArgs struct {
|
||||
hasQuery bool
|
||||
|
||||
@@ -2,6 +2,7 @@ package automation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
. "github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
@@ -29,6 +30,7 @@ type (
|
||||
usersHandler struct {
|
||||
reg usersHandlerRegistry
|
||||
uSvc userService
|
||||
rSvc roleService
|
||||
}
|
||||
|
||||
userSetIterator struct {
|
||||
@@ -42,10 +44,11 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func UsersHandler(reg usersHandlerRegistry, uSvc userService) *usersHandler {
|
||||
func UsersHandler(reg usersHandlerRegistry, uSvc userService, rSvc roleService) *usersHandler {
|
||||
h := &usersHandler{
|
||||
reg: reg,
|
||||
uSvc: uSvc,
|
||||
rSvc: rSvc,
|
||||
}
|
||||
|
||||
h.register()
|
||||
@@ -58,6 +61,98 @@ func (h usersHandler) lookup(ctx context.Context, args *usersLookupArgs) (result
|
||||
return
|
||||
}
|
||||
|
||||
func (h usersHandler) searchMembership(ctx context.Context, args *usersSearchMembershipArgs) (results *usersSearchMembershipResults, err error) {
|
||||
results = &usersSearchMembershipResults{}
|
||||
u, err := lookupUser(ctx, h.uSvc, args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if u == nil {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
|
||||
// Get the roles
|
||||
mm, err := h.rSvc.Membership(ctx, u.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(mm) == 0 {
|
||||
results.Roles = []*types.Role{}
|
||||
return
|
||||
}
|
||||
|
||||
rr := make([]uint64, len(mm))
|
||||
for i, r := range mm {
|
||||
rr[i] = r.RoleID
|
||||
}
|
||||
|
||||
results.Roles, _, err = h.rSvc.Find(ctx, types.RoleFilter{
|
||||
RoleID: rr,
|
||||
})
|
||||
results.Total = uint64(len(results.Roles))
|
||||
return
|
||||
}
|
||||
|
||||
func (h usersHandler) checkMembership(ctx context.Context, args *usersCheckMembershipArgs) (results *usersCheckMembershipResults, err error) {
|
||||
results = &usersCheckMembershipResults{}
|
||||
|
||||
// Resolve user
|
||||
u, err := lookupUser(ctx, h.uSvc, usersLookupArgs{
|
||||
hasLookup: args.hasUser,
|
||||
Lookup: args.User,
|
||||
lookupID: args.userID,
|
||||
lookupHandle: args.userHandle,
|
||||
lookupEmail: args.userEmail,
|
||||
lookupRes: args.userRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if u == nil {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
|
||||
// Get user membershio
|
||||
mm, err := h.rSvc.Membership(ctx, u.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if len(mm) == 0 {
|
||||
return &usersCheckMembershipResults{
|
||||
Member: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Resolve role
|
||||
r, err := lookupRole(ctx, h.rSvc, rolesLookupArgs{
|
||||
hasLookup: args.hasRole,
|
||||
Lookup: args.Role,
|
||||
lookupID: args.roleID,
|
||||
lookupHandle: args.roleHandle,
|
||||
lookupRes: args.roleRes,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if r == nil {
|
||||
return nil, errors.New("role not found")
|
||||
}
|
||||
|
||||
// Check if there
|
||||
for _, m := range mm {
|
||||
if m.RoleID == r.ID {
|
||||
return &usersCheckMembershipResults{
|
||||
Member: true,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &usersCheckMembershipResults{
|
||||
Member: false,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h usersHandler) search(ctx context.Context, args *usersSearchArgs) (results *usersSearchResults, err error) {
|
||||
results = &usersSearchResults{}
|
||||
|
||||
|
||||
@@ -10,6 +10,13 @@ snippets:
|
||||
- { wf: String, suffix: email }
|
||||
- { wf: User, suffix: res }
|
||||
|
||||
lookupRole: &lookupRole
|
||||
required: true
|
||||
types:
|
||||
- { wf: ID, }
|
||||
- { wf: Handle, }
|
||||
- { wf: Role, suffix: res }
|
||||
|
||||
user: &user
|
||||
types:
|
||||
- { wf: User }
|
||||
@@ -17,9 +24,15 @@ snippets:
|
||||
rvUser: &rvUser
|
||||
wf: User
|
||||
|
||||
rvRole: &rvRole
|
||||
wf: Role
|
||||
|
||||
rvTotal: &rvTotal
|
||||
wf: UnsignedInteger
|
||||
|
||||
rvInclusion: &rvInclusion
|
||||
wf: Boolean
|
||||
|
||||
rvPageCursor: &rvPageCursor
|
||||
wf: String
|
||||
|
||||
@@ -73,6 +86,32 @@ functions:
|
||||
results:
|
||||
user: *rvUser
|
||||
|
||||
searchMembership:
|
||||
meta:
|
||||
short: User role search
|
||||
description: Search user role membership by ID, handle or string
|
||||
params:
|
||||
lookup: *lookup
|
||||
labels:
|
||||
<<: *labels
|
||||
results:
|
||||
roles:
|
||||
<<: *rvRole
|
||||
isArray: true
|
||||
total: *rvTotal
|
||||
|
||||
checkMembership:
|
||||
meta:
|
||||
short: User membership check
|
||||
description: Find user role membership by ID, handle or string
|
||||
params:
|
||||
user: *lookup
|
||||
role: *lookupRole
|
||||
labels:
|
||||
<<: *labels
|
||||
results:
|
||||
member: *rvInclusion
|
||||
|
||||
search:
|
||||
meta:
|
||||
short: User search
|
||||
|
||||
@@ -187,6 +187,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
|
||||
automation.UsersHandler(
|
||||
automationService.Registry(),
|
||||
DefaultUser,
|
||||
DefaultRole,
|
||||
)
|
||||
|
||||
automation.TemplatesHandler(
|
||||
@@ -197,6 +198,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
|
||||
automation.RolesHandler(
|
||||
automationService.Registry(),
|
||||
DefaultRole,
|
||||
DefaultUser,
|
||||
)
|
||||
|
||||
automation.RbacHandler(
|
||||
|
||||
50
tests/workflows/0003_role_members_test.go
Normal file
50
tests/workflows/0003_role_members_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package workflows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
autTypes "github.com/cortezaproject/corteza-server/automation/types"
|
||||
sysTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test0003_role_members(t *testing.T) {
|
||||
var (
|
||||
ctx = superUser(context.Background())
|
||||
req = require.New(t)
|
||||
)
|
||||
|
||||
req.NoError(defStore.TruncateRoleMembers(ctx))
|
||||
req.NoError(defStore.TruncateUsers(ctx))
|
||||
req.NoError(defStore.TruncateRoles(ctx))
|
||||
|
||||
loadScenario(ctx, t)
|
||||
|
||||
var (
|
||||
aux = struct {
|
||||
UsersPre_r1 sysTypes.UserSet
|
||||
TotalPre_r1 uint64
|
||||
UsersPre_r2 sysTypes.UserSet
|
||||
TotalPre_r2 uint64
|
||||
|
||||
UsersPost_r1 sysTypes.UserSet
|
||||
TotalPost_r1 uint64
|
||||
UsersPost_r2 sysTypes.UserSet
|
||||
TotalPost_r2 uint64
|
||||
}{}
|
||||
vars, _ = mustExecWorkflow(ctx, t, "role-members", autTypes.WorkflowExecParams{})
|
||||
)
|
||||
|
||||
req.NoError(vars.Decode(&aux))
|
||||
|
||||
req.Len(aux.UsersPre_r1, 1)
|
||||
req.Equal(uint64(1), aux.TotalPre_r1)
|
||||
req.Len(aux.UsersPre_r2, 1)
|
||||
req.Equal(uint64(1), aux.TotalPre_r2)
|
||||
|
||||
req.Len(aux.UsersPost_r1, 0)
|
||||
req.Equal(uint64(0), aux.TotalPost_r1)
|
||||
req.Len(aux.UsersPost_r2, 1)
|
||||
req.Equal(uint64(1), aux.TotalPost_r2)
|
||||
}
|
||||
58
tests/workflows/0004_user_membership_test.go
Normal file
58
tests/workflows/0004_user_membership_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package workflows
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
autTypes "github.com/cortezaproject/corteza-server/automation/types"
|
||||
sysTypes "github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test0004_user_membership(t *testing.T) {
|
||||
var (
|
||||
ctx = superUser(context.Background())
|
||||
req = require.New(t)
|
||||
)
|
||||
|
||||
req.NoError(defStore.TruncateRoleMembers(ctx))
|
||||
req.NoError(defStore.TruncateUsers(ctx))
|
||||
req.NoError(defStore.TruncateRoles(ctx))
|
||||
|
||||
loadScenario(ctx, t)
|
||||
|
||||
var (
|
||||
aux = struct {
|
||||
RolesPre_u1 sysTypes.RoleSet
|
||||
TotalPre_u1 uint64
|
||||
RolesPre_u2 sysTypes.RoleSet
|
||||
TotalPre_u2 uint64
|
||||
MemberPre_u1 bool
|
||||
MemberPre_u2 bool
|
||||
|
||||
RolesPost_u1 sysTypes.RoleSet
|
||||
TotalPost_u1 uint64
|
||||
RolesPost_u2 sysTypes.RoleSet
|
||||
TotalPost_u2 uint64
|
||||
MemberPost_u1 bool
|
||||
MemberPost_u2 bool
|
||||
}{}
|
||||
vars, _ = mustExecWorkflow(ctx, t, "user-membership", autTypes.WorkflowExecParams{})
|
||||
)
|
||||
|
||||
req.NoError(vars.Decode(&aux))
|
||||
|
||||
req.Len(aux.RolesPre_u1, 2)
|
||||
req.Equal(uint64(2), aux.TotalPre_u1)
|
||||
req.True(aux.MemberPre_u1)
|
||||
req.Len(aux.RolesPre_u2, 0)
|
||||
req.Equal(uint64(0), aux.TotalPre_u2)
|
||||
req.False(aux.MemberPre_u2)
|
||||
|
||||
req.Len(aux.RolesPost_u1, 1)
|
||||
req.Equal(uint64(1), aux.TotalPost_u1)
|
||||
req.False(aux.MemberPost_u1)
|
||||
req.Len(aux.RolesPost_u2, 0)
|
||||
req.Equal(uint64(0), aux.TotalPost_u2)
|
||||
req.False(aux.MemberPost_u2)
|
||||
}
|
||||
7
tests/workflows/testdata/S0003_role_members/data_model.yaml
vendored
Normal file
7
tests/workflows/testdata/S0003_role_members/data_model.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
users:
|
||||
u1: u1@example.tld
|
||||
u2: u2@example.tld
|
||||
|
||||
roles:
|
||||
r1: Role1
|
||||
r2: Role2
|
||||
74
tests/workflows/testdata/S0003_role_members/workflow.yaml
vendored
Normal file
74
tests/workflows/testdata/S0003_role_members/workflow.yaml
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
workflows:
|
||||
role-members:
|
||||
enabled: true
|
||||
trace: true
|
||||
triggers:
|
||||
- enabled: true
|
||||
stepID: 10
|
||||
|
||||
steps:
|
||||
# Adding membership
|
||||
- stepID: 10
|
||||
kind: function
|
||||
ref: rolesAddMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
- stepID: 11
|
||||
kind: function
|
||||
ref: rolesAddMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r2 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
|
||||
# Get current state
|
||||
- stepID: 20
|
||||
kind: function
|
||||
ref: rolesSearchMembers
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: usersPre_r1, expr: "users" }
|
||||
- { target: totalPre_r1, expr: "total" }
|
||||
- stepID: 21
|
||||
kind: function
|
||||
ref: rolesSearchMembers
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: r2 }
|
||||
results:
|
||||
- { target: usersPre_r2, expr: "users" }
|
||||
- { target: totalPre_r2, expr: "total" }
|
||||
|
||||
# Removing membership
|
||||
- stepID: 30
|
||||
kind: function
|
||||
ref: rolesRemoveMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
|
||||
# Get final state
|
||||
- stepID: 40
|
||||
kind: function
|
||||
ref: rolesSearchMembers
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: usersPost_r1, expr: "users" }
|
||||
- { target: totalPost_r1, expr: "total" }
|
||||
- stepID: 41
|
||||
kind: function
|
||||
ref: rolesSearchMembers
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: r2 }
|
||||
results:
|
||||
- { target: usersPost_r2, expr: "users" }
|
||||
- { target: totalPost_r2, expr: "total" }
|
||||
|
||||
paths:
|
||||
- { parentID: 10, childID: 11 }
|
||||
- { parentID: 11, childID: 20 }
|
||||
- { parentID: 20, childID: 21 }
|
||||
- { parentID: 21, childID: 30 }
|
||||
- { parentID: 30, childID: 40 }
|
||||
- { parentID: 40, childID: 41 }
|
||||
7
tests/workflows/testdata/S0004_user_membership/data_model.yaml
vendored
Normal file
7
tests/workflows/testdata/S0004_user_membership/data_model.yaml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
users:
|
||||
u1: u1@example.tld
|
||||
u2: u2@example.tld
|
||||
|
||||
roles:
|
||||
r1: Role1
|
||||
r2: Role2
|
||||
115
tests/workflows/testdata/S0004_user_membership/workflow.yaml
vendored
Normal file
115
tests/workflows/testdata/S0004_user_membership/workflow.yaml
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
workflows:
|
||||
user-membership:
|
||||
enabled: true
|
||||
trace: true
|
||||
triggers:
|
||||
- enabled: true
|
||||
stepID: 10
|
||||
|
||||
steps:
|
||||
# Adding membership
|
||||
- stepID: 10
|
||||
kind: function
|
||||
ref: rolesAddMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
- stepID: 11
|
||||
kind: function
|
||||
ref: rolesAddMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r2 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
|
||||
# Get current state
|
||||
- stepID: 20
|
||||
kind: function
|
||||
ref: usersSearchMembership
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: u1 }
|
||||
results:
|
||||
- { target: rolesPre_u1, expr: "roles" }
|
||||
- { target: totalPre_u1, expr: "total" }
|
||||
- stepID: 21
|
||||
kind: function
|
||||
ref: usersSearchMembership
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: u2 }
|
||||
results:
|
||||
- { target: rolesPre_u2, expr: "roles" }
|
||||
- { target: totalPre_u2, expr: "total" }
|
||||
|
||||
- stepID: 22
|
||||
kind: function
|
||||
ref: usersCheckMembership
|
||||
arguments:
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: memberPre_u1, expr: "member" }
|
||||
- stepID: 23
|
||||
kind: function
|
||||
ref: usersCheckMembership
|
||||
arguments:
|
||||
- { target: user, type: Handle, value: u2 }
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: memberPre_u2, expr: "member" }
|
||||
|
||||
|
||||
# Removing membership
|
||||
- stepID: 30
|
||||
kind: function
|
||||
ref: rolesRemoveMember
|
||||
arguments:
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
|
||||
# Get final state
|
||||
- stepID: 40
|
||||
kind: function
|
||||
ref: usersSearchMembership
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: u1 }
|
||||
results:
|
||||
- { target: rolesPost_u1, expr: "roles" }
|
||||
- { target: totalPost_u1, expr: "total" }
|
||||
- stepID: 41
|
||||
kind: function
|
||||
ref: usersSearchMembership
|
||||
arguments:
|
||||
- { target: lookup, type: Handle, value: u2 }
|
||||
results:
|
||||
- { target: rolesPost_u2, expr: "roles" }
|
||||
- { target: totalPost_u2, expr: "total" }
|
||||
|
||||
- stepID: 42
|
||||
kind: function
|
||||
ref: usersCheckMembership
|
||||
arguments:
|
||||
- { target: user, type: Handle, value: u1 }
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: memberPost_u1, expr: "member" }
|
||||
- stepID: 43
|
||||
kind: function
|
||||
ref: usersCheckMembership
|
||||
arguments:
|
||||
- { target: user, type: Handle, value: u2 }
|
||||
- { target: role, type: Handle, value: r1 }
|
||||
results:
|
||||
- { target: memberPost_u2, expr: "member" }
|
||||
|
||||
paths:
|
||||
- { parentID: 10, childID: 11 }
|
||||
- { parentID: 11, childID: 20 }
|
||||
- { parentID: 20, childID: 21 }
|
||||
- { parentID: 21, childID: 22 }
|
||||
- { parentID: 22, childID: 23 }
|
||||
|
||||
- { parentID: 23, childID: 30 }
|
||||
|
||||
- { parentID: 30, childID: 40 }
|
||||
- { parentID: 40, childID: 41 }
|
||||
- { parentID: 41, childID: 42 }
|
||||
- { parentID: 42, childID: 43 }
|
||||
Reference in New Issue
Block a user