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

     1  package teams
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/hex"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/keybase/client/go/kbtest"
    10  	"github.com/keybase/client/go/libkb"
    11  	"github.com/keybase/client/go/protocol/keybase1"
    12  	"github.com/stretchr/testify/require"
    13  	"golang.org/x/net/context"
    14  )
    15  
    16  func makeCryptKey(t *testing.T, gen int) keybase1.CryptKey {
    17  	var key [libkb.NaclDHKeysize]byte
    18  	_, err := rand.Read(key[:])
    19  	require.NoError(t, err)
    20  	return keybase1.CryptKey{
    21  		KeyGeneration: gen,
    22  		Key:           key,
    23  	}
    24  }
    25  
    26  func makeTLFID(t *testing.T) keybase1.TLFID {
    27  	b, err := libkb.RandBytesWithSuffix(16, 0x16)
    28  	require.NoError(t, err)
    29  	return keybase1.TLFID(hex.EncodeToString(b))
    30  }
    31  
    32  func TestKBFSUpgradeTeam(t *testing.T) {
    33  	tc := SetupTest(t, "team", 1)
    34  	defer tc.Cleanup()
    35  
    36  	ctx := context.TODO()
    37  	user, err := kbtest.CreateAndSignupFakeUser("team", tc.G)
    38  	require.NoError(t, err)
    39  
    40  	team, _, _, err := LookupOrCreateImplicitTeam(ctx, tc.G, user.Username, false)
    41  	require.NoError(t, err)
    42  	tlfID := makeTLFID(t)
    43  	t.Logf("TLFID: %s", tlfID)
    44  	require.NoError(t, team.AssociateWithTLFID(ctx, tlfID))
    45  	team, err = Load(context.TODO(), tc.G, keybase1.LoadTeamArg{
    46  		ID:          team.ID,
    47  		ForceRepoll: true,
    48  	})
    49  	require.NoError(t, err)
    50  
    51  	checkCryptKeys := func(tlfID keybase1.TLFID, cryptKeys []keybase1.CryptKey,
    52  		appType keybase1.TeamApplication) {
    53  		team, err = Load(context.TODO(), tc.G, keybase1.LoadTeamArg{
    54  			ID:          team.ID,
    55  			ForceRepoll: true,
    56  		})
    57  		require.NoError(t, err)
    58  		resKeys := team.KBFSCryptKeys(ctx, appType)
    59  		require.Len(t, resKeys, len(cryptKeys))
    60  		require.Equal(t, cryptKeys, resKeys)
    61  		require.Equal(t, tlfID, team.LatestKBFSTLFID())
    62  	}
    63  
    64  	chatCryptKeys := []keybase1.CryptKey{
    65  		makeCryptKey(t, 1),
    66  		makeCryptKey(t, 2),
    67  		makeCryptKey(t, 3),
    68  	}
    69  	require.NoError(t, team.AssociateWithTLFKeyset(ctx, tlfID, chatCryptKeys, keybase1.TeamApplication_CHAT))
    70  	checkCryptKeys(tlfID, chatCryptKeys, keybase1.TeamApplication_CHAT)
    71  
    72  	kbfsCryptKeys := chatCryptKeys
    73  	kbfsCryptKeys = append(kbfsCryptKeys, makeCryptKey(t, 4))
    74  	require.NoError(t, team.AssociateWithTLFKeyset(ctx, tlfID, kbfsCryptKeys, keybase1.TeamApplication_KBFS))
    75  	checkCryptKeys(tlfID, kbfsCryptKeys, keybase1.TeamApplication_KBFS)
    76  }
    77  
    78  type testTimer struct {
    79  	waits int
    80  }
    81  
    82  func (t *testTimer) StartupWait(m libkb.MetaContext) (err error) {
    83  	time.Sleep(10 * time.Millisecond)
    84  	return nil
    85  }
    86  
    87  func (t *testTimer) LoopWait(m libkb.MetaContext, _ error) (err error) {
    88  	time.Sleep(10 * time.Millisecond)
    89  	t.waits++
    90  	return nil
    91  }
    92  
    93  type unpinnedTLFAPIFaker struct {
    94  	res *unpinnedTLF
    95  }
    96  
    97  func (u *unpinnedTLFAPIFaker) getUnpinnedTLF(_ libkb.MetaContext) (res *unpinnedTLF, err error) {
    98  	ret := u.res
    99  	u.res = nil
   100  	return ret, nil
   101  }
   102  
   103  func TestTLFPinLoop(t *testing.T) {
   104  
   105  	_, tcs, cleanup := setupNTests(t, 1)
   106  	defer cleanup()
   107  
   108  	t.Logf("U0 creates A")
   109  	rootName, rootID := createTeam2(*tcs[0])
   110  	tlfID := randomTlfID(t)
   111  
   112  	faker := &unpinnedTLFAPIFaker{
   113  		res: &unpinnedTLF{
   114  			Name:   rootName.String(),
   115  			TeamID: rootID,
   116  			TlfID:  tlfID,
   117  		},
   118  	}
   119  	exitCh := make(chan error)
   120  	timer := &testTimer{}
   121  
   122  	pinner := &backgroundTLFPinner{
   123  		timer:          timer,
   124  		getUnpinnedTLF: faker.getUnpinnedTLF,
   125  		exitCh:         exitCh,
   126  	}
   127  
   128  	m := libkb.NewMetaContextForTest(*tcs[0])
   129  
   130  	go func() { _ = pinner.run(m) }()
   131  	err := <-exitCh
   132  	require.NoError(t, err)
   133  	require.Equal(t, timer.waits, 1)
   134  
   135  	team, err := Load(m.Ctx(), tcs[0].G, keybase1.LoadTeamArg{
   136  		ID:          rootID,
   137  		ForceRepoll: true,
   138  	})
   139  	require.NoError(t, err)
   140  	require.Equal(t, team.KBFSTLFIDs(), []keybase1.TLFID{tlfID})
   141  }
   142  
   143  type logoutTimer struct{}
   144  
   145  func (t *logoutTimer) StartupWait(m libkb.MetaContext) (err error) {
   146  	return m.LogoutKillSecrets()
   147  }
   148  
   149  func (t *logoutTimer) LoopWait(m libkb.MetaContext, _ error) (err error) {
   150  	return nil
   151  }
   152  
   153  func TestTLFPinLoopLogout(t *testing.T) {
   154  
   155  	_, tcs, cleanup := setupNTests(t, 1)
   156  	defer cleanup()
   157  
   158  	faker := &unpinnedTLFAPIFaker{}
   159  	exitCh := make(chan error)
   160  	timer := &logoutTimer{}
   161  
   162  	pinner := &backgroundTLFPinner{
   163  		timer:          timer,
   164  		getUnpinnedTLF: faker.getUnpinnedTLF,
   165  		exitCh:         exitCh,
   166  	}
   167  
   168  	m := libkb.NewMetaContextForTest(*tcs[0])
   169  
   170  	go func() { _ = pinner.run(m) }()
   171  	err := <-exitCh
   172  	require.Error(t, err)
   173  	require.IsType(t, libkb.LoginRequiredError{}, err)
   174  }