github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/teambot/handler.go (about)

     1  package teambot
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/keybase/client/go/libkb"
     7  	"github.com/keybase/client/go/protocol/keybase1"
     8  	"github.com/keybase/client/go/teams"
     9  )
    10  
    11  // HandleNewTeambotKey checks that the bot's team cache has at least up to the
    12  // generation just created.
    13  func HandleNewTeambotKey(mctx libkb.MetaContext, teamID keybase1.TeamID,
    14  	app keybase1.TeamApplication, generation keybase1.TeambotKeyGeneration) (err error) {
    15  	defer mctx.Trace("HandleNewTeambotKey", &err)()
    16  	defer func() {
    17  		mctx.G().NotifyRouter.HandleNewTeambotKey(mctx.Ctx(), teamID, app, generation)
    18  	}()
    19  
    20  	team, err := teams.Load(mctx.Ctx(), mctx.G(), keybase1.LoadTeamArg{
    21  		ID: teamID,
    22  	})
    23  	if err != nil {
    24  		return err
    25  	}
    26  	if team.Generation() < keybase1.PerTeamKeyGeneration(generation) {
    27  		team, err := teams.Load(mctx.Ctx(), mctx.G(), keybase1.LoadTeamArg{
    28  			ID:          teamID,
    29  			ForceRepoll: true,
    30  		})
    31  		if err != nil {
    32  			return err
    33  		}
    34  		if team.Generation() < keybase1.PerTeamKeyGeneration(generation) {
    35  			return fmt.Errorf("HandleNewTeambotKey: Found max PerTeamGeneration %d vs NewTeambotKey generation %d",
    36  				team.Generation(), generation)
    37  		}
    38  	}
    39  	return nil
    40  }
    41  
    42  // HandleTeambotEKNeeded forces a teambot key to be generated since the bot does
    43  // not have access. All team members are notified and race to publish the
    44  // requested key.
    45  func HandleTeambotKeyNeeded(mctx libkb.MetaContext, teamID keybase1.TeamID, botUID keybase1.UID,
    46  	app keybase1.TeamApplication, generation keybase1.TeambotKeyGeneration) (err error) {
    47  	defer mctx.Trace("HandleTeambotKeyNeeded", &err)()
    48  	defer func() {
    49  		mctx.G().NotifyRouter.HandleTeambotKeyNeeded(mctx.Ctx(), teamID, botUID, app, generation)
    50  	}()
    51  
    52  	keyer := mctx.G().GetTeambotMemberKeyer()
    53  	if keyer == nil {
    54  		return fmt.Errorf("member keyer not found")
    55  	}
    56  
    57  	team, err := teams.Load(mctx.Ctx(), mctx.G(), keybase1.LoadTeamArg{
    58  		ID: teamID,
    59  	})
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	// Clear out our caches so we can force publish a key
    65  	var appKey keybase1.TeamApplicationKey
    66  	if generation == 0 { // Bot needs the latest key
    67  		keyer.PurgeCache(mctx)
    68  		appKey, err = team.ApplicationKey(mctx.Ctx(), app)
    69  		if err != nil {
    70  			return err
    71  		}
    72  	} else { // Bot needs a specific generation
    73  		keyer.PurgeCacheAtGeneration(mctx, teamID, botUID, app, generation)
    74  		appKey, err = team.ApplicationKeyAtGeneration(mctx.Ctx(), app,
    75  			keybase1.PerTeamKeyGeneration(generation))
    76  		if err != nil {
    77  			return err
    78  		}
    79  	}
    80  
    81  	_, _, err = keyer.GetOrCreateTeambotKey(mctx, teamID, botUID.ToBytes(), appKey)
    82  	return err
    83  }