From 832d2cde4d5a93721c291644107b3a89acb7e741 Mon Sep 17 00:00:00 2001 From: Dominik Schulz Date: Mon, 18 Jul 2022 21:55:05 +0200 Subject: [PATCH] Add autosync once a week (#2191) RELEASE_NOTES=[ENHANCEMENT] Automatically sync once a week Signed-off-by: Dominik Schulz --- docs/config.md | 2 ++ internal/action/init.go | 1 + internal/action/process_test.go | 1 + internal/action/sync.go | 43 +++++++++++++++++++++++++++++++++ internal/reminder/reminder.go | 7 +++--- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/config.md b/docs/config.md index 9dd041f02e..aa876c5519 100644 --- a/docs/config.md +++ b/docs/config.md @@ -25,6 +25,8 @@ Some configuration options are only available through setting environment variab | `GOPASS_CLIPBOARD_CLEAR_CMD` | `string` | Use an external command to remove a password from the clipboard. See [GPaste](usecases/gpaste.md) for an example | | `GOPASS_GPG_BINARY` | `string` | Set this to the absolute path to the GPG binary if you need to override the value returned by `gpgconf`, e.g. [QubesOS](https://www.qubes-os.org/doc/split-gpg/). | | `GOPASS_PW_DEFAULT_LENGTH` | `int` | Set to any integer value larger than zero to define a different default length in the `generate` command. By default the length is 24 characters. | +| `GOPASS_AUTOSYNC_INTERVAL` | `int` | Set this to the number of days between autosync runs. | +| `GOPASS_NO_AUTOSYNC` | `bool` | Set this to `true` to disable autosync. | Variables not exclusively used by gopass diff --git a/internal/action/init.go b/internal/action/init.go index ff38c6a515..1720e1d909 100644 --- a/internal/action/init.go +++ b/internal/action/init.go @@ -37,6 +37,7 @@ func (s *Action) IsInitialized(c *cli.Context) error { if inited { debug.Log("Store is fully initialized and ready to go\n\nAll systems go. 🚀\n") s.printReminder(ctx) + _ = s.autoSync(ctx) return nil } diff --git a/internal/action/process_test.go b/internal/action/process_test.go index 6b88cd163b..bad569d806 100644 --- a/internal/action/process_test.go +++ b/internal/action/process_test.go @@ -22,6 +22,7 @@ func TestProcess(t *testing.T) { //nolint:paralleltest ctx := context.Background() ctx = ctxutil.WithAlwaysYes(ctx, true) + ctx = ctxutil.WithInteractive(ctx, false) buf := &bytes.Buffer{} out.Stdout = buf diff --git a/internal/action/sync.go b/internal/action/sync.go index 1304e18bc4..41c6af181a 100644 --- a/internal/action/sync.go +++ b/internal/action/sync.go @@ -4,6 +4,9 @@ import ( "context" "errors" "fmt" + "os" + "strconv" + "time" "github.com/fatih/color" "github.com/gopasspw/gopass/internal/backend" @@ -18,11 +21,51 @@ import ( "github.com/urfave/cli/v2" ) +var autosyncIntervalDays = 3 + +func init() { + sv := os.Getenv("GOPASS_AUTOSYNC_INTERVAL") + if sv == "" { + return + } + + iv, err := strconv.Atoi(sv) + if err != nil { + return + } + + autosyncIntervalDays = iv +} + // Sync all stores with their remotes. func (s *Action) Sync(c *cli.Context) error { return s.sync(ctxutil.WithGlobalFlags(c), c.String("store")) } +func (s *Action) autoSync(ctx context.Context) error { + if !ctxutil.IsInteractive(ctx) { + return nil + } + + if !ctxutil.IsTerminal(ctx) { + return nil + } + + if sv := os.Getenv("GOPASS_NO_AUTOSYNC"); sv != "" { + return nil + } + + ls := s.rem.LastSeen("autosync") + debug.Log("autosync - last seen: %s", ls) + if time.Since(ls) > time.Duration(autosyncIntervalDays)*24*time.Hour { + _ = s.rem.Reset("autosync") + + return s.sync(ctx, "") + } + + return nil +} + func (s *Action) sync(ctx context.Context, store string) error { out.Printf(ctx, "🚥 Syncing with all remotes ...") diff --git a/internal/reminder/reminder.go b/internal/reminder/reminder.go index c419c1a8e1..f3ad02ffc6 100644 --- a/internal/reminder/reminder.go +++ b/internal/reminder/reminder.go @@ -25,7 +25,8 @@ func New() (*Store, error) { }, nil } -func (s *Store) lastSeen(key string) time.Time { +// LastSeen returns the time when the key was last reset. +func (s *Store) LastSeen(key string) time.Time { t := time.Time{} if s == nil { return t @@ -70,11 +71,11 @@ func (s *Store) Overdue(key string) bool { return false } - if time.Since(s.lastSeen("overdue")) < 24*time.Hour { + if time.Since(s.LastSeen("overdue")) < 24*time.Hour { return false } _ = s.Reset("overdue") - return time.Since(s.lastSeen(key)) > 90*24*time.Hour + return time.Since(s.LastSeen(key)) > 90*24*time.Hour }