github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/chat/upgrade_test.go (about)

     1  package chat
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/keybase/client/go/chat/globals"
     9  	"github.com/keybase/client/go/chat/types"
    10  	"github.com/keybase/client/go/chat/utils"
    11  	"github.com/keybase/client/go/kbtest"
    12  	"github.com/keybase/client/go/libkb"
    13  	"github.com/keybase/client/go/protocol/chat1"
    14  	"github.com/keybase/client/go/protocol/gregor1"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  	"github.com/keybase/client/go/teams"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func makeTLFID() chat1.TLFID {
    21  	suffix := byte(0x29)
    22  	idBytes, err := libkb.RandBytesWithSuffix(16, suffix)
    23  	if err != nil {
    24  		panic("RandBytes failed: " + err.Error())
    25  	}
    26  	return chat1.TLFID(idBytes)
    27  }
    28  
    29  func TestChatKBFSUpgradeMixed(t *testing.T) {
    30  	ctc := makeChatTestContext(t, "TestChatKBFSUpgradeMixed", 1)
    31  	defer ctc.cleanup()
    32  	u := ctc.users()[0]
    33  
    34  	tc := ctc.world.Tcs[u.Username]
    35  	uid := u.User.GetUID().ToBytes()
    36  	tlf := kbtest.NewTlfMock(ctc.world)
    37  	ctx := newTestContextWithTlfMock(tc, tlf)
    38  	ri := ctc.as(t, u).ri
    39  
    40  	info := mustCreateConversationForTest(t, ctc, u, chat1.TopicType_CHAT, chat1.ConversationMembersType_KBFS)
    41  	cres, err := tlf.CryptKeys(ctx, u.Username)
    42  	require.NoError(t, err)
    43  	tlfID := cres.NameIDBreaks.TlfID
    44  	t.Logf("TLFID: %s", tlfID)
    45  	require.Equal(t, info.Triple.Tlfid, chat1.TLFID(tlfID.ToBytes()))
    46  	conv, err := utils.GetVerifiedConv(context.TODO(), tc.Context(), uid, info.Id,
    47  		types.InboxSourceDataSourceAll)
    48  	require.NoError(t, err)
    49  
    50  	header := chat1.MessageClientHeader{
    51  		TlfPublic:   false,
    52  		TlfName:     u.Username,
    53  		MessageType: chat1.MessageType_TEXT,
    54  	}
    55  	kbfsPlain := textMsgWithHeader(t, "kbfs", header)
    56  
    57  	boxer := NewBoxer(tc.Context())
    58  	sender := NewBlockingSender(tc.Context(), boxer, func() chat1.RemoteInterface { return ri })
    59  	prepareRes, err := sender.Prepare(ctx, kbfsPlain, chat1.ConversationMembersType_KBFS, &conv, nil)
    60  	require.NoError(t, err)
    61  	kbfsBoxed := prepareRes.Boxed
    62  	kbfsBoxed.ServerHeader = &chat1.MessageServerHeader{
    63  		Ctime:     gregor1.ToTime(time.Now()),
    64  		MessageID: 2,
    65  	}
    66  
    67  	require.NoError(t, teams.UpgradeTLFIDToImpteam(ctx, tc.G, u.Username, tlfID, false,
    68  		keybase1.TeamApplication_CHAT, cres.CryptKeys))
    69  
    70  	conv.Info.MembersType = chat1.ConversationMembersType_IMPTEAMUPGRADE
    71  	ctx = globals.CtxAddOverrideNameInfoSource(ctx, nil)
    72  	header = chat1.MessageClientHeader{
    73  		TlfPublic:   false,
    74  		TlfName:     u.Username,
    75  		MessageType: chat1.MessageType_TEXT,
    76  	}
    77  	teamPlain := textMsgWithHeader(t, "team", header)
    78  	prepareRes, err = sender.Prepare(ctx, teamPlain,
    79  		chat1.ConversationMembersType_IMPTEAMUPGRADE, &conv, nil)
    80  	require.NoError(t, err)
    81  	teamBoxed := prepareRes.Boxed
    82  	teamBoxed.ServerHeader = &chat1.MessageServerHeader{
    83  		Ctime:     gregor1.ToTime(time.Now()),
    84  		MessageID: 3,
    85  	}
    86  
    87  	checkUnbox := func() {
    88  		unboxed, err := boxer.UnboxMessages(ctx, []chat1.MessageBoxed{teamBoxed, kbfsBoxed}, conv)
    89  		require.NoError(t, err)
    90  		require.Len(t, unboxed, 2)
    91  		for _, u := range unboxed {
    92  			require.True(t, u.IsValid())
    93  			require.NotNil(t, u.Valid().ClientHeader.KbfsCryptKeysUsed)
    94  			if u.GetMessageID() == kbfsBoxed.GetMessageID() {
    95  				require.True(t, *u.Valid().ClientHeader.KbfsCryptKeysUsed)
    96  				require.Equal(t, "kbfs", u.Valid().MessageBody.Text().Body)
    97  			} else {
    98  				require.False(t, *u.Valid().ClientHeader.KbfsCryptKeysUsed)
    99  				require.Equal(t, "team", u.Valid().MessageBody.Text().Body)
   100  			}
   101  		}
   102  	}
   103  	checkUnbox()
   104  
   105  	// Associate a new TLF ID with the team and make sure we can still use the chat
   106  	rogueTLFID := keybase1.TLFID(makeTLFID().String())
   107  	t.Logf("rogue: %s", rogueTLFID)
   108  	iteam, _, _, err := teams.LookupOrCreateImplicitTeam(context.TODO(), tc.G, u.Username, false)
   109  	t.Logf("TEAMID: %s", iteam.ID)
   110  	require.NoError(t, err)
   111  	require.NoError(t, iteam.AssociateWithTLFID(context.TODO(), rogueTLFID))
   112  	tlfIDToTeamID.storage.Purge()
   113  	iteam, err = teams.Load(context.TODO(), tc.G, keybase1.LoadTeamArg{
   114  		ID:              iteam.ID,
   115  		ForceFullReload: true,
   116  	})
   117  	require.NoError(t, err)
   118  	require.Equal(t, 2, len(iteam.KBFSTLFIDs()))
   119  	globals.CtxKeyFinder(ctx, tc.Context()).Reset()
   120  	checkUnbox()
   121  }
   122  
   123  func TestChatKBFSUpgradeBadteam(t *testing.T) {
   124  	ctc := makeChatTestContext(t, "TestLoadTeamImpteamUpgradeSafety", 2)
   125  	defer ctc.cleanup()
   126  	users := ctc.users()
   127  
   128  	tc0 := ctc.world.Tcs[users[0].Username]
   129  	tc1 := ctc.world.Tcs[users[1].Username]
   130  	useRemoteMock = true
   131  	conv := mustCreateConversationForTest(t, ctc, users[0], chat1.TopicType_CHAT,
   132  		chat1.ConversationMembersType_KBFS)
   133  	delete(ctc.userContextCache, users[0].Username)
   134  	useRemoteMock = false
   135  	listener0 := newServerChatListener()
   136  	ctc.as(t, users[0]).h.G().NotifyRouter.AddListener(listener0)
   137  
   138  	iteam, _, _, err := teams.LookupOrCreateImplicitTeam(context.TODO(), tc1.Context().ExternalG(),
   139  		users[0].Username+","+users[1].Username, false)
   140  	require.NoError(t, err)
   141  
   142  	tlfID := keybase1.TLFID(conv.Triple.Tlfid.String())
   143  	require.NoError(t, iteam.AssociateWithTLFID(context.TODO(), tlfID))
   144  	team, err := teams.Load(context.TODO(), tc1.Context().ExternalG(), keybase1.LoadTeamArg{
   145  		ID:          iteam.ID,
   146  		ForceRepoll: true,
   147  	})
   148  	require.NoError(t, err)
   149  	require.NoError(t, team.AssociateWithTLFKeyset(context.TODO(), tlfID, []keybase1.CryptKey{
   150  		{},
   151  	}, keybase1.TeamApplication_CHAT))
   152  
   153  	// Should fail because the name of the imp team doesn't match the conversation name
   154  	loader := NewTeamLoader(tc0.Context().ExternalG())
   155  	_, err = loader.loadTeam(context.TODO(), chat1.TLFID(tlfID.ToBytes()), conv.TlfName,
   156  		chat1.ConversationMembersType_IMPTEAMUPGRADE, false, nil)
   157  	require.Error(t, err)
   158  	require.IsType(t, ImpteamBadteamError{}, err)
   159  }