mirror of
https://github.com/passbolt/go-passbolt-cli.git
synced 2025-05-12 10:58:21 +00:00
Merge pull request #26 from PiMaDaum/feature/CEL-filter-implementation
feature/CEL filter implementation
This commit is contained in:
commit
7fe89a34b3
12 changed files with 333 additions and 2 deletions
|
@ -19,6 +19,12 @@ var listCmd = &cobra.Command{
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(listCmd)
|
rootCmd.AddCommand(listCmd)
|
||||||
listCmd.PersistentFlags().BoolP("json", "j", false, "Output JSON")
|
listCmd.PersistentFlags().BoolP("json", "j", false, "Output JSON")
|
||||||
|
listCmd.PersistentFlags().String("filter", "",
|
||||||
|
"Define a CEl expression as filter for any list commands. In the expression, all available columns of subcommand can be used (see -c/--column).\n"+
|
||||||
|
"See also CEl specifications under https://github.com/google/cel-spec.\n"+
|
||||||
|
"Examples:\n"+
|
||||||
|
"\t--filter '(Name == \"SomeName\" || matches(Name, \"RegExpr\")) && URI.startsWith(\"https://auth.\")'\n"+
|
||||||
|
"\t--filter 'Username == \"User\" && CreatedTimestamp > timestamp(\"2022-06-10T00:00:00.000-00:00\")'")
|
||||||
listCmd.AddCommand(resource.ResourceListCmd)
|
listCmd.AddCommand(resource.ResourceListCmd)
|
||||||
listCmd.AddCommand(folder.FolderListCmd)
|
listCmd.AddCommand(folder.FolderListCmd)
|
||||||
listCmd.AddCommand(group.GroupListCmd)
|
listCmd.AddCommand(group.GroupListCmd)
|
||||||
|
|
56
folder/filter.go
Normal file
56
folder/filter.go
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
package folder
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/cel-go/cel"
|
||||||
|
"github.com/passbolt/go-passbolt-cli/util"
|
||||||
|
"github.com/passbolt/go-passbolt/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environments for CEl
|
||||||
|
var celEnvOptions = []cel.EnvOption{
|
||||||
|
cel.Variable("ID", cel.StringType),
|
||||||
|
cel.Variable("FolderParentID", cel.StringType),
|
||||||
|
cel.Variable("Name", cel.StringType),
|
||||||
|
cel.Variable("CreatedTimestamp", cel.TimestampType),
|
||||||
|
cel.Variable("ModifiedTimestamp", cel.TimestampType),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters the slice folders by invoke CEL program for each folder
|
||||||
|
func filterFolders(folders *[]api.Folder, celCmd string, ctx context.Context) ([]api.Folder, error) {
|
||||||
|
if celCmd == "" {
|
||||||
|
return *folders, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
program, err := util.InitCELProgram(celCmd, celEnvOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredFolders := []api.Folder{}
|
||||||
|
for _, folder := range *folders {
|
||||||
|
val, _, err := (*program).ContextEval(ctx, map[string]any{
|
||||||
|
"ID": folder.ID,
|
||||||
|
"FolderParentID": folder.FolderParentID,
|
||||||
|
"Name": folder.Name,
|
||||||
|
"CreatedTimestamp": folder.Created.Time,
|
||||||
|
"ModifiedTimestamp": folder.Modified.Time,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.Value() == true {
|
||||||
|
filteredFolders = append(filteredFolders, folder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(filteredFolders) == 0 {
|
||||||
|
return nil, fmt.Errorf("No such folders found with filter %v!", celCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredFolders, nil
|
||||||
|
}
|
|
@ -51,6 +51,10 @@ func FolderList(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()
|
||||||
cmd.SilenceUsage = true
|
cmd.SilenceUsage = true
|
||||||
|
@ -69,6 +73,11 @@ func FolderList(cmd *cobra.Command, args []string) error {
|
||||||
return fmt.Errorf("Listing Folder: %w", err)
|
return fmt.Errorf("Listing Folder: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
folders, err = filterFolders(&folders, celFilter, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
outputFolders := []FolderJsonOutput{}
|
outputFolders := []FolderJsonOutput{}
|
||||||
for i := range folders {
|
for i := range folders {
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -20,10 +20,12 @@ require (
|
||||||
github.com/ProtonMail/gopenpgp/v2 v2.5.0 // indirect
|
github.com/ProtonMail/gopenpgp/v2 v2.5.0 // indirect
|
||||||
github.com/aead/argon2 v0.0.0-20180111183520-a87724528b07 // indirect
|
github.com/aead/argon2 v0.0.0-20180111183520-a87724528b07 // indirect
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||||
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||||
github.com/cloudflare/circl v1.3.1 // indirect
|
github.com/cloudflare/circl v1.3.1 // indirect
|
||||||
github.com/containerd/console v1.0.3 // indirect
|
github.com/containerd/console v1.0.3 // indirect
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
|
github.com/google/cel-go v0.13.0 // indirect
|
||||||
github.com/google/go-querystring v1.1.0 // indirect
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/gookit/color v1.5.2 // indirect
|
github.com/gookit/color v1.5.2 // indirect
|
||||||
|
@ -42,11 +44,14 @@ require (
|
||||||
github.com/spf13/cast v1.5.0 // indirect
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||||
github.com/subosito/gotenv v1.4.1 // indirect
|
github.com/subosito/gotenv v1.4.1 // indirect
|
||||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||||
golang.org/x/crypto v0.4.0 // indirect
|
golang.org/x/crypto v0.4.0 // indirect
|
||||||
golang.org/x/sys v0.3.0 // indirect
|
golang.org/x/sys v0.3.0 // indirect
|
||||||
golang.org/x/text v0.5.0 // indirect
|
golang.org/x/text v0.5.0 // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect
|
||||||
|
google.golang.org/protobuf v1.28.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -66,6 +66,8 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
|
||||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||||
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
|
||||||
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||||
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
|
||||||
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||||
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
|
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
|
||||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
@ -123,8 +125,11 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/cel-go v0.13.0 h1:z+8OBOcmh7IeKyqwT/6IlnMvy621fYUqnTVPEdegGlU=
|
||||||
|
github.com/google/cel-go v0.13.0/go.mod h1:K2hpQgEjDp18J76a2DKFRlPBPpgRZgi6EbnpDgIhJ8s=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
@ -134,6 +139,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
|
@ -239,6 +245,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
|
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
|
||||||
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
|
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
@ -550,6 +558,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
|
||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+Ca/rDdKubLIU9rcJ3xfy1DC/Wd2Oo=
|
||||||
|
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
@ -576,6 +586,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||||
|
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
|
|
54
group/filter.go
Normal file
54
group/filter.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package group
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/cel-go/cel"
|
||||||
|
"github.com/passbolt/go-passbolt-cli/util"
|
||||||
|
"github.com/passbolt/go-passbolt/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environments for CEl
|
||||||
|
var celEnvOptions = []cel.EnvOption{
|
||||||
|
cel.Variable("ID", cel.StringType),
|
||||||
|
cel.Variable("Name", cel.StringType),
|
||||||
|
cel.Variable("CreatedTimestamp", cel.TimestampType),
|
||||||
|
cel.Variable("ModifiedTimestamp", cel.TimestampType),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters the slice groups by invoke CEL program for each group
|
||||||
|
func filterGroups(groups *[]api.Group, celCmd string, ctx context.Context) ([]api.Group, error) {
|
||||||
|
if celCmd == "" {
|
||||||
|
return *groups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
program, err := util.InitCELProgram(celCmd, celEnvOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredGroups := []api.Group{}
|
||||||
|
for _, group := range *groups {
|
||||||
|
val, _, err := (*program).ContextEval(ctx, map[string]any{
|
||||||
|
"ID": group.ID,
|
||||||
|
"Name": group.Name,
|
||||||
|
"CreatedTimestamp": group.Created.Time,
|
||||||
|
"ModifiedTimestamp": group.Modified.Time,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.Value() == true {
|
||||||
|
filteredGroups = append(filteredGroups, group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(filteredGroups) == 0 {
|
||||||
|
return nil, fmt.Errorf("No such groups found with filter %v!", celCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredGroups, nil
|
||||||
|
}
|
|
@ -51,6 +51,10 @@ func GroupList(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()
|
||||||
|
|
||||||
|
@ -69,6 +73,11 @@ func GroupList(cmd *cobra.Command, args []string) error {
|
||||||
return fmt.Errorf("Listing Group: %w", err)
|
return fmt.Errorf("Listing Group: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
groups, err = filterGroups(&groups, celFilter, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
outputGroups := []GroupJsonOutput{}
|
outputGroups := []GroupJsonOutput{}
|
||||||
for i := range groups {
|
for i := range groups {
|
||||||
|
|
80
resource/filter.go
Normal file
80
resource/filter.go
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
package resource
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"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/api"
|
||||||
|
"github.com/passbolt/go-passbolt/helper"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Environments for CEl
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filters the slice resources by invoke CEL program for each resource
|
||||||
|
func filterResources(resources *[]api.Resource, celCmd string, ctx context.Context, client *api.Client) ([]api.Resource, error) {
|
||||||
|
if celCmd == "" {
|
||||||
|
return *resources, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
program, err := util.InitCELProgram(celCmd, celEnvOptions...)
|
||||||
|
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
|
||||||
|
}
|
|
@ -28,10 +28,8 @@ var ResourceListCmd = &cobra.Command{
|
||||||
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().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")
|
||||||
|
|
||||||
ResourceListCmd.Flags().StringArrayP("column", "c", []string{"ID", "FolderParentID", "Name", "Username", "URI"}, "Columns to return, possible Columns:\nID, FolderParentID, Name, Username, URI, Password, Description, CreatedTimestamp, ModifiedTimestamp")
|
ResourceListCmd.Flags().StringArrayP("column", "c", []string{"ID", "FolderParentID", "Name", "Username", "URI"}, "Columns to return, possible Columns:\nID, FolderParentID, Name, Username, URI, Password, Description, CreatedTimestamp, ModifiedTimestamp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +61,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 +85,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 {
|
||||||
|
|
60
user/filter.go
Normal file
60
user/filter.go
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/cel-go/cel"
|
||||||
|
"github.com/passbolt/go-passbolt-cli/util"
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
||||||
|
program, err := util.InitCELProgram(celCmd, celEnvOptions...)
|
||||||
|
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
|
||||||
|
}
|
|
@ -62,6 +62,10 @@ func UserList(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()
|
||||||
|
|
||||||
|
@ -82,6 +86,11 @@ func UserList(cmd *cobra.Command, args []string) error {
|
||||||
return fmt.Errorf("Listing User: %w", err)
|
return fmt.Errorf("Listing User: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
users, err = filterUsers(&users, celFilter, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if jsonOutput {
|
if jsonOutput {
|
||||||
outputUsers := []UserJsonOutput{}
|
outputUsers := []UserJsonOutput{}
|
||||||
for i := range users {
|
for i := range users {
|
||||||
|
|
23
util/cel.go
Normal file
23
util/cel.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "github.com/google/cel-go/cel"
|
||||||
|
|
||||||
|
// InitCELProgram - Initialize a CEL program with given CEL command and a set of environments
|
||||||
|
func InitCELProgram(celCmd string, options ...cel.EnvOption) (*cel.Program, error) {
|
||||||
|
env, err := cel.NewEnv(options...)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return &program, nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue