github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/pgp_pull_test.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package engine 5 6 import ( 7 "testing" 8 9 "github.com/keybase/client/go/libkb" 10 "github.com/stretchr/testify/require" 11 "golang.org/x/net/context" 12 ) 13 14 const aliceFp string = "2373fd089f28f328916b88f99c7927c0bdfdadf9" 15 const bobFp string = "91fe9b24ef6706b1f7898f2059a2a43f8b731f29" 16 17 func createUserWhoTracks(tc libkb.TestContext, trackedUsers []string, sigVersion libkb.SigVersion) *FakeUser { 18 fu := CreateAndSignupFakeUser(tc, "pull") 19 fu.LoginOrBust(tc) 20 21 for _, trackedUser := range trackedUsers { 22 _, _, err := runTrack(tc, fu, trackedUser, sigVersion) 23 require.NoError(tc.T, err, "error while tracking") 24 } 25 return fu 26 } 27 28 func untrackUserList(tc libkb.TestContext, fu *FakeUser, trackedUsers []string, sigVersion libkb.SigVersion) { 29 for _, trackedUser := range trackedUsers { 30 err := runUntrack(tc, fu, trackedUser, sigVersion) 31 require.NoError(tc.T, err, "error while untracking %s", trackedUser) 32 } 33 } 34 35 func createGpgClient(tc libkb.TestContext) *libkb.GpgCLI { 36 gpgClient := libkb.NewGpgCLI(tc.G, tc.G.UI.GetLogUI()) 37 err := gpgClient.Configure(tc.MetaContext()) 38 require.NoError(tc.T, err, "Error while configuring gpg client.") 39 return gpgClient 40 } 41 42 func assertKeysPresent(t *testing.T, gpgClient *libkb.GpgCLI, fingerprints []string) { 43 for _, fingerprint := range fingerprints { 44 fpObj, err := gpgClient.ImportKey(gpgClient.MetaContext(context.Background()), false /*secret*/, *libkb.PGPFingerprintFromHexNoError(fingerprint), "") 45 require.NoError(t, err, "Should have fingerprint in keyring: %s", fingerprint) 46 require.Equal(t, fingerprint, fpObj.GetFingerprint().String()) 47 } 48 } 49 50 func assertKeysMissing(t *testing.T, gpgClient *libkb.GpgCLI, fingerprints []string) { 51 for _, fingerprint := range fingerprints { 52 _, err := gpgClient.ImportKey(gpgClient.MetaContext(context.Background()), false /*secret*/, *libkb.PGPFingerprintFromHexNoError(fingerprint), "") 53 require.Error(t, err, "Should not already have fingerprint in keyring: %s", fingerprint) 54 } 55 } 56 57 func runPGPPull(tc libkb.TestContext, arg PGPPullEngineArg) { 58 eng := NewPGPPullEngine(tc.G, &arg) 59 m := NewMetaContextForTestWithLogUI(tc) 60 err := RunEngine2(m, eng) 61 require.NoError(tc.T, err, "Error in PGPPullEngine") 62 } 63 64 func runPGPPullExpectingError(tc libkb.TestContext, arg PGPPullEngineArg) { 65 eng := NewPGPPullEngine(tc.G, &arg) 66 m := NewMetaContextForTestWithLogUI(tc) 67 err := RunEngine2(m, eng) 68 require.Error(tc.T, err, "PGPPullEngine should have failed.") 69 } 70 71 func TestPGPPullAll(t *testing.T) { 72 tc := SetupEngineTest(t, "pgp_pull") 73 defer tc.Cleanup() 74 sigVersion := libkb.GetDefaultSigVersion(tc.G) 75 76 users := []string{"t_alice", "t_bob"} 77 fu := createUserWhoTracks(tc, users, sigVersion) 78 defer untrackUserList(tc, fu, users, sigVersion) 79 gpgClient := createGpgClient(tc) 80 81 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 82 83 runPGPPull(tc, PGPPullEngineArg{}) 84 85 assertKeysPresent(t, gpgClient, []string{aliceFp, bobFp}) 86 } 87 88 func TestPGPPullOne(t *testing.T) { 89 tc := SetupEngineTest(t, "pgp_pull") 90 defer tc.Cleanup() 91 sigVersion := libkb.GetDefaultSigVersion(tc.G) 92 93 users := []string{"t_alice", "t_bob"} 94 fu := createUserWhoTracks(tc, users, sigVersion) 95 defer untrackUserList(tc, fu, users, sigVersion) 96 gpgClient := createGpgClient(tc) 97 98 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 99 100 runPGPPull(tc, PGPPullEngineArg{ 101 // ID'ing the same user twice should be ok. 102 UserAsserts: []string{"t_bob"}, 103 }) 104 105 assertKeysPresent(t, gpgClient, []string{bobFp}) 106 assertKeysMissing(t, gpgClient, []string{aliceFp}) 107 } 108 109 func TestPGPPullBadIDs(t *testing.T) { 110 tc := SetupEngineTest(t, "pgp_pull") 111 defer tc.Cleanup() 112 sigVersion := libkb.GetDefaultSigVersion(tc.G) 113 114 users := []string{"t_alice", "t_bob"} 115 fu := createUserWhoTracks(tc, users, sigVersion) 116 defer untrackUserList(tc, fu, users, sigVersion) 117 gpgClient := createGpgClient(tc) 118 119 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 120 121 runPGPPullExpectingError(tc, PGPPullEngineArg{ 122 // ID'ing invalid user should fail the pull. 123 UserAsserts: []string{"t_bob", "t_NOT_TRACKED_BY_ME"}, 124 }) 125 126 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 127 } 128 129 func TestPGPPullNotTracked(t *testing.T) { 130 tc := SetupEngineTest(t, "pgp_pull") 131 defer tc.Cleanup() 132 sigVersion := libkb.GetDefaultSigVersion(tc.G) 133 134 // Only tracking alice 135 users := []string{"t_alice"} 136 fu := createUserWhoTracks(tc, users, sigVersion) 137 defer untrackUserList(tc, fu, users, sigVersion) 138 gpgClient := createGpgClient(tc) 139 140 // But want to pull bot alice and bob. 141 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 142 143 fui := &FakeIdentifyUI{FakeConfirm: true} 144 uis := libkb.UIs{ 145 LogUI: tc.G.UI.GetLogUI(), 146 GPGUI: &gpgtestui{}, 147 IdentifyUI: fui, 148 } 149 eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{ 150 UserAsserts: []string{"t_bob", "t_alice"}, 151 }) 152 m := NewMetaContextForTest(tc).WithUIs(uis) 153 err := RunEngine2(m, eng) 154 require.NoError(t, err) 155 require.Equal(t, 1, fui.StartCount, "Expected 1 ID UI prompt") 156 157 assertKeysPresent(t, gpgClient, []string{bobFp, aliceFp}) 158 } 159 160 func TestPGPPullNotLoggedIn(t *testing.T) { 161 tc := SetupEngineTest(t, "track") 162 defer tc.Cleanup() 163 164 gpgClient := createGpgClient(tc) 165 166 assertKeysMissing(t, gpgClient, []string{aliceFp, bobFp}) 167 168 fui := &FakeIdentifyUI{FakeConfirm: true} 169 uis := libkb.UIs{ 170 LogUI: tc.G.UI.GetLogUI(), 171 GPGUI: &gpgtestui{}, 172 IdentifyUI: fui, 173 } 174 eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{ 175 UserAsserts: []string{"t_bob", "t_alice"}, 176 }) 177 m := NewMetaContextForTest(tc).WithUIs(uis) 178 err := RunEngine2(m, eng) 179 require.NoError(t, err) 180 require.Equal(t, 2, fui.StartCount, "Expected 2 ID UI prompt") 181 182 assertKeysPresent(t, gpgClient, []string{aliceFp, bobFp}) 183 } 184 185 func TestPGPPullMultiplePrompts(t *testing.T) { 186 tc := SetupEngineTest(t, "pgp_pull") 187 defer tc.Cleanup() 188 sigVersion := libkb.GetDefaultSigVersion(tc.G) 189 createUserWhoTracks(tc, []string{}, sigVersion) 190 191 gpgClient := createGpgClient(tc) 192 assertKeysMissing(t, gpgClient, []string{aliceFp}) 193 194 // Try the first time, declining in prompt. We expect keys not to 195 // be imported. 196 fui := &FakeIdentifyUI{FakeConfirm: false} 197 uis := libkb.UIs{ 198 LogUI: tc.G.UI.GetLogUI(), 199 GPGUI: &gpgtestui{}, 200 IdentifyUI: fui, 201 } 202 203 eng := NewPGPPullEngine(tc.G, &PGPPullEngineArg{ 204 UserAsserts: []string{"t_alice"}, 205 }) 206 m := NewMetaContextForTest(tc).WithUIs(uis) 207 err := RunEngine2(m, eng) 208 require.NoError(t, err) 209 210 require.Equal(t, 1, fui.StartCount, "Expected 1 ID UI prompt") 211 assertKeysMissing(t, gpgClient, []string{aliceFp}) 212 213 // Run again, declining like before, but make sure we got asked 214 // second time and our answer wasn't just cached. 215 err = RunEngine2(m, eng) 216 require.NoError(t, err) 217 218 require.Equal(t, 2, fui.StartCount, "Expected 2 ID UI prompts") 219 assertKeysMissing(t, gpgClient, []string{aliceFp}) 220 221 // Run again, attempt to confirm in prompt. PGP Pull should ask us 222 // again even though we declined before, and successfully import 223 // the keys. 224 fui.FakeConfirm = true 225 err = RunEngine2(m, eng) 226 require.NoError(t, err) 227 228 require.Equal(t, 3, fui.StartCount, "Expected 2 ID UI prompts") 229 assertKeysPresent(t, gpgClient, []string{aliceFp}) 230 }