Implement CEL filter in list user command

This commit is contained in:
PiMaDaum 2023-02-05 21:57:01 +01:00
parent 6562aeab95
commit f30590588e
2 changed files with 78 additions and 0 deletions

69
user/filter.go Normal file
View file

@ -0,0 +1,69 @@
package user
import (
"context"
"fmt"
"github.com/google/cel-go/cel"
"github.com/passbolt/go-passbolt/api"
)
// Environments for CEl
var celEnvOptions = []cel.EnvOption{
cel.Variable("ID", cel.StringType),
cel.Variable("Username", cel.StringType),
cel.Variable("FirstName", cel.StringType),
cel.Variable("LastName", cel.StringType),
cel.Variable("Role", cel.StringType),
cel.Variable("CreatedTimestamp", cel.TimestampType),
cel.Variable("ModifiedTimestamp", cel.TimestampType),
}
// Filters the slice users by invoke CEL program for each user
func filterUsers(users *[]api.User, celCmd string, ctx context.Context) ([]api.User, error) {
if celCmd == "" {
return *users, nil
}
env, err := cel.NewEnv(celEnvOptions...)
if err != nil {
return nil, err
}
ast, issue := env.Compile(celCmd)
if issue.Err() != nil {
return nil, issue.Err()
}
program, err := env.Program(ast)
if err != nil {
return nil, err
}
filteredUsers := []api.User{}
for _, user := range *users {
val, _, err := program.ContextEval(ctx, map[string]any{
"ID": user.ID,
"Username": user.Username,
"FirstName": user.Profile.FirstName,
"LastName": user.Profile.LastName,
"Role": user.Role.Name,
"CreatedTimestamp": user.Created.Time,
"ModifiedTimestamp": user.Modified.Time,
})
if err != nil {
return nil, err
}
if val.Value() == true {
filteredUsers = append(filteredUsers, user)
}
}
if len(filteredUsers) == 0 {
return nil, fmt.Errorf("No such users found with filter %v!", celCmd)
}
return filteredUsers, nil
}

View file

@ -62,6 +62,10 @@ func UserList(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}
celFilter, err := cmd.Flags().GetString("filter")
if err != nil {
return err
}
ctx := util.GetContext()
@ -82,6 +86,11 @@ func UserList(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Listing User: %w", err)
}
users, err = filterUsers(&users, celFilter, ctx)
if err != nil {
return err
}
if jsonOutput {
outputUsers := []UserJsonOutput{}
for i := range users {