github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/deprovision.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  	"github.com/keybase/client/go/libkb"
     8  )
     9  
    10  // XXX: THIS ENGINE DELETES SECRET KEYS. Deleting the wrong secret keys can
    11  // make you lose all your data forever. Apart from `keybase deprovision`, which
    12  // shows a ton of SCARY ALL CAPS prompts to the user, we probably never want to
    13  // use this engine.
    14  type DeprovisionEngine struct {
    15  	libkb.Contextified
    16  	username      libkb.NormalizedUsername
    17  	doRevoke      bool // requires being logged in already
    18  	logoutOptions libkb.LogoutOptions
    19  }
    20  
    21  func NewDeprovisionEngine(g *libkb.GlobalContext, username string, doRevoke bool, logoutOptions libkb.LogoutOptions) *DeprovisionEngine {
    22  	return &DeprovisionEngine{
    23  		Contextified:  libkb.NewContextified(g),
    24  		username:      libkb.NewNormalizedUsername(username),
    25  		doRevoke:      doRevoke,
    26  		logoutOptions: logoutOptions,
    27  	}
    28  }
    29  
    30  func (e *DeprovisionEngine) Name() string {
    31  	return "Deprovision"
    32  }
    33  
    34  func (e *DeprovisionEngine) Prereqs() Prereqs {
    35  	return Prereqs{}
    36  }
    37  
    38  func (e *DeprovisionEngine) RequiredUIs() []libkb.UIKind {
    39  	return []libkb.UIKind{}
    40  }
    41  
    42  func (e *DeprovisionEngine) SubConsumers() []libkb.UIConsumer {
    43  	return []libkb.UIConsumer{
    44  		&RevokeEngine{},
    45  	}
    46  }
    47  
    48  // This function anticipates some error cases (particularly that the device may
    49  // be already revoked), but it will still return an error if something
    50  // unexpected goes wrong.
    51  func (e *DeprovisionEngine) attemptLoggedInRevoke(m libkb.MetaContext) error {
    52  	m.G().LocalSigchainGuard().Set(m.Ctx(), "DeprovisionEngine")
    53  	defer m.G().LocalSigchainGuard().Clear(m.Ctx(), "DeprovisionEngine")
    54  
    55  	me, err := libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m))
    56  	if err != nil {
    57  		m.Debug("DeprovisionEngine error loading current user: %s", err)
    58  		return err
    59  	}
    60  	nun := me.GetNormalizedName()
    61  
    62  	keys, err := me.GetComputedKeyFamily().GetAllActiveKeysForDevice(m.G().Env.GetDeviceIDForUsername(nun))
    63  	if err != nil {
    64  		e.G().Log.Debug("DeprovisionEngine error loading keys for current device: %s", err)
    65  		return err
    66  	}
    67  
    68  	// If there are no keys to revoke, it's likely the device has already been
    69  	// revoked. We still need to log out below though.
    70  	if len(keys) == 0 {
    71  		m.UIs().LogUI.Warning("No active keys to revoke.")
    72  	} else {
    73  		// Do the revoke. We expect this to succeed.
    74  		revokeArg := RevokeDeviceEngineArgs{
    75  			ID:        m.G().Env.GetDeviceIDForUsername(nun),
    76  			ForceSelf: true,
    77  			ForceLast: true,
    78  		}
    79  		revokeEng := NewRevokeDeviceEngine(m.G(), revokeArg)
    80  		if err = revokeEng.Run(m); err != nil {
    81  			m.Debug("DeprovisionEngine error during revoke: %s", err)
    82  			return err
    83  		}
    84  	}
    85  
    86  	m.UIs().LogUI.Info("Logging out...")
    87  	if err = m.LogoutWithOptions(e.logoutOptions); err != nil {
    88  		m.Debug("DeprovisionEngine error during logout: %s", err)
    89  		return err
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  func (e *DeprovisionEngine) Run(m libkb.MetaContext) (err error) {
    96  	// Deprovision steps
    97  	// =================
    98  	// 1. If the user is logged in:
    99  	//   a) Revoke all the current device's keys.
   100  	//   b) Log out.
   101  	// 2. Delete all the user's secret keys!!!
   102  	// 3. Delete the user's ephemeralKeys
   103  	// 4. Delete the user from the config file.
   104  	// 5. Db nuke.
   105  
   106  	if e.doRevoke {
   107  		if err = e.attemptLoggedInRevoke(m); err != nil {
   108  			return err
   109  		}
   110  	}
   111  
   112  	if err = libkb.ClearSecretsOnDeprovision(m, e.username); err != nil {
   113  		m.Debug("DeprovisionEngine error during clear secrets: %s", err)
   114  	}
   115  	return nil
   116  }