github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/track.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package engine 5 6 import ( 7 "errors" 8 9 "github.com/keybase/client/go/libkb" 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 ) 12 13 type TrackEngineArg struct { 14 UserAssertion string 15 Me *libkb.User 16 Options keybase1.TrackOptions 17 ForceRemoteCheck bool 18 SigVersion libkb.SigVersion 19 } 20 21 type TrackEngine struct { 22 arg *TrackEngineArg 23 them *libkb.User 24 libkb.Contextified 25 confirmResult keybase1.ConfirmResult 26 } 27 28 // NewTrackEngine creates a default TrackEngine for tracking theirName. 29 func NewTrackEngine(g *libkb.GlobalContext, arg *TrackEngineArg) *TrackEngine { 30 return &TrackEngine{ 31 arg: arg, 32 Contextified: libkb.NewContextified(g), 33 } 34 } 35 36 func (e *TrackEngine) Name() string { 37 return "Follow" 38 } 39 40 func (e *TrackEngine) Prereqs() Prereqs { 41 return Prereqs{ 42 Device: true, 43 } 44 } 45 46 func (e *TrackEngine) RequiredUIs() []libkb.UIKind { 47 return []libkb.UIKind{ 48 libkb.SecretUIKind, 49 libkb.IdentifyUIKind, 50 } 51 } 52 53 func (e *TrackEngine) SubConsumers() []libkb.UIConsumer { 54 return []libkb.UIConsumer{ 55 &ResolveThenIdentify2{}, 56 } 57 } 58 59 func (e *TrackEngine) Run(m libkb.MetaContext) error { 60 m.G().LocalSigchainGuard().Set(m.Ctx(), "TrackEngine") 61 defer m.G().LocalSigchainGuard().Clear(m.Ctx(), "TrackEngine") 62 63 arg := &keybase1.Identify2Arg{ 64 UserAssertion: e.arg.UserAssertion, 65 ForceRemoteCheck: e.arg.ForceRemoteCheck, 66 NeedProofSet: true, 67 NoErrorOnTrackFailure: true, 68 AlwaysBlock: true, 69 } 70 71 if m.UIs().SessionID != 0 { 72 arg.IdentifyBehavior = keybase1.TLFIdentifyBehavior_GUI 73 } else { 74 arg.IdentifyBehavior = keybase1.TLFIdentifyBehavior_CLI 75 } 76 77 ieng := NewResolveThenIdentify2WithTrack(m.G(), arg, e.arg.Options) 78 if err := RunEngine2(m, ieng); err != nil { 79 return err 80 } 81 82 res, err := ieng.Result(m) 83 if err != nil { 84 return err 85 } 86 upk := res.Upk 87 88 if _, uid, _ := libkb.BootstrapActiveDeviceWithMetaContext(m); uid.Equal(upk.GetUID()) { 89 return errors.New("You can't follow yourself.") 90 } 91 92 loadarg := libkb.NewLoadUserArgWithMetaContext(m).WithUID(upk.GetUID()).WithPublicKeyOptional() 93 e.them, err = libkb.LoadUser(loadarg) 94 if err != nil { 95 return err 96 } 97 98 e.confirmResult = ieng.ConfirmResult() 99 if !e.confirmResult.IdentityConfirmed { 100 m.Debug("confirmResult: %+v", e.confirmResult) 101 return errors.New("Follow not confirmed") 102 } 103 104 // if they didn't specify local only on the command line, then if they answer no to posting 105 // the tracking statement publicly to keybase, change LocalOnly to true here: 106 if !e.arg.Options.LocalOnly && !e.confirmResult.RemoteConfirmed { 107 e.arg.Options.LocalOnly = true 108 } 109 110 if !e.arg.Options.ExpiringLocal && e.confirmResult.ExpiringLocal { 111 m.Debug("-ExpiringLocal-") 112 e.arg.Options.ExpiringLocal = true 113 } 114 115 targ := &TrackTokenArg{ 116 Token: ieng.TrackToken(), 117 Me: e.arg.Me, 118 Options: e.arg.Options, 119 } 120 teng := NewTrackToken(m.G(), targ) 121 return RunEngine2(m, teng) 122 } 123 124 func (e *TrackEngine) User() *libkb.User { 125 return e.them 126 } 127 128 func (e *TrackEngine) ConfirmResult() keybase1.ConfirmResult { 129 return e.confirmResult 130 }