diff options
-rw-r--r-- | cmd/search.go | 76 | ||||
-rw-r--r-- | datadir/datadir.go | 48 |
2 files changed, 124 insertions, 0 deletions
diff --git a/cmd/search.go b/cmd/search.go new file mode 100644 index 0000000..ba831df --- /dev/null +++ b/cmd/search.go @@ -0,0 +1,76 @@ +package cmd + +import ( + "context" + "encoding/json" + "github.com/pablotron/cvez/datadir" + "github.com/pablotron/cvez/dbstore" + "github.com/spf13/cobra" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "os" + "strings" + "time" +) + +// Build query string. +func getSearchQuery(args []string) string { + r := make([]string, len(args)) + + for i, v := range(args) { + r[i] = "\"" + strings.ReplaceAll(strings.ToLower(v), "\"", "\"\"") + "\"" + } + + return strings.Join(r, " AND ") +} + +// Get database store. +func getDb() dbstore.DbStore { + // build database path + dbPath, err := datadir.Join("cvez.db") + if err != nil { + log.Error().Err(err).Msg("Join") + os.Exit(-1) + } + + // open database + db, err := dbstore.Open(dbPath) + if err != nil { + log.Error().Err(err).Msg("Open") + os.Exit(-1) + } + + return db +} + +var searchCmd = &cobra.Command{ + Use: "search", + Args: cobra.MinimumNArgs(1), + Short: "Search CVEs.", + Long: `Common Vulnerability Enumeration (CVE) search.`, + + Run: func(cmd *cobra.Command, args []string) { + ctx := context.Background() + + // set global logging options + zerolog.TimeFieldFormat = time.RFC3339 + zerolog.SetGlobalLevel(zerolog.InfoLevel) + + // search for CVEs + rows, err := getDb().CveSearch(ctx, getSearchQuery(args)) + if err != nil { + log.Error().Err(err).Msg("CveSearch") + os.Exit(-1) + } + + // search for CVEs, write result + e := json.NewEncoder(os.Stdout) + if err := e.Encode(rows); err != nil { + log.Error().Err(err).Msg("Encode") + } + }, +} + +func init() { + rootCmd.AddCommand(searchCmd) +} diff --git a/datadir/datadir.go b/datadir/datadir.go new file mode 100644 index 0000000..9019e5d --- /dev/null +++ b/datadir/datadir.go @@ -0,0 +1,48 @@ +// data directory +package datadir + +import ( + "errors" + "io/fs" + "os" + "path/filepath" +) + +// Get data directory path. +func DataDir() (string, error) { + var dir string + + // check environment + if val, ok := os.LookupEnv("CVEZ_DATA_DIR"); ok { + return val, nil + } + + // get config dir + configDir, err := os.UserConfigDir() + if err != nil { + return dir, err + } + + // build path to data directory in config dir + dir = filepath.Join(configDir, "cvez") + if _, err = os.Stat(dir); err != nil { + if errors.Is(err, fs.ErrNotExist) { + // create data directory + return dir, os.MkdirAll(dir, 0700) + } else { + // return error + return "", err + } + } else { + return dir, nil + } +} + +// Build path to file in cvez data directory. +func Join(args ...string) (string, error) { + if dir, err := DataDir(); err != nil { + return "", err + } else { + return filepath.Join(dir, filepath.Join(args...)), nil + } +} |