posh-providers/onepassword/command.go
2023-03-20 11:44:56 +01:00

137 lines
3.4 KiB
Go

package onepassword
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/shell"
)
type (
Command struct {
l log.Logger
op *OnePassword
commandTree tree.Root
}
CommandOption func(*Command) error
)
// ------------------------------------------------------------------------------------------------
// ~ Options
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
// ~ Constructor
// ------------------------------------------------------------------------------------------------
func NewCommand(l log.Logger, op *OnePassword, opts ...CommandOption) (*Command, error) {
inst := &Command{
l: l.Named("onePassword"),
op: op,
}
for _, opt := range opts {
if opt != nil {
if err := opt(inst); err != nil {
return nil, err
}
}
}
inst.commandTree = tree.New(&tree.Node{
Name: "op",
Description: "Execute 1Password commands",
Execute: inst.signin,
Nodes: tree.Nodes{
{
Name: "signin",
Description: "Sign into your account",
Execute: inst.signin,
},
{
Name: "get",
Description: "Retrieve an item",
Args: tree.Args{
{
Name: "id",
Description: "Item name or uuid",
},
},
Execute: inst.get,
},
{
Name: "register",
Description: "Register an account",
Args: tree.Args{
{
Name: "email",
Description: "User email address",
},
},
Execute: inst.register,
},
},
})
return inst, nil
}
// ------------------------------------------------------------------------------------------------
// ~ 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) get(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l,
"op",
"--account", c.op.cfg.Account,
"item", "get", r.Args().At(1),
"--format", "json",
).
Args(r.AdditionalArgs()...).
Run()
}
func (c *Command) register(ctx context.Context, r *readline.Readline) error {
return shell.New(ctx, c.l,
"op", "account", "add",
"--address", c.op.cfg.Account+".1password.eu",
"--email", r.Args().At(1),
).
Args(r.AdditionalArgs()...).
Wait()
}
func (c *Command) signin(ctx context.Context, r *readline.Readline) error {
if ok, _ := c.op.Session(); ok {
c.l.Info("Already signed in")
return nil
} else if err := c.op.SignIn(ctx); err != nil {
return err
}
return nil
}