feat(arbitary/zip): add zip

This commit is contained in:
Kevin Franklin Kim 2024-07-12 16:19:41 +02:00
parent e0327f0da1
commit 6d5a5e31b3
No known key found for this signature in database
4 changed files with 267 additions and 0 deletions

15
arbitrary/zip/README.md Normal file
View File

@ -0,0 +1,15 @@
# POSH zip provider
## Usage
## Configuration
```yaml
zip:
credentials:
default:
field: password
item: teasdfadsfadsfadskjsmj34
vault: zhkmc5znychsqasdfasdfadfa
account: foomo
```

103
arbitrary/zip/command.go Normal file
View File

@ -0,0 +1,103 @@
package zip
import (
"context"
"github.com/foomo/posh/pkg/command/tree"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/prompt/goprompt"
"github.com/foomo/posh/pkg/readline"
"github.com/foomo/posh/pkg/util/files"
"github.com/foomo/posh/pkg/util/suggests"
)
type (
Command struct {
l log.Logger
zip *Zip
commandTree tree.Root
}
CommandOption func(*Command)
)
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, zip *Zip, opts ...CommandOption) *Command {
inst := &Command{
l: l.Named("zip"),
zip: zip,
}
inst.commandTree = tree.New(&tree.Node{
Name: "zip",
Description: "Zip command",
Nodes: tree.Nodes{
{
Name: "extract",
Flags: func(ctx context.Context, r *readline.Readline, fs *readline.FlagSets) error {
fs.Internal().String("cred", "", "configured zip credential name")
if err := fs.Internal().SetValues("cred", inst.zip.Config().CredentialNames()...); err != nil {
return err
}
return nil
},
Args: tree.Args{
{
Name: "filename",
Description: "Path to zip file",
Suggest: func(ctx context.Context, t tree.Root, r *readline.Readline) []goprompt.Suggest {
ret, _ := files.Find(ctx, ".", "*.zip",
files.FindWithIgnore(`^\.`, "vendor", "node_modules"),
)
return suggests.List(ret)
},
},
},
Execute: inst.extract,
},
},
})
return inst
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Command) Name() string {
return c.commandTree.Node().Name
}
func (c *Command) Description() string {
return c.commandTree.Node().Description
}
func (c *Command) Complete(ctx context.Context, r *readline.Readline) []goprompt.Suggest {
return c.commandTree.Complete(ctx, r)
}
func (c *Command) Execute(ctx context.Context, r *readline.Readline) error {
return c.commandTree.Execute(ctx, r)
}
func (c *Command) Help(ctx context.Context, r *readline.Readline) string {
return c.commandTree.Help(ctx, r)
}
// ------------------------------------------------------------------------------------------------
// ~ Private methods
// ------------------------------------------------------------------------------------------------
func (c *Command) extract(ctx context.Context, r *readline.Readline) error {
ifs := r.FlagSets().Internal()
filename := r.Args().At(1)
if cred := log.MustGet(ifs.GetString("cred"))(c.l); cred != "" {
return c.zip.ExtractWithPassword(ctx, filename, cred)
}
return c.zip.Extract(ctx, filename)
}

19
arbitrary/zip/config.go Normal file
View File

@ -0,0 +1,19 @@
package zip
import (
"github.com/foomo/posh-providers/onepassword"
"github.com/samber/lo"
)
type Config struct {
Credentials map[string]onepassword.Secret `json:"credentials" yaml:"credentials"`
}
func (c Config) Credential(name string) (onepassword.Secret, bool) {
value, ok := c.Credentials[name]
return value, ok
}
func (c Config) CredentialNames() []string {
return lo.Keys(c.Credentials)
}

130
arbitrary/zip/zip.go Normal file
View File

@ -0,0 +1,130 @@
package zip
import (
"context"
"fmt"
"path"
"github.com/foomo/posh-providers/onepassword"
"github.com/foomo/posh/pkg/log"
"github.com/foomo/posh/pkg/shell"
"github.com/pkg/errors"
"github.com/spf13/viper"
)
type (
Zip struct {
l log.Logger
cfg Config
configKey string
op *onepassword.OnePassword
}
Option func(*Zip) error
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
func WithConfigKey(v string) Option {
return func(o *Zip) error {
o.configKey = v
return nil
}
}
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func New(l log.Logger, op *onepassword.OnePassword, opts ...Option) (*Zip, error) {
inst := &Zip{
l: l,
op: op,
configKey: "zip",
}
for _, opt := range opts {
if opt != nil {
if err := opt(inst); err != nil {
return nil, err
}
}
}
if err := viper.UnmarshalKey(inst.configKey, &inst.cfg); err != nil {
return nil, err
}
return inst, nil
}
// ------------------------------------------------------------------------------------------------
// ~ Getter
// ------------------------------------------------------------------------------------------------
func (c *Zip) Config() Config {
return c.cfg
}
// ------------------------------------------------------------------------------------------------
// ~ Public methods
// ------------------------------------------------------------------------------------------------
func (c *Zip) Create(ctx context.Context, filename string) error {
basename := path.Base(filename)
if out, err := shell.New(ctx, c.l, "zip", basename+".zip", basename).
Dir(path.Dir(filename)).
Output(); err != nil {
return errors.Wrap(err, string(out))
}
return nil
}
func (c *Zip) Extract(ctx context.Context, filename string) error {
basename := path.Base(filename)
if out, err := shell.New(ctx, c.l, "unzip", basename).
Dir(path.Dir(filename)).
Output(); err != nil {
return errors.Wrap(err, string(out))
}
return nil
}
func (c *Zip) CreateWithPassword(ctx context.Context, filename, credential string) error {
basename := path.Base(filename)
password, err := c.GetCredentialPassword(ctx, credential)
if err != nil {
return err
}
if out, err := shell.New(ctx, c.l, "zip", "-e", "-P", password, basename+".zip", basename).
Dir(path.Dir(filename)).
Output(); err != nil {
return errors.Wrap(err, string(out))
}
return nil
}
func (c *Zip) ExtractWithPassword(ctx context.Context, filename, credential string) error {
basename := path.Base(filename)
password, err := c.GetCredentialPassword(ctx, credential)
if err != nil {
return err
}
if out, err := shell.New(ctx, c.l, "unzip", "-P", password, basename).
Dir(path.Dir(filename)).
Output(); err != nil {
return errors.Wrap(err, string(out))
}
return nil
}
func (c *Zip) GetCredentialPassword(ctx context.Context, name string) (string, error) {
secret, ok := c.cfg.Credential(name)
if !ok {
return "", fmt.Errorf("credential %s not found", name)
}
return c.op.Get(ctx, secret)
}