github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/engine/track_proof_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 "fmt" 8 "sort" 9 "testing" 10 11 "github.com/keybase/client/go/libkb" 12 keybase1 "github.com/keybase/client/go/protocol/keybase1" 13 "github.com/stretchr/testify/require" 14 ) 15 16 // testing service block 17 type sb struct { 18 social bool 19 id string 20 proofState keybase1.ProofState 21 } 22 23 func checkTrack(tc libkb.TestContext, fu *FakeUser, username string, blocks []sb, outcome *keybase1.IdentifyOutcome, sigVersion libkb.SigVersion) error { 24 ui, them, err := runTrack(tc, fu, username, sigVersion) 25 if err != nil { 26 return err 27 } 28 return checkTrackCommon(tc, blocks, outcome, them, ui) 29 } 30 31 func checkTrackForce(tc libkb.TestContext, fu *FakeUser, username string, blocks []sb, outcome *keybase1.IdentifyOutcome) error { 32 ui, them, err := runTrackWithOptions(tc, fu, username, keybase1.TrackOptions{BypassConfirm: true}, fu.NewSecretUI(), true) 33 if err != nil { 34 return err 35 } 36 return checkTrackCommon(tc, blocks, outcome, them, ui) 37 } 38 39 func checkTrackCommon(tc libkb.TestContext, blocks []sb, outcome *keybase1.IdentifyOutcome, them *libkb.User, ui *FakeIdentifyUI) error { 40 me, err := libkb.LoadMe(libkb.NewLoadUserArg(tc.G)) 41 if err != nil { 42 return err 43 } 44 if them == nil { 45 tc.T.Fatal("checkTrackCommon called with nil 'them' user") 46 } 47 m := NewMetaContextForTest(tc) 48 s, err := me.TrackChainLinkFor(m, them.GetNormalizedName(), them.GetUID()) 49 if err != nil { 50 return err 51 } 52 53 if s == nil { 54 tc.T.Fatal("me.TrackChainLinkFor(...) returned nil, nil") 55 } else { 56 tc.T.Logf("payload json:\n%s", s.UnmarshalPayloadJSON().MarshalPretty()) 57 } 58 59 sbs := s.ToServiceBlocks() 60 if len(sbs) != len(blocks) { 61 return fmt.Errorf("num service blocks: %d, expected %d", len(sbs), len(blocks)) 62 } 63 sort.Sort(byID(sbs)) 64 for i, sb := range sbs { 65 tsb := blocks[i] 66 if sb.IsSocial() != tsb.social { 67 return fmt.Errorf("(sb %d): social: %v, expected %v", i, sb.IsSocial(), tsb.social) 68 } 69 if sb.ToIDString() != tsb.id { 70 return fmt.Errorf("(sb %d): id: %s, expected %s", i, sb.ToIDString(), tsb.id) 71 } 72 if sb.GetProofState() != tsb.proofState { 73 return fmt.Errorf("(sb %d): proof state: %d, expected %d", i, sb.GetProofState(), tsb.proofState) 74 } 75 } 76 77 if ui.Outcome.TrackStatus != outcome.TrackStatus { 78 return fmt.Errorf("track status: %d, expected %d", ui.Outcome.TrackStatus, outcome.TrackStatus) 79 } 80 81 if ui.Outcome.NumTrackFailures != outcome.NumTrackFailures { 82 return fmt.Errorf("num track failures: %d, expected %d", ui.Outcome.NumTrackFailures, outcome.NumTrackFailures) 83 } 84 if ui.Outcome.NumTrackChanges != outcome.NumTrackChanges { 85 return fmt.Errorf("num track changes: %d, expected %d", ui.Outcome.NumTrackChanges, outcome.NumTrackChanges) 86 } 87 if ui.Outcome.NumProofFailures != outcome.NumProofFailures { 88 return fmt.Errorf("num proof failures: %d, expected %d", ui.Outcome.NumProofFailures, outcome.NumProofFailures) 89 } 90 if ui.Outcome.NumProofSuccesses != outcome.NumProofSuccesses { 91 return fmt.Errorf("num proof successes: %d, expected %d", ui.Outcome.NumProofSuccesses, outcome.NumProofSuccesses) 92 } 93 if ui.Outcome.NumRevoked != outcome.NumRevoked { 94 return fmt.Errorf("num revoked: %d, expected %d", ui.Outcome.NumRevoked, outcome.NumRevoked) 95 } 96 97 return nil 98 } 99 100 type byID []*libkb.ServiceBlock 101 102 func (b byID) Len() int { return len(b) } 103 func (b byID) Less(x, y int) bool { return b[x].ToIDString() < b[y].ToIDString() } 104 func (b byID) Swap(x, y int) { b[x], b[y] = b[y], b[x] } 105 106 type sbtest struct { 107 name string 108 blocks []sb 109 outcome keybase1.IdentifyOutcome 110 } 111 112 // these aren't that interesting since all the proof states are 113 // the same, but it does some basic testing of the service blocks 114 // in a TrackChainLink. 115 var sbtests = []sbtest{ 116 { 117 name: "t_alice", 118 blocks: []sb{ 119 {social: true, id: "kbtester2@github", proofState: keybase1.ProofState_OK}, 120 {social: true, id: "tacovontaco@twitter", proofState: keybase1.ProofState_OK}, 121 }, 122 outcome: keybase1.IdentifyOutcome{ 123 NumProofSuccesses: 2, 124 TrackStatus: keybase1.TrackStatus_NEW_OK, 125 }, 126 }, 127 { 128 name: "t_bob", 129 blocks: []sb{ 130 {social: true, id: "kbtester1@github", proofState: keybase1.ProofState_OK}, 131 {social: true, id: "kbtester1@twitter", proofState: keybase1.ProofState_OK}, 132 }, 133 outcome: keybase1.IdentifyOutcome{ 134 NumProofSuccesses: 2, 135 TrackStatus: keybase1.TrackStatus_NEW_OK, 136 }, 137 }, 138 { 139 name: "t_charlie", 140 blocks: []sb{ 141 {social: true, id: "tacoplusplus@github", proofState: keybase1.ProofState_OK}, 142 {social: true, id: "tacovontaco@twitter", proofState: keybase1.ProofState_OK}, 143 }, 144 outcome: keybase1.IdentifyOutcome{ 145 NumProofSuccesses: 2, 146 TrackStatus: keybase1.TrackStatus_NEW_OK, 147 }, 148 }, 149 { 150 name: "t_doug", 151 outcome: keybase1.IdentifyOutcome{ 152 TrackStatus: keybase1.TrackStatus_NEW_ZERO_PROOFS, 153 }, 154 }, 155 } 156 157 func TestTrackProofServiceBlocks(t *testing.T) { 158 tc := SetupEngineTest(t, "track") 159 defer tc.Cleanup() 160 sigVersion := libkb.GetDefaultSigVersion(tc.G) 161 fu := CreateAndSignupFakeUser(tc, "track") 162 163 for _, test := range sbtests { 164 err := checkTrack(tc, fu, test.name, test.blocks, &test.outcome, sigVersion) 165 require.NoError(t, err) 166 err = runUntrack(tc, fu, test.name, sigVersion) 167 require.NoError(t, err) 168 } 169 } 170 171 // track a user that has no proofs 172 func TestTrackProofZero(t *testing.T) { 173 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 174 _testTrackProofZero(t, sigVersion) 175 }) 176 } 177 178 func _testTrackProofZero(t *testing.T, sigVersion libkb.SigVersion) { 179 tc := SetupEngineTest(t, "track") 180 defer tc.Cleanup() 181 182 // create a user with no proofs 183 proofUser := CreateAndSignupFakeUser(tc, "proof") 184 Logout(tc) 185 186 // create a user to track the proofUser 187 trackUser := CreateAndSignupFakeUser(tc, "track") 188 189 outcome := keybase1.IdentifyOutcome{ 190 TrackStatus: keybase1.TrackStatus_NEW_ZERO_PROOFS, 191 } 192 err := checkTrack(tc, trackUser, proofUser.Username, nil, &outcome, sigVersion) 193 require.NoError(t, err) 194 } 195 196 // track a user that has a rooter proof, check the tracking 197 // statement for correctness. 198 func TestTrackProofRooter(t *testing.T) { 199 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 200 _testTrackProofRooter(t, sigVersion) 201 }) 202 } 203 204 func _testTrackProofRooter(t *testing.T, sigVersion libkb.SigVersion) { 205 tc := SetupEngineTest(t, "track") 206 defer tc.Cleanup() 207 208 // create a user with a rooter proof 209 proofUser := CreateAndSignupFakeUser(tc, "proof") 210 _, _, err := proveRooter(tc.G, proofUser, sigVersion) 211 require.NoError(t, err) 212 Logout(tc) 213 214 // create a user to track the proofUser 215 trackUser := CreateAndSignupFakeUser(tc, "track") 216 217 rbl := sb{ 218 social: true, 219 id: proofUser.Username + "@rooter", 220 proofState: keybase1.ProofState_OK, 221 } 222 outcome := keybase1.IdentifyOutcome{ 223 NumProofSuccesses: 1, 224 TrackStatus: keybase1.TrackStatus_NEW_OK, 225 } 226 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 227 require.NoError(t, err) 228 229 // retrack, check the track status 230 outcome.TrackStatus = keybase1.TrackStatus_UPDATE_OK 231 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 232 require.NoError(t, err) 233 } 234 235 func TestTrackProofGubble(t *testing.T) { 236 tc := SetupEngineTest(t, "track") 237 defer tc.Cleanup() 238 sigVersion := libkb.KeybaseSignatureV2 239 240 // create a user with a rooter proof 241 proofUser := CreateAndSignupFakeUser(tc, "proof") 242 proveGubbleSocial(tc, proofUser, sigVersion) 243 proveGubbleCloud(tc, proofUser, sigVersion) 244 Logout(tc) 245 246 // create a user to track the proofUser 247 trackUser := CreateAndSignupFakeUser(tc, "track") 248 249 rbl := []sb{ 250 { 251 social: true, 252 id: proofUser.Username + "@gubble.cloud", 253 proofState: keybase1.ProofState_OK, 254 }, 255 { 256 social: true, 257 id: proofUser.Username + "@gubble.social", 258 proofState: keybase1.ProofState_OK, 259 }, 260 } 261 outcome := keybase1.IdentifyOutcome{ 262 NumProofSuccesses: 2, 263 TrackStatus: keybase1.TrackStatus_NEW_OK, 264 } 265 err := checkTrack(tc, trackUser, proofUser.Username, rbl, &outcome, sigVersion) 266 require.NoError(t, err) 267 268 // retrack, check the track status 269 outcome.TrackStatus = keybase1.TrackStatus_UPDATE_OK 270 err = checkTrack(tc, trackUser, proofUser.Username, rbl, &outcome, sigVersion) 271 require.NoError(t, err) 272 } 273 274 // upgrade tracking statement when new proof is added: 275 // track a user that has no proofs, then track them again after they add a proof 276 func TestTrackProofUpgrade(t *testing.T) { 277 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 278 _testTrackProofUpgrade(t, sigVersion) 279 }) 280 } 281 282 func _testTrackProofUpgrade(t *testing.T, sigVersion libkb.SigVersion) { 283 tc := SetupEngineTest(t, "track") 284 defer tc.Cleanup() 285 286 // create a user with no proofs 287 proofUser := CreateAndSignupFakeUser(tc, "proof") 288 Logout(tc) 289 290 // create a user to track the proofUser 291 trackUser := CreateAndSignupFakeUser(tc, "track") 292 outcome := keybase1.IdentifyOutcome{ 293 TrackStatus: keybase1.TrackStatus_NEW_ZERO_PROOFS, 294 } 295 err := checkTrack(tc, trackUser, proofUser.Username, nil, &outcome, sigVersion) 296 require.NoError(t, err) 297 298 // proofUser adds a rooter proof: 299 Logout(tc) 300 proofUser.LoginOrBust(tc) 301 _, _, err = proveRooter(tc.G, proofUser, sigVersion) 302 require.NoError(t, err) 303 Logout(tc) 304 305 // trackUser tracks proofUser again: 306 trackUser.LoginOrBust(tc) 307 308 rbl := sb{ 309 social: true, 310 id: proofUser.Username + "@rooter", 311 proofState: keybase1.ProofState_OK, 312 } 313 outcome = keybase1.IdentifyOutcome{ 314 NumTrackChanges: 1, 315 NumProofSuccesses: 1, 316 TrackStatus: keybase1.TrackStatus_UPDATE_NEW_PROOFS, 317 } 318 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 319 require.NoError(t, err) 320 } 321 322 // test a change to a proof 323 func TestTrackProofChangeSinceTrack(t *testing.T) { 324 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 325 _testTrackProofChangeSinceTrack(t, sigVersion) 326 }) 327 } 328 329 func _testTrackProofChangeSinceTrack(t *testing.T, sigVersion libkb.SigVersion) { 330 tc := SetupEngineTest(t, "track") 331 defer tc.Cleanup() 332 333 // create a user with a rooter proof 334 proofUser := CreateAndSignupFakeUser(tc, "proof") 335 _, _, err := proveRooter(tc.G, proofUser, sigVersion) 336 require.NoError(t, err) 337 Logout(tc) 338 339 // create a user to track the proofUser 340 trackUser := CreateAndSignupFakeUser(tc, "track") 341 342 rbl := sb{ 343 social: true, 344 id: proofUser.Username + "@rooter", 345 proofState: keybase1.ProofState_OK, 346 } 347 outcome := keybase1.IdentifyOutcome{ 348 NumProofSuccesses: 1, 349 TrackStatus: keybase1.TrackStatus_NEW_OK, 350 } 351 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 352 require.NoError(t, err) 353 354 Logout(tc) 355 356 // proof user logs in and does a new rooter proof 357 proofUser.LoginOrBust(tc) 358 _, _, err = proveRooter(tc.G, proofUser, sigVersion) 359 require.NoError(t, err) 360 Logout(tc) 361 362 // track user logs in and tracks proof user again 363 trackUser.LoginOrBust(tc) 364 outcome.TrackStatus = keybase1.TrackStatus_UPDATE_OK 365 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 366 require.NoError(t, err) 367 } 368 369 // track a user that has a failed rooter proof 370 func TestTrackProofRooterFail(t *testing.T) { 371 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 372 _testTrackProofRooterFail(t, sigVersion) 373 }) 374 } 375 376 func _testTrackProofRooterFail(t *testing.T, sigVersion libkb.SigVersion) { 377 tc := SetupEngineTest(t, "track") 378 defer tc.Cleanup() 379 380 // create a user with a rooter proof 381 proofUser := CreateAndSignupFakeUser(tc, "proof") 382 _, err := proveRooterFail(tc.G, proofUser, sigVersion) 383 require.Error(t, err) 384 Logout(tc) 385 386 // create a user to track the proofUser 387 trackUser := CreateAndSignupFakeUser(tc, "track") 388 389 // proveRooterFail posts a bad sig id, so it won't be found. 390 // thus the state is ProofState_SIG_HINT_MISSING 391 rbl := sb{ 392 social: true, 393 id: proofUser.Username + "@rooter", 394 proofState: keybase1.ProofState_SIG_HINT_MISSING, 395 } 396 outcome := keybase1.IdentifyOutcome{ 397 NumProofFailures: 1, 398 TrackStatus: keybase1.TrackStatus_NEW_ZERO_PROOFS, 399 } 400 // and they have no proofs 401 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 402 require.NoError(t, err) 403 } 404 405 func TestTrackProofGubbleFail(t *testing.T) { 406 tc := SetupEngineTest(t, "track") 407 defer tc.Cleanup() 408 sigVersion := libkb.KeybaseSignatureV2 409 410 // create a user with a rooter proof 411 proofUser := CreateAndSignupFakeUser(tc, "proof") 412 proveGubbleSocialFail(tc, proofUser, sigVersion) 413 Logout(tc) 414 415 // create a user to track the proofUser 416 trackUser := CreateAndSignupFakeUser(tc, "track") 417 418 // proveGubbleSocialFail posts a bad sig id, so it won't be found. 419 // thus the state is ProofState_SIG_HINT_MISSING 420 rbl := sb{ 421 social: true, 422 id: proofUser.Username + "@gubble.social", 423 proofState: keybase1.ProofState_SIG_HINT_MISSING, 424 } 425 outcome := keybase1.IdentifyOutcome{ 426 NumProofFailures: 1, 427 TrackStatus: keybase1.TrackStatus_NEW_ZERO_PROOFS, 428 } 429 // and they have no proofs 430 err := checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 431 require.NoError(t, err) 432 } 433 434 // track a user that has a rooter proof, remove the proof, then 435 // track again. 436 // Note that the API server won't notice that the rooter proof has 437 // been removed as it only checks every 12 hours. The client will 438 // notice and should generate an appropriate tracking statement. 439 func TestTrackProofRooterRemove(t *testing.T) { 440 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 441 _testTrackProofRooterRemove(t, sigVersion) 442 }) 443 } 444 445 func _testTrackProofRooterRemove(t *testing.T, sigVersion libkb.SigVersion) { 446 tc := SetupEngineTest(t, "track") 447 defer tc.Cleanup() 448 449 // create a user with a rooter proof 450 proofUser := CreateAndSignupFakeUser(tc, "proof") 451 ui, _, err := proveRooter(tc.G, proofUser, sigVersion) 452 require.NoError(t, err) 453 Logout(tc) 454 455 // create a user to track the proofUser 456 trackUser := CreateAndSignupFakeUser(tc, "track") 457 458 rbl := sb{ 459 social: true, 460 id: proofUser.Username + "@rooter", 461 proofState: keybase1.ProofState_OK, 462 } 463 outcome := keybase1.IdentifyOutcome{ 464 NumProofSuccesses: 1, 465 TrackStatus: keybase1.TrackStatus_NEW_OK, 466 } 467 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 468 require.NoError(t, err) 469 470 // remove the rooter proof 471 Logout(tc) 472 proofUser.LoginOrBust(tc) 473 err = proveRooterRemove(tc.G, ui.postID) 474 require.NoError(t, err) 475 476 Logout(tc) 477 478 // track again 479 trackUser.LoginOrBust(tc) 480 rbl.proofState = keybase1.ProofState_TEMP_FAILURE 481 outcome = keybase1.IdentifyOutcome{ 482 NumTrackFailures: 1, 483 NumTrackChanges: 1, 484 NumProofFailures: 1, 485 TrackStatus: keybase1.TrackStatus_UPDATE_BROKEN_FAILED_PROOFS, 486 } 487 // use checkTrackForce to skip any proof cache results 488 err = checkTrackForce(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome) 489 require.NoError(t, err) 490 491 // check that it is "fixed" 492 outcome = keybase1.IdentifyOutcome{ 493 NumProofFailures: 1, 494 TrackStatus: keybase1.TrackStatus_UPDATE_OK, 495 } 496 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 497 require.NoError(t, err) 498 } 499 500 // test tracking a user who revokes a proof. Revoking a proof 501 // removes it from the sig chain, so this tests the 502 // libkb.IdentifyState.ComputeRevokedProofs() function, and how 503 // libkb.IdentifyOutcome.TrackStatus() interprets the result. 504 func TestTrackProofRooterRevoke(t *testing.T) { 505 doWithSigChainVersions(func(sigVersion libkb.SigVersion) { 506 _testTrackProofRooterRevoke(t, sigVersion) 507 }) 508 } 509 510 func _testTrackProofRooterRevoke(t *testing.T, sigVersion libkb.SigVersion) { 511 tc := SetupEngineTest(t, "track") 512 defer tc.Cleanup() 513 514 // create a user with a rooter proof 515 proofUser := CreateAndSignupFakeUser(tc, "proof") 516 _, sigID, err := proveRooter(tc.G, proofUser, sigVersion) 517 require.NoError(t, err) 518 Logout(tc) 519 520 // create a user to track the proofUser 521 trackUser := CreateAndSignupFakeUser(tc, "track") 522 523 rbl := sb{ 524 social: true, 525 id: proofUser.Username + "@rooter", 526 proofState: keybase1.ProofState_OK, 527 } 528 outcome := keybase1.IdentifyOutcome{ 529 NumProofSuccesses: 1, 530 TrackStatus: keybase1.TrackStatus_NEW_OK, 531 } 532 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 533 require.NoError(t, err) 534 535 // revoke the rooter proof 536 Logout(tc) 537 proofUser.LoginOrBust(tc) 538 revEng := NewRevokeSigsEngine(tc.G, []string{sigID.String()}) 539 uis := libkb.UIs{ 540 LogUI: tc.G.UI.GetLogUI(), 541 SecretUI: proofUser.NewSecretUI(), 542 } 543 m := NewMetaContextForTest(tc).WithUIs(uis) 544 545 err = revEng.Run(m) 546 require.NoError(t, err) 547 Logout(tc) 548 549 // track proofUser again and check revoked proof handled correctly 550 trackUser.LoginOrBust(tc) 551 outcome = keybase1.IdentifyOutcome{ 552 NumRevoked: 1, 553 TrackStatus: keybase1.TrackStatus_UPDATE_BROKEN_REVOKED, 554 } 555 err = checkTrack(tc, trackUser, proofUser.Username, nil, &outcome, sigVersion) 556 require.NoError(t, err) 557 558 // track again and check for fix 559 outcome = keybase1.IdentifyOutcome{ 560 TrackStatus: keybase1.TrackStatus_UPDATE_OK, 561 } 562 err = checkTrack(tc, trackUser, proofUser.Username, nil, &outcome, sigVersion) 563 require.NoError(t, err) 564 } 565 566 // proofUser makes a user@rooter proof, then a user2@rooter proof. 567 // trackUser tracks proofUser. Verify the tracking statement. 568 func TestTrackProofRooterOther(t *testing.T) { 569 tc := SetupEngineTest(t, "track") 570 defer tc.Cleanup() 571 572 sigVersion := libkb.GetDefaultSigVersion(tc.G) 573 // create a user with a rooter proof 574 proofUser := CreateAndSignupFakeUser(tc, "proof") 575 _, _, err := proveRooter(tc.G, proofUser, sigVersion) 576 require.NoError(t, err) 577 Logout(tc) 578 579 // post a rooter proof as a different rooter user 580 proofUserOther := CreateAndSignupFakeUser(tc, "proof") 581 Logout(tc) 582 proofUser.LoginOrBust(tc) 583 _, _, err = proveRooterOther(tc.G, proofUser, proofUserOther.Username, sigVersion) 584 require.NoError(t, err) 585 Logout(tc) 586 587 // create a user to track the proofUser 588 trackUser := CreateAndSignupFakeUser(tc, "track") 589 590 rbl := sb{ 591 social: true, 592 id: proofUserOther.Username + "@rooter", 593 proofState: keybase1.ProofState_OK, 594 } 595 outcome := keybase1.IdentifyOutcome{ 596 NumProofSuccesses: 1, 597 TrackStatus: keybase1.TrackStatus_NEW_OK, 598 } 599 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 600 require.NoError(t, err) 601 } 602 603 // proofUser makes a user@rooter proof, trackUser tracks 604 // proofUser. proofUser makes a user2@rooter proof, trackUser 605 // tracks proofUser again. Test that the change is noticed. 606 func TestTrackProofRooterChange(t *testing.T) { 607 tc := SetupEngineTest(t, "track") 608 defer tc.Cleanup() 609 sigVersion := libkb.GetDefaultSigVersion(tc.G) 610 611 // create a user with a rooter proof 612 proofUser := CreateAndSignupFakeUser(tc, "proof") 613 _, _, err := proveRooter(tc.G, proofUser, sigVersion) 614 require.NoError(t, err) 615 Logout(tc) 616 617 // create a user to track the proofUser 618 trackUser := CreateAndSignupFakeUser(tc, "track") 619 620 rbl := sb{ 621 social: true, 622 id: proofUser.Username + "@rooter", 623 proofState: keybase1.ProofState_OK, 624 } 625 outcome := keybase1.IdentifyOutcome{ 626 NumProofSuccesses: 1, 627 TrackStatus: keybase1.TrackStatus_NEW_OK, 628 } 629 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 630 require.NoError(t, err) 631 632 // post a rooter proof as a different rooter user 633 Logout(tc) 634 proofUserOther := CreateAndSignupFakeUser(tc, "proof") 635 Logout(tc) 636 637 proofUser.LoginOrBust(tc) 638 _, _, err = proveRooterOther(tc.G, proofUser, proofUserOther.Username, sigVersion) 639 require.NoError(t, err) 640 Logout(tc) 641 642 // track proofUser again and check new rooter proof with different account handled correctly 643 trackUser.LoginOrBust(tc) 644 rbl.id = proofUserOther.Username + "@rooter" 645 outcome = keybase1.IdentifyOutcome{ 646 NumTrackChanges: 1, 647 NumTrackFailures: 1, 648 NumProofSuccesses: 1, 649 TrackStatus: keybase1.TrackStatus_UPDATE_BROKEN_FAILED_PROOFS, 650 } 651 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 652 require.NoError(t, err) 653 654 // track again and check for fix 655 outcome = keybase1.IdentifyOutcome{ 656 NumProofSuccesses: 1, 657 TrackStatus: keybase1.TrackStatus_UPDATE_OK, 658 } 659 err = checkTrack(tc, trackUser, proofUser.Username, []sb{rbl}, &outcome, sigVersion) 660 require.NoError(t, err) 661 } 662 663 // TODO: 664 // * get a test that will generate TrackStatus_NEW_FAIL_PROOFS 665 // (this requires two services, one with an ok proof, one with a 666 // failing proof) 667 // * test upgrade from http to https, or a secure rooter post vs. 668 // regular rooter post to get TrackDiffUpgraded. 669 // * a test that will generate TrackDiffRemoteChanged