github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/id_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 "reflect" 8 "sync" 9 "testing" 10 "time" 11 12 "github.com/keybase/client/go/libkb" 13 keybase1 "github.com/keybase/client/go/protocol/keybase1" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func runIdentify(tc *libkb.TestContext, username string) (idUI *FakeIdentifyUI, res *keybase1.Identify2ResUPK2, err error) { 18 idUI = &FakeIdentifyUI{} 19 arg := keybase1.Identify2Arg{ 20 UserAssertion: username, 21 AlwaysBlock: true, 22 IdentifyBehavior: keybase1.TLFIdentifyBehavior_CLI, 23 } 24 25 uis := libkb.UIs{ 26 LogUI: tc.G.UI.GetLogUI(), 27 IdentifyUI: idUI, 28 } 29 30 eng := NewResolveThenIdentify2(tc.G, &arg) 31 m := NewMetaContextForTest(*tc).WithUIs(uis) 32 err = RunEngine2(m, eng) 33 if err != nil { 34 return idUI, nil, err 35 } 36 res, err = eng.Result(m) 37 if err != nil { 38 return idUI, nil, err 39 } 40 return idUI, res, nil 41 } 42 43 func checkAliceProofs(tb libkb.TestingTB, idUI *FakeIdentifyUI, user *keybase1.UserPlusKeysV2) { 44 checkKeyedProfile(tb, idUI, user, "alice", map[string]string{ 45 "github": "kbtester2", 46 "twitter": "tacovontaco", 47 }) 48 } 49 50 func checkBobProofs(tb libkb.TestingTB, idUI *FakeIdentifyUI, user *keybase1.UserPlusKeysV2) { 51 checkKeyedProfile(tb, idUI, user, "bob", map[string]string{ 52 "github": "kbtester1", 53 "twitter": "kbtester1", 54 }) 55 } 56 57 func checkCharlieProofs(tb libkb.TestingTB, idUI *FakeIdentifyUI, user *keybase1.UserPlusKeysV2) { 58 checkKeyedProfile(tb, idUI, user, "charlie", map[string]string{ 59 "github": "tacoplusplus", 60 "twitter": "tacovontaco", 61 }) 62 } 63 64 func checkDougProofs(tb libkb.TestingTB, idUI *FakeIdentifyUI, user *keybase1.UserPlusKeysV2) { 65 checkKeyedProfile(tb, idUI, user, "doug", nil) 66 } 67 68 func checkKeyedProfile(tb libkb.TestingTB, idUI *FakeIdentifyUI, them *keybase1.UserPlusKeysV2, name string, expectedProofs map[string]string) { 69 if them == nil { 70 tb.Fatal("nil 'them' user") 71 } else { 72 exported := &keybase1.User{ 73 Uid: them.GetUID(), 74 Username: them.GetName(), 75 } 76 if !reflect.DeepEqual(idUI.User, exported) { 77 tb.Fatal("LaunchNetworkChecks User not equal to result user.", idUI.User, exported) 78 } 79 } 80 81 if !reflect.DeepEqual(expectedProofs, idUI.Proofs) { 82 tb.Fatal("Wrong proofs.", expectedProofs, idUI.Proofs) 83 } 84 } 85 86 func checkDisplayKeys(t *testing.T, idUI *FakeIdentifyUI, callCount, keyCount int) { 87 if idUI.DisplayKeyCalls != callCount { 88 t.Errorf("DisplayKey calls: %d. expected %d.", idUI.DisplayKeyCalls, callCount) 89 } 90 91 if len(idUI.Keys) != keyCount { 92 t.Errorf("keys: %d, expected %d.", len(idUI.Keys), keyCount) 93 for k, v := range idUI.Keys { 94 t.Logf("key: %+v, %+v", k, v) 95 } 96 } 97 } 98 99 func TestIdAlice(t *testing.T) { 100 tc := SetupEngineTest(t, "id") 101 defer tc.Cleanup() 102 idUI, result, err := runIdentify(&tc, "t_alice") 103 require.NoError(t, err) 104 checkAliceProofs(t, idUI, &result.Upk.Current) 105 checkDisplayKeys(t, idUI, 1, 1) 106 } 107 108 func TestIdBob(t *testing.T) { 109 tc := SetupEngineTest(t, "id") 110 defer tc.Cleanup() 111 idUI, result, err := runIdentify(&tc, "t_bob") 112 require.NoError(t, err) 113 checkBobProofs(t, idUI, &result.Upk.Current) 114 checkDisplayKeys(t, idUI, 1, 1) 115 } 116 117 func TestIdCharlie(t *testing.T) { 118 tc := SetupEngineTest(t, "id") 119 defer tc.Cleanup() 120 idUI, result, err := runIdentify(&tc, "t_charlie") 121 require.NoError(t, err) 122 checkCharlieProofs(t, idUI, &result.Upk.Current) 123 checkDisplayKeys(t, idUI, 1, 1) 124 } 125 126 func TestIdDoug(t *testing.T) { 127 tc := SetupEngineTest(t, "id") 128 defer tc.Cleanup() 129 idUI, result, err := runIdentify(&tc, "t_doug") 130 require.NoError(t, err) 131 checkDougProofs(t, idUI, &result.Upk.Current) 132 checkDisplayKeys(t, idUI, 1, 1) 133 } 134 135 func TestIdEllen(t *testing.T) { 136 tc := SetupEngineTest(t, "id") 137 defer tc.Cleanup() 138 idUI, _, err := runIdentify(&tc, "t_ellen") 139 require.NoError(t, err) 140 checkDisplayKeys(t, idUI, 0, 0) 141 } 142 143 // TestIdPGPNotEldest creates a user with a pgp key that isn't 144 // eldest key, then runs identify to make sure the pgp key is 145 // still displayed. 146 func TestIdPGPNotEldest(t *testing.T) { 147 tc := SetupEngineTest(t, "id") 148 defer tc.Cleanup() 149 150 // create new user, then add pgp key 151 u := CreateAndSignupFakeUser(tc, "login") 152 uis := libkb.UIs{LogUI: tc.G.UI.GetLogUI(), SecretUI: u.NewSecretUI()} 153 _, _, key := genPGPKeyAndArmor(t, tc, u.Email) 154 eng, err := NewPGPKeyImportEngineFromBytes(tc.G, []byte(key), true) 155 require.NoError(t, err) 156 157 m := NewMetaContextForTest(tc).WithUIs(uis) 158 err = RunEngine2(m, eng) 159 require.NoError(t, err) 160 161 Logout(tc) 162 163 idUI, _, err := runIdentify(&tc, u.Username) 164 require.NoError(t, err) 165 166 checkDisplayKeys(t, idUI, 1, 1) 167 } 168 169 func TestIdGenericSocialProof(t *testing.T) { 170 tc := SetupEngineTest(t, "id") 171 defer tc.Cleanup() 172 173 // create new user and have them prove a gubble.social account 174 fu := CreateAndSignupFakeUser(tc, "login") 175 proveGubbleSocial(tc, fu, libkb.KeybaseSignatureV2) 176 proveGubbleCloud(tc, fu, libkb.KeybaseSignatureV2) 177 Logout(tc) 178 179 fu2 := CreateAndSignupFakeUser(tc, "login") 180 fu2.LoginOrBust(tc) 181 182 idUI, result, err := runIdentify(&tc, fu.Username) 183 require.NoError(t, err) 184 185 expectedResult := keybase1.ProofResult{ 186 State: keybase1.ProofState_OK, 187 Status: keybase1.ProofStatus_OK, 188 Desc: "", 189 } 190 191 require.Equal(t, expectedResult, idUI.ProofResults["gubble.social"].ProofResult) 192 require.Equal(t, expectedResult, idUI.ProofResults["gubble.cloud"].ProofResult) 193 194 checkKeyedProfile(t, idUI, &result.Upk.Current, fu.Username, map[string]string{ 195 "gubble.social": fu.Username, 196 "gubble.cloud": fu.Username, 197 }) 198 } 199 200 type FakeIdentifyUI struct { 201 Proofs map[string]string 202 ProofResults map[string]keybase1.LinkCheckResult 203 User *keybase1.User 204 Keys map[libkb.PGPFingerprint]*keybase1.TrackDiff 205 DisplayKeyCalls int 206 DisplayKeyDiffs []*keybase1.TrackDiff 207 Outcome *keybase1.IdentifyOutcome 208 StartCount int 209 Token keybase1.TrackToken 210 BrokenTracking bool 211 DisplayTLFArg keybase1.DisplayTLFCreateWithInviteArg 212 DisplayTLFCount int 213 FakeConfirm bool 214 LastTrack *keybase1.TrackSummary 215 sync.Mutex 216 } 217 218 func (ui *FakeIdentifyUI) FinishWebProofCheck(_ libkb.MetaContext, proof keybase1.RemoteProof, result keybase1.LinkCheckResult) error { 219 ui.Lock() 220 defer ui.Unlock() 221 if ui.Proofs == nil { 222 ui.Proofs = make(map[string]string) 223 } 224 ui.Proofs[proof.Key] = proof.Value 225 226 if ui.ProofResults == nil { 227 ui.ProofResults = make(map[string]keybase1.LinkCheckResult) 228 } 229 ui.ProofResults[proof.Key] = result 230 if result.BreaksTracking { 231 ui.BrokenTracking = true 232 } 233 return nil 234 } 235 236 func (ui *FakeIdentifyUI) FinishSocialProofCheck(_ libkb.MetaContext, proof keybase1.RemoteProof, result keybase1.LinkCheckResult) error { 237 ui.Lock() 238 defer ui.Unlock() 239 if ui.Proofs == nil { 240 ui.Proofs = make(map[string]string) 241 } 242 ui.Proofs[proof.Key] = proof.Value 243 if ui.ProofResults == nil { 244 ui.ProofResults = make(map[string]keybase1.LinkCheckResult) 245 } 246 ui.ProofResults[proof.Key] = result 247 if result.BreaksTracking { 248 ui.BrokenTracking = true 249 } 250 return nil 251 } 252 253 func (ui *FakeIdentifyUI) Confirm(_ libkb.MetaContext, outcome *keybase1.IdentifyOutcome) (result keybase1.ConfirmResult, err error) { 254 ui.Lock() 255 defer ui.Unlock() 256 257 // Do a short sleep. This helps trigger bugs when other code is racing 258 // against the UI here. (Note from Jack: In the bug I initially added this 259 // for, 10ms was just enough to trigger it. I'm adding in an extra factor 260 // of 10.) 261 time.Sleep(100 * time.Millisecond) 262 263 ui.Outcome = outcome 264 bypass := ui.FakeConfirm || outcome.TrackOptions.BypassConfirm 265 result.IdentityConfirmed = bypass 266 result.RemoteConfirmed = bypass && !outcome.TrackOptions.ExpiringLocal 267 return 268 } 269 270 func (ui *FakeIdentifyUI) DisplayCryptocurrency(libkb.MetaContext, keybase1.Cryptocurrency) error { 271 return nil 272 } 273 274 func (ui *FakeIdentifyUI) DisplayStellarAccount(libkb.MetaContext, keybase1.StellarAccount) error { 275 return nil 276 } 277 278 func (ui *FakeIdentifyUI) DisplayKey(_ libkb.MetaContext, ik keybase1.IdentifyKey) error { 279 ui.Lock() 280 defer ui.Unlock() 281 if ui.Keys == nil { 282 ui.Keys = make(map[libkb.PGPFingerprint]*keybase1.TrackDiff) 283 } 284 285 fp := libkb.ImportPGPFingerprintSlice(ik.PGPFingerprint) 286 if fp != nil { 287 ui.Keys[*fp] = ik.TrackDiff 288 } 289 290 if ik.TrackDiff != nil { 291 ui.DisplayKeyDiffs = append(ui.DisplayKeyDiffs, ik.TrackDiff) 292 } 293 294 ui.DisplayKeyCalls++ 295 return nil 296 } 297 func (ui *FakeIdentifyUI) ReportLastTrack(_ libkb.MetaContext, summary *keybase1.TrackSummary) error { 298 ui.LastTrack = summary 299 return nil 300 } 301 302 func (ui *FakeIdentifyUI) Start(_ libkb.MetaContext, username string, _ keybase1.IdentifyReason, _ bool) error { 303 ui.Lock() 304 defer ui.Unlock() 305 ui.StartCount++ 306 return nil 307 } 308 309 func (ui *FakeIdentifyUI) Cancel(libkb.MetaContext) error { 310 return nil 311 } 312 313 func (ui *FakeIdentifyUI) Finish(libkb.MetaContext) error { 314 return nil 315 } 316 317 func (ui *FakeIdentifyUI) Dismiss(_ libkb.MetaContext, _ string, _ keybase1.DismissReason) error { 318 return nil 319 } 320 321 func (ui *FakeIdentifyUI) LaunchNetworkChecks(_ libkb.MetaContext, id *keybase1.Identity, user *keybase1.User) error { 322 ui.Lock() 323 defer ui.Unlock() 324 ui.User = user 325 return nil 326 } 327 328 func (ui *FakeIdentifyUI) DisplayTrackStatement(libkb.MetaContext, string) error { 329 return nil 330 } 331 332 func (ui *FakeIdentifyUI) DisplayUserCard(libkb.MetaContext, keybase1.UserCard) error { 333 return nil 334 } 335 336 func (ui *FakeIdentifyUI) ReportTrackToken(_ libkb.MetaContext, tok keybase1.TrackToken) error { 337 ui.Token = tok 338 return nil 339 } 340 341 func (ui *FakeIdentifyUI) SetStrict(b bool) { 342 } 343 344 func (ui *FakeIdentifyUI) DisplayTLFCreateWithInvite(_ libkb.MetaContext, arg keybase1.DisplayTLFCreateWithInviteArg) error { 345 ui.DisplayTLFCount++ 346 ui.DisplayTLFArg = arg 347 return nil 348 }