/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/engine/track_test.go
391 строка
12 KB
chrisnojima-zoom
Version 670 - clean2 (#29122)
08 июн 2026, 19:31
Не верифицирован
08 июн 2026, 19:31
1943197
Код
Авторство
О чём код?
// Copyright 2015 Keybase, Inc. All rights reserved. Use of // this source code is governed by the included BSD license. package engine import ( "context" "testing" "github.com/keybase/client/go/libkb" keybase1 "github.com/keybase/client/go/protocol/keybase1" "github.com/stretchr/testify/require" ) func runTrack(tc libkb.TestContext, fu *FakeUser, username string, sigVersion libkb.SigVersion) (idUI *FakeIdentifyUI, them *libkb.User, err error) { sv := keybase1.SigVersion(sigVersion) return runTrackWithOptions(tc, fu, username, keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, fu.NewSecretUI(), false) } func runTrackWithOptions(tc libkb.TestContext, fu *FakeUser, username string, options keybase1.TrackOptions, secretUI libkb.SecretUI, forceRemoteCheck bool) (idUI *FakeIdentifyUI, them *libkb.User, err error) { idUI = &FakeIdentifyUI{} arg := &TrackEngineArg{ UserAssertion: username, Options: options, ForceRemoteCheck: forceRemoteCheck, } uis := libkb.UIs{ LogUI: tc.G.UI.GetLogUI(), IdentifyUI: idUI, SecretUI: secretUI, } eng := NewTrackEngine(tc.G, arg) m := NewMetaContextForTest(tc).WithUIs(uis) err = RunEngine2(m, eng) them = eng.User() return } func assertTracking(tc libkb.TestContext, username string) { me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) require.NoError(tc.T, err) them, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tc.G, username)) require.NoError(tc.T, err) m := NewMetaContextForTest(tc) s, err := me.TrackChainLinkFor(m, them.GetNormalizedName(), them.GetUID()) require.NoError(tc.T, err) require.NotNil(tc.T, s) } func assertNotTracking(tc libkb.TestContext, username string) { me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) require.NoError(tc.T, err) them, err := libkb.LoadUser(libkb.NewLoadUserByNameArg(tc.G, username)) require.NoError(tc.T, err) m := NewMetaContextForTest(tc) s, err := me.TrackChainLinkFor(m, them.GetNormalizedName(), them.GetUID()) require.NoError(tc.T, err) require.Nil(tc.T, s) } func trackAlice(tc libkb.TestContext, fu *FakeUser, sigVersion libkb.SigVersion) { sv := keybase1.SigVersion(sigVersion) trackAliceWithOptions(tc, fu, keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, fu.NewSecretUI()) } func trackUser(tc libkb.TestContext, fu *FakeUser, un libkb.NormalizedUsername, sigVersion libkb.SigVersion) { sv := keybase1.SigVersion(sigVersion) _, _, err := runTrackWithOptions(tc, fu, un.String(), keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, fu.NewSecretUI(), false) require.NoError(tc.T, err) } func trackUserGetUI(tc libkb.TestContext, fu *FakeUser, un libkb.NormalizedUsername, sigVersion libkb.SigVersion) *FakeIdentifyUI { sv := keybase1.SigVersion(sigVersion) ui, _, err := runTrackWithOptions(tc, fu, un.String(), keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, fu.NewSecretUI(), false) require.NoError(tc.T, err) return ui } func trackAliceWithOptions(tc libkb.TestContext, fu *FakeUser, options keybase1.TrackOptions, secretUI libkb.SecretUI) { idUI, res, err := runTrackWithOptions(tc, fu, "t_alice", options, secretUI, false) require.NoError(tc.T, err) upk, err := res.ExportToUPKV2AllIncarnations() require.NoError(tc.T, err) checkAliceProofs(tc.T, idUI, &upk.Current) assertTracking(tc, "t_alice") } func trackBob(tc libkb.TestContext, fu *FakeUser, sigVersion libkb.SigVersion) { sv := keybase1.SigVersion(sigVersion) trackBobWithOptions(tc, fu, keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, fu.NewSecretUI()) } func trackBobWithOptions(tc libkb.TestContext, fu *FakeUser, options keybase1.TrackOptions, secretUI libkb.SecretUI) { // Refer to t_bob as kbtester1@twitter. This helps test a different // codepath through idenfity2. (For example, in one case it triggered a // race condition that aborted tracking without waiting for the UI to // confirm, which wasn't present in the regular "t_bob" case.) idUI, res, err := runTrackWithOptions(tc, fu, "kbtester1@twitter", options, secretUI, false) require.NoError(tc.T, err) upk, err := res.ExportToUPKV2AllIncarnations() require.NoError(tc.T, err) checkBobProofs(tc.T, idUI, &upk.Current) assertTracking(tc, "t_bob") } func TestTrack(t *testing.T) { doWithSigChainVersions(func(sigVersion libkb.SigVersion) { _testTrack(t, sigVersion) }) } func _testTrack(t *testing.T, sigVersion libkb.SigVersion) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() fu := CreateAndSignupFakeUser(tc, "track") trackAlice(tc, fu, sigVersion) defer untrackAlice(tc, fu, sigVersion) // Assert that we gracefully handle the case of no login Logout(tc) _, _, err := runTrack(tc, fu, "t_bob", sigVersion) require.Error(t, err) _, ok := err.(libkb.DeviceRequiredError) require.True(t, ok) fu.LoginOrBust(tc) trackBob(tc, fu, sigVersion) defer untrackBob(tc, fu, sigVersion) // try tracking a user with no keys (which is now allowed) _, _, err = runTrack(tc, fu, "t_ellen", sigVersion) require.NoError(t, err) } // tests tracking a user that doesn't have a public key (#386) func TestTrackNoPubKey(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) fu := CreateAndSignupFakeUser(tc, "track") Logout(tc) tracker := CreateAndSignupFakeUser(tc, "track") _, _, err := runTrack(tc, tracker, fu.Username, sigVersion) require.NoError(t, err) } func TestTrackMultiple(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) fu := CreateAndSignupFakeUser(tc, "track") trackAlice(tc, fu, sigVersion) defer untrackAlice(tc, fu, sigVersion) trackAlice(tc, fu, sigVersion) } func TestTrackNewUserWithPGP(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) fu := createFakeUserWithPGPSibkey(tc) Logout(tc) tracker := CreateAndSignupFakeUser(tc, "track") t.Logf("first track:") _, _, err := runTrack(tc, tracker, fu.Username, sigVersion) require.NoError(t, err) t.Logf("second track:") _, _, err = runTrack(tc, tracker, fu.Username, sigVersion) require.NoError(t, err) } // see issue #578 func TestTrackRetrack(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) fu := createFakeUserWithPGPSibkey(tc) idUI := &FakeIdentifyUI{} secretUI := fu.NewSecretUI() var err error fu.User, err = libkb.LoadMe(libkb.NewLoadUserPubOptionalArg(tc.G)) require.NoError(t, err) seqnoBefore := fu.User.GetSigChainLastKnownSeqno() sv := keybase1.SigVersion(sigVersion) arg := &TrackEngineArg{ UserAssertion: "t_alice", Options: keybase1.TrackOptions{BypassConfirm: true, SigVersion: &sv}, } uis := libkb.UIs{ LogUI: tc.G.UI.GetLogUI(), IdentifyUI: idUI, SecretUI: secretUI, } eng := NewTrackEngine(tc.G, arg) m := NewMetaContextForTest(tc).WithUIs(uis) err = RunEngine2(m, eng) require.NoError(t, err) fu.User, err = libkb.LoadMe(libkb.NewLoadUserPubOptionalArg(tc.G)) require.NoError(t, err) seqnoAfter := fu.User.GetSigChainLastKnownSeqno() require.NotEqual(t, seqnoAfter, seqnoBefore) eng = NewTrackEngine(tc.G, arg) err = RunEngine2(m, eng) require.NoError(t, err) fu.User, err = libkb.LoadMe(libkb.NewLoadUserPubOptionalArg(tc.G)) require.NoError(t, err) seqnoRetrack := fu.User.GetSigChainLastKnownSeqno() require.False(t, seqnoRetrack > seqnoAfter) } func TestTrackLocal(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() fu := CreateAndSignupFakeUser(tc, "track") _, them, err := runTrackWithOptions(tc, fu, "t_alice", keybase1.TrackOptions{LocalOnly: true, BypassConfirm: true}, fu.NewSecretUI(), false) require.NoError(t, err) require.NotNil(t, them) me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) require.NoError(t, err) m := NewMetaContextForTest(tc) s, err := me.TrackChainLinkFor(m, them.GetNormalizedName(), them.GetUID()) require.NoError(t, err) require.NotNil(t, s) require.False(t, s.IsRemote()) } // Make sure the track engine uses the secret store. func TestTrackWithSecretStore(t *testing.T) { doWithSigChainVersions(func(sigVersion libkb.SigVersion) { _testTrackWithSecretStore(t, sigVersion) }) } func _testTrackWithSecretStore(t *testing.T, sigVersion libkb.SigVersion) { testEngineWithSecretStore(t, func( tc libkb.TestContext, fu *FakeUser, secretUI libkb.SecretUI, ) { trackAliceWithOptions(tc, fu, keybase1.TrackOptions{BypassConfirm: true}, secretUI) untrackAlice(tc, fu, sigVersion) }) } // Test for Core-2196 identify/track race detection func TestIdentifyTrackRaceDetection(t *testing.T) { doWithSigChainVersions(func(sigVersion libkb.SigVersion) { _testIdentifyTrackRaceDetection(t, sigVersion) }) } func _testIdentifyTrackRaceDetection(t *testing.T, sigVersion libkb.SigVersion) { user, dev1, dev2, cleanup := SetupTwoDevices(t, "track") defer cleanup() trackee := "t_tracy" doID := func(tc libkb.TestContext, fui *FakeIdentifyUI) { iarg := &keybase1.Identify2Arg{ UserAssertion: trackee, // We need to block on identification so that the track token // is delivered to the UI before we return. Otherwise, the // following call to track might happen before the token // is known. AlwaysBlock: true, IdentifyBehavior: keybase1.TLFIdentifyBehavior_CLI, } eng := NewResolveThenIdentify2(tc.G, iarg) uis := libkb.UIs{IdentifyUI: fui} m := NewMetaContextForTest(tc).WithUIs(uis) err := RunEngine2(m, eng) require.NoError(t, err) } sv := keybase1.SigVersion(sigVersion) track := func(tc libkb.TestContext, fui *FakeIdentifyUI) error { arg := TrackTokenArg{ Token: fui.Token, Options: keybase1.TrackOptions{ BypassConfirm: true, ForceRetrack: true, SigVersion: &sv, }, } uis := libkb.UIs{ LogUI: tc.G.UI.GetLogUI(), SecretUI: user.NewSecretUI(), } eng := NewTrackToken(tc.G, &arg) m := NewMetaContextForTest(tc).WithUIs(uis) return RunEngine2(m, eng) } trackSucceed := func(tc libkb.TestContext, fui *FakeIdentifyUI) { err := track(tc, fui) require.NoError(tc.T, err) assertTracking(dev1, trackee) } trackFail := func(tc libkb.TestContext, fui *FakeIdentifyUI, firstTrack bool) { err := track(tc, fui) require.Error(tc.T, err) tse, ok := err.(libkb.TrackStaleError) require.True(tc.T, ok) require.Equal(tc.T, tse.FirstTrack, firstTrack) } for i := range 2 { fui1 := &FakeIdentifyUI{} fui2 := &FakeIdentifyUI{} doID(dev1, fui1) if i > 0 { // Device2 won't know that device1 made a change to the ME user // in time to make this test pass. So we hack in an invalidation. // We might have used the fact the userchanged notifications are bounced // off of the server, but that might slow down this test, so do the // simple and non-flakey thing. dev2.G.GetUPAKLoader().Invalidate(context.TODO(), libkb.UsernameToUID(user.Username)) } doID(dev2, fui2) trackSucceed(dev1, fui1) trackFail(dev2, fui2, (i == 0)) } err := runUntrack(dev1, user, trackee, sigVersion) require.NoError(t, err) } func TestTrackNoKeys(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) nk, pp := createFakeUserWithNoKeys(tc) Logout(tc) fu := CreateAndSignupFakeUser(tc, "track") trackUser(tc, fu, libkb.NewNormalizedUsername(nk), sigVersion) // provision nk on a new device Logout(tc) nku := &FakeUser{Username: nk, Passphrase: pp} err := nku.Login(tc.G) require.NoError(t, err) Logout(tc) // track nk again err = fu.Login(tc.G) require.NoError(t, err) ui := trackUserGetUI(tc, fu, libkb.NewNormalizedUsername(nk), sigVersion) // ensure track diff for new eldest key require.Equal(t, 1, len(ui.DisplayKeyDiffs)) require.Equal(t, ui.DisplayKeyDiffs[0].Type, keybase1.TrackDiffType_NEW_ELDEST) } func TestTrackSelf(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() sigVersion := libkb.GetDefaultSigVersion(tc.G) sv := keybase1.SigVersion(sigVersion) fu := CreateAndSignupFakeUser(tc, "track") _, _, err := runTrackWithOptions(tc, fu, fu.NormalizedUsername().String(), keybase1.TrackOptions{ BypassConfirm: true, SigVersion: &sv, }, fu.NewSecretUI(), false) require.Error(t, err) require.Equal(t, "You can't follow yourself.", err.Error()) }