github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/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 }