1// Copyright 2017 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4// PerUserKeyUpkeepBackground runs PerUserKeyUpkeep in the background once in a while. 5// It rolls the per-user-key if the last one was involved in a deprovision. 6// See PerUserKeyUpkeep for more info. 7 8package engine 9 10import ( 11 "sync" 12 "time" 13 14 "github.com/keybase/client/go/libkb" 15) 16 17var PerUserKeyUpkeepBackgroundSettings = BackgroundTaskSettings{ 18 Start: 20 * time.Second, // Wait after starting the app 19 StartStagger: 20 * time.Second, // Wait an additional random amount. 20 WakeUp: 15 * time.Second, // Additional delay after waking from sleep. 21 Interval: 6 * time.Hour, // Wait between checks 22 Limit: 5 * time.Minute, // Time limit on each round 23} 24 25// PerUserKeyUpkeepBackground is an engine. 26type PerUserKeyUpkeepBackground struct { 27 libkb.Contextified 28 sync.Mutex 29 30 args *PerUserKeyUpkeepBackgroundArgs 31 task *BackgroundTask 32} 33 34type PerUserKeyUpkeepBackgroundArgs struct { 35 // Channels used for testing. Normally nil. 36 testingMetaCh chan<- string 37 testingRoundResCh chan<- error 38} 39 40// NewPerUserKeyUpkeepBackground creates a PerUserKeyUpkeepBackground engine. 41func NewPerUserKeyUpkeepBackground(g *libkb.GlobalContext, args *PerUserKeyUpkeepBackgroundArgs) *PerUserKeyUpkeepBackground { 42 task := NewBackgroundTask(g, &BackgroundTaskArgs{ 43 Name: "PerUserKeyUpkeepBackground", 44 F: PerUserKeyUpkeepBackgroundRound, 45 Settings: PerUserKeyUpkeepBackgroundSettings, 46 47 testingMetaCh: args.testingMetaCh, 48 testingRoundResCh: args.testingRoundResCh, 49 }) 50 return &PerUserKeyUpkeepBackground{ 51 Contextified: libkb.NewContextified(g), 52 args: args, 53 // Install the task early so that Shutdown can be called before RunEngine. 54 task: task, 55 } 56} 57 58// Name is the unique engine name. 59func (e *PerUserKeyUpkeepBackground) Name() string { 60 return "PerUserKeyUpkeepBackground" 61} 62 63// GetPrereqs returns the engine prereqs. 64func (e *PerUserKeyUpkeepBackground) Prereqs() Prereqs { 65 return Prereqs{} 66} 67 68// RequiredUIs returns the required UIs. 69func (e *PerUserKeyUpkeepBackground) RequiredUIs() []libkb.UIKind { 70 return []libkb.UIKind{} 71} 72 73// SubConsumers returns the other UI consumers for this engine. 74func (e *PerUserKeyUpkeepBackground) SubConsumers() []libkb.UIConsumer { 75 return []libkb.UIConsumer{&PerUserKeyUpkeep{}} 76} 77 78// Run starts the engine. 79// Returns immediately, kicks off a background goroutine. 80func (e *PerUserKeyUpkeepBackground) Run(m libkb.MetaContext) (err error) { 81 return RunEngine2(m, e.task) 82} 83 84func (e *PerUserKeyUpkeepBackground) Shutdown() { 85 e.task.Shutdown() 86} 87 88func PerUserKeyUpkeepBackgroundRound(m libkb.MetaContext) error { 89 if m.G().ConnectivityMonitor.IsConnected(m.Ctx()) == libkb.ConnectivityMonitorNo { 90 m.Debug("PerUserKeyUpkeepBackgroundRound giving up offline") 91 return nil 92 } 93 94 if !m.G().ActiveDevice.Valid() { 95 m.Debug("PerUserKeyUpkeepBackgroundRound not logged in") 96 return nil 97 } 98 99 if !m.G().LocalSigchainGuard().IsAvailable(m.Ctx(), "PerUserKeyUpkeepBackgroundRound") { 100 m.Debug("PerUserKeyUpkeepBackgroundRound yielding to guard") 101 return nil 102 } 103 104 arg := &PerUserKeyUpkeepArgs{} 105 eng := NewPerUserKeyUpkeep(m.G(), arg) 106 err := RunEngine2(m, eng) 107 return err 108} 109