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  }