Implement filtering over CEL on list resources

This commit is contained in:
PiMaDaum 2023-01-29 01:18:55 +01:00
parent a0b7b7daaf
commit 5a464f48da

View file

@ -8,6 +8,9 @@ import (
"time" "time"
"github.com/alessio/shellescape" "github.com/alessio/shellescape"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
"github.com/passbolt/go-passbolt-cli/util" "github.com/passbolt/go-passbolt-cli/util"
"github.com/passbolt/go-passbolt/api" "github.com/passbolt/go-passbolt/api"
"github.com/passbolt/go-passbolt/helper" "github.com/passbolt/go-passbolt/helper"
@ -25,9 +28,21 @@ var ResourceListCmd = &cobra.Command{
RunE: ResourceList, RunE: ResourceList,
} }
var CelEnvOptions = []cel.EnvOption{
cel.Variable("ID", cel.StringType),
cel.Variable("FolderParentID", cel.StringType),
cel.Variable("Name", cel.StringType),
cel.Variable("Username", cel.StringType),
cel.Variable("URI", cel.StringType),
cel.Variable("Password", cel.StringType),
cel.Variable("Description", cel.StringType),
cel.Variable("CreatedTimestamp", cel.TimestampType),
cel.Variable("ModifiedTimestamp", cel.TimestampType)}
func init() { func init() {
ResourceListCmd.Flags().Bool("favorite", false, "Resources that are marked as favorite") ResourceListCmd.Flags().Bool("favorite", false, "Resources that are marked as favorite")
ResourceListCmd.Flags().Bool("own", false, "Resources that are owned by me") ResourceListCmd.Flags().Bool("own", false, "Resources that are owned by me")
ResourceListCmd.Flags().String("filter", "", "Define a CEl expression as filter for resources.")
ResourceListCmd.Flags().StringP("group", "g", "", "Resources that are shared with group") ResourceListCmd.Flags().StringP("group", "g", "", "Resources that are shared with group")
ResourceListCmd.Flags().StringArrayP("folder", "f", []string{}, "Resources that are in folder") ResourceListCmd.Flags().StringArrayP("folder", "f", []string{}, "Resources that are in folder")
@ -63,6 +78,10 @@ func ResourceList(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
celFilter, err := cmd.Flags().GetString("filter")
if err != nil {
return err
}
ctx := util.GetContext() ctx := util.GetContext()
@ -83,6 +102,11 @@ func ResourceList(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Listing Resource: %w", err) return fmt.Errorf("Listing Resource: %w", err)
} }
resources, err = filterResources(&resources, celFilter, ctx, client)
if err != nil {
return err
}
if jsonOutput { if jsonOutput {
outputResources := []ResourceJsonOutput{} outputResources := []ResourceJsonOutput{}
for i := range resources { for i := range resources {
@ -152,3 +176,66 @@ func ResourceList(cmd *cobra.Command, args []string) error {
} }
return nil return nil
} }
func filterResources(resources *[]api.Resource, celCmd string, ctx context.Context, client *api.Client) ([]api.Resource, error) {
if celCmd == "" {
return *resources, 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
}
filteredResources := []api.Resource{}
for _, resource := range *resources {
val, _, err := program.ContextEval(ctx, map[string]any{
"Id": resource.ID,
"FolderParentID": resource.FolderParentID,
"Name": resource.Name,
"Username": resource.Username,
"URI": resource.URI,
"Password": func() ref.Val {
_, _, _, _, pass, _, err := helper.GetResource(ctx, client, resource.ID)
if err != nil {
fmt.Printf("Get Resource %v", err)
return types.String("")
}
return types.String(pass)
},
"Description": func() ref.Val {
_, _, _, _, _, descr, err := helper.GetResource(ctx, client, resource.ID)
if err != nil {
fmt.Printf("Get Resource %v", err)
return types.String("")
}
return types.String(descr)
},
"CreatedTimestamp": resource.Created.Time,
"ModifiedTimestamp": resource.Modified.Time,
})
if err != nil {
return nil, err
}
if val.Value() == true {
filteredResources = append(filteredResources, resource)
}
}
if len(filteredResources) == 0 {
return nil, fmt.Errorf("No such Resources found with filter %v!", celCmd)
}
return filteredResources, nil
}