From 75b0b5726d030bdebfe456b1f8d13aecc8b4c2da Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Wed, 20 Dec 2023 16:46:48 +0100 Subject: [PATCH 1/2] feat: handle cli integration --- foomo/squadron/command.go | 2 +- onepassword/checker.go | 2 +- onepassword/command.go | 2 +- onepassword/onepassword.go | 20 +++++++++++++------- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/foomo/squadron/command.go b/foomo/squadron/command.go index 4827a6d..acf29a7 100644 --- a/foomo/squadron/command.go +++ b/foomo/squadron/command.go @@ -352,7 +352,7 @@ func (c *Command) execute(ctx context.Context, r *readline.Readline) error { { // handle 1password if c.op != nil { - if ok, _ := c.op.IsAuthenticated(); !ok { + if ok, _ := c.op.IsAuthenticated(ctx); !ok { c.l.Info("missing 1password session, please login") if err := c.op.SignIn(ctx); err != nil { return err diff --git a/onepassword/checker.go b/onepassword/checker.go index 93a8ad9..043a2cd 100644 --- a/onepassword/checker.go +++ b/onepassword/checker.go @@ -10,7 +10,7 @@ import ( func AuthChecker(p *OnePassword) check.Checker { return func(ctx context.Context, l log.Logger) check.Info { name := "1Password" - if ok, _ := p.IsAuthenticated(); ok { + if ok, _ := p.IsAuthenticated(ctx); ok { return check.NewSuccessInfo(name, "Authenticated") } else { return check.NewFailureInfo(name, "Run `op auth` to sign into 1password") diff --git a/onepassword/command.go b/onepassword/command.go index 2c9e67f..5ea2e72 100644 --- a/onepassword/command.go +++ b/onepassword/command.go @@ -135,7 +135,7 @@ func (c *Command) register(ctx context.Context, r *readline.Readline) error { } func (c *Command) auth(ctx context.Context, r *readline.Readline) error { - if ok, _ := c.op.IsAuthenticated(); ok { + if ok, _ := c.op.IsAuthenticated(ctx); ok { c.l.Info("Already signed in") return nil } else if err := c.op.SignIn(ctx); err != nil { diff --git a/onepassword/onepassword.go b/onepassword/onepassword.go index 4d5360e..a740a03 100644 --- a/onepassword/onepassword.go +++ b/onepassword/onepassword.go @@ -85,9 +85,15 @@ func New(l log.Logger, cache cache.Cache, opts ...Option) (*OnePassword, error) // ~ Public methods // ------------------------------------------------------------------------------------------------ -func (op *OnePassword) IsAuthenticated() (bool, error) { +func (op *OnePassword) IsAuthenticated(ctx context.Context) (bool, error) { var sessChanged bool sess := os.Getenv("OP_SESSION_" + op.cfg.Account) + + // check for enabled cli integration + if _, err := exec.CommandContext(ctx, "op", "account", "get", "--account", op.cfg.Account).CombinedOutput(); err == nil { + return true, nil + } + op.isSignedInLock.Lock() defer op.isSignedInLock.Unlock() @@ -104,7 +110,7 @@ func (op *OnePassword) IsAuthenticated() (bool, error) { } if sessChanged || op.isSignedInTime.IsZero() || time.Since(op.isSignedInTime) > time.Minute*10 { - out, err := exec.Command("op", "account", "--account", op.cfg.Account, "get", "--format", "json").Output() + out, err := exec.CommandContext(ctx, "op", "account", "--account", op.cfg.Account, "get", "--format", "json").Output() if err != nil { return false, fmt.Errorf("%w: %s", err, string(out)) } @@ -127,7 +133,7 @@ func (op *OnePassword) IsAuthenticated() (bool, error) { } func (op *OnePassword) SignIn(ctx context.Context) error { - if ok, _ := op.IsAuthenticated(); ok { + if ok, _ := op.IsAuthenticated(ctx); ok { return nil } @@ -189,7 +195,7 @@ func (op *OnePassword) Get(ctx context.Context, secret Secret) (string, error) { return strings.ReplaceAll(strings.TrimSpace(value), "\\n", "\n"), nil } } else { - if ok, _ := op.IsAuthenticated(); !ok { + if ok, _ := op.IsAuthenticated(ctx); !ok { return "", ErrNotSignedIn } else if fields := op.clientGet(ctx, secret.Vault, secret.Item); len(fields) == 0 { return "", fmt.Errorf("could not find secret '%s' '%s'", secret.Vault, secret.Item) @@ -209,7 +215,7 @@ func (op *OnePassword) GetDocument(ctx context.Context, secret Secret) (string, return value, nil } } else { - if ok, _ := op.IsAuthenticated(); !ok { + if ok, _ := op.IsAuthenticated(ctx); !ok { return "", ErrNotSignedIn } else if value := op.clientGetDoument(ctx, secret.Vault, secret.Item); len(value) == 0 { return "", fmt.Errorf("could not find document '%s' '%s'", secret.Vault, secret.Item) @@ -220,7 +226,7 @@ func (op *OnePassword) GetDocument(ctx context.Context, secret Secret) (string, } func (op *OnePassword) GetOnetimePassword(ctx context.Context, account, uuid string) (string, error) { - if ok, _ := op.IsAuthenticated(); !ok { + if ok, _ := op.IsAuthenticated(ctx); !ok { return "", ErrNotSignedIn } @@ -421,7 +427,7 @@ func (op *OnePassword) watch() { if v, ok := op.watching[op.cfg.Account]; !ok || !v { go func() { for { - if ok, err := op.IsAuthenticated(); err != nil { + if ok, err := op.IsAuthenticated(context.Background()); err != nil { op.l.Warnf("\n1password session keep alive failed for '%s' (%s)", op.cfg.Account, err.Error()) op.watching[op.cfg.Account] = false return From c184bd74340a5e32d28285b426568f51e344b237 Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Wed, 20 Dec 2023 16:50:55 +0100 Subject: [PATCH 2/2] fix: pass context --- onepassword/onepassword.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onepassword/onepassword.go b/onepassword/onepassword.go index a740a03..39afbb7 100644 --- a/onepassword/onepassword.go +++ b/onepassword/onepassword.go @@ -125,7 +125,7 @@ func (op *OnePassword) IsAuthenticated(ctx context.Context) (bool, error) { if data.Name == op.cfg.Account { op.isSignedInTime = time.Now() - op.watch() + op.watch(context.WithoutCancel(ctx)) return true, nil } } @@ -181,7 +181,7 @@ $ export OP_SESSION_%s=%s `, op.cfg.TokenFilename) } } - op.watch() + op.watch(context.WithoutCancel(ctx)) return nil } @@ -423,11 +423,11 @@ func (op *OnePassword) connectGetFileContent(vaultQuery, itemQuery, fileUUID str }).(string) } -func (op *OnePassword) watch() { +func (op *OnePassword) watch(ctx context.Context) { if v, ok := op.watching[op.cfg.Account]; !ok || !v { go func() { for { - if ok, err := op.IsAuthenticated(context.Background()); err != nil { + if ok, err := op.IsAuthenticated(ctx); err != nil { op.l.Warnf("\n1password session keep alive failed for '%s' (%s)", op.cfg.Account, err.Error()) op.watching[op.cfg.Account] = false return