diff --git a/go/client/cmd_pgp_update.go b/go/client/cmd_pgp_update.go index f13a5d6a233d..830a49c1ca54 100644 --- a/go/client/cmd_pgp_update.go +++ b/go/client/cmd_pgp_update.go @@ -56,7 +56,7 @@ func NewCmdPGPUpdate(cl *libcmdline.CommandLine) cli.Command { Action: func(c *cli.Context) { cl.ChooseCommand(&CmdPGPUpdate{}, "update", c) }, - Description: `'keybase pgp update' pushed updated PGP public keys to the server. + Description: `'keybase pgp update' pushes updated PGP public keys to the server. Public PGP keys are exported from your local GPG keyring and sent to the Keybase server, where they will supersede PGP keys that have been previously updated. This feature is for updating PGP subkeys, identities, diff --git a/go/engine/track_test.go b/go/engine/track_test.go index 10dfc83642dd..1e1a62840d48 100644 --- a/go/engine/track_test.go +++ b/go/engine/track_test.go @@ -151,6 +151,20 @@ func TestTrackMultiple(t *testing.T) { trackAlice(tc, fu) } +func TestTrackNewUserWithPGP(t *testing.T) { + tc := SetupEngineTest(t, "track") + defer tc.Cleanup() + fu := createFakeUserWithPGPSibkey(tc) + Logout(tc) + + tracker := CreateAndSignupFakeUser(tc, "track") + t.Logf("first track:") + runTrack(tc, tracker, fu.Username) + + t.Logf("second track:") + runTrack(tc, tracker, fu.Username) +} + // see issue #578 func TestTrackRetrack(t *testing.T) { tc := SetupEngineTest(t, "track") diff --git a/go/libkb/id_table.go b/go/libkb/id_table.go index 388e29678ff5..a09846c57f8b 100644 --- a/go/libkb/id_table.go +++ b/go/libkb/id_table.go @@ -422,15 +422,12 @@ func trackedKeyFromJSON(jw *jsonw.Wrapper) (TrackedKey, error) { return TrackedKey{}, err } ret.KID = kid - // TODO: Should we tolerate missing fingerprints? Will "body.track.key" - // ever be a non-PGP key, for example? I'm *very* hesitant about defining a - // new type that's basically a FOKID, right after we did all that work to - // delete FOKID. + + // It's ok if key_fingerprint doesn't exist. But if it does, then include it: fp, err := GetPGPFingerprint(jw.AtKey("key_fingerprint")) - if err != nil { - return TrackedKey{}, err + if err == nil && fp != nil { + ret.Fingerprint = *fp } - ret.Fingerprint = *fp return ret, nil } @@ -441,16 +438,6 @@ func (l *TrackChainLink) GetTrackedKeys() ([]TrackedKey, error) { var res []TrackedKey - keyJSON := l.payloadJSON.AtPath("body.track.key") - if !keyJSON.IsNil() { - tracked, err := trackedKeyFromJSON(keyJSON) - if err != nil { - return nil, err - } - res = append(res, tracked) - set[tracked.KID] = true - } - pgpKeysJSON := l.payloadJSON.AtPath("body.track.pgp_keys") if !pgpKeysJSON.IsNil() { n, err := pgpKeysJSON.Len() @@ -472,6 +459,18 @@ func (l *TrackChainLink) GetTrackedKeys() ([]TrackedKey, error) { return res, nil } +func (l *TrackChainLink) GetEldestKID() (kid keybase1.KID, err error) { + keyJSON := l.payloadJSON.AtPath("body.track.key") + if keyJSON.IsNil() { + return kid, nil + } + tracked, err := trackedKeyFromJSON(keyJSON) + if err != nil { + return kid, err + } + return tracked.KID, nil +} + func (l *TrackChainLink) GetTrackedUID() (keybase1.UID, error) { return GetUID(l.payloadJSON.AtPath("body.track.id")) } diff --git a/go/libkb/identify_state.go b/go/libkb/identify_state.go index f4fcf4a7e8c6..b92a840ac0ef 100644 --- a/go/libkb/identify_state.go +++ b/go/libkb/identify_state.go @@ -91,6 +91,17 @@ func (s *IdentifyState) ComputeKeyDiffs(dhook func(keybase1.IdentifyKey)) { dhook(k) } + // first check the eldest key + observedEldest := s.u.GetEldestKID() + if s.track != nil { + trackedEldest := s.track.GetEldestKID() + if observedEldest.NotEqual(trackedEldest) { + diff := TrackDiffNewEldest{tracked: trackedEldest, observed: observedEldest} + s.res.KeyDiffs = append(s.res.KeyDiffs, diff) + display(observedEldest, diff) + } + } + found := s.u.GetActivePGPKIDs(true) foundMap := mapify(found) var tracked []keybase1.KID diff --git a/go/libkb/track.go b/go/libkb/track.go index 933068cb1216..15421e0395a9 100644 --- a/go/libkb/track.go +++ b/go/libkb/track.go @@ -122,6 +122,14 @@ func (l TrackLookup) GetTrackedKeys() []TrackedKey { return ret } +func (l TrackLookup) GetEldestKID() keybase1.KID { + ret, err := l.link.GetEldestKID() + if err != nil { + G.Log.Warning("Error in lookup of eldest KID: %s", err) + } + return ret +} + func (l TrackLookup) IsRemote() bool { return l.link.IsRemote() } @@ -296,6 +304,27 @@ func (t TrackDiffRemoteChanged) IsSameAsTracked() bool { return false } +type TrackDiffNewEldest struct { + tracked keybase1.KID + observed keybase1.KID +} + +func (t TrackDiffNewEldest) BreaksTracking() bool { + return true +} +func (t TrackDiffNewEldest) IsSameAsTracked() bool { + return false +} +func (t TrackDiffNewEldest) GetTrackDiffType() keybase1.TrackDiffType { + return keybase1.TrackDiffType_NEW_ELDEST +} +func (t TrackDiffNewEldest) ToDisplayString() string { + return fmt.Sprintf("Changed from %s to %s", t.tracked, t.observed) +} +func (t TrackDiffNewEldest) ToDisplayMarkup() *Markup { + return NewMarkup(t.ToDisplayString()) +} + func NewTrackLookup(link *TrackChainLink) *TrackLookup { sbs := link.ToServiceBlocks() set := NewTrackSet() diff --git a/go/protocol/keybase_v1.go b/go/protocol/keybase_v1.go index e0a74251ef43..75ac9ff9ad5a 100644 --- a/go/protocol/keybase_v1.go +++ b/go/protocol/keybase_v1.go @@ -1425,6 +1425,7 @@ const ( TrackDiffType_REMOTE_FAIL TrackDiffType = 6 TrackDiffType_REMOTE_WORKING TrackDiffType = 7 TrackDiffType_REMOTE_CHANGED TrackDiffType = 8 + TrackDiffType_NEW_ELDEST TrackDiffType = 9 ) type TrackDiff struct { diff --git a/protocol/avdl/identify_common.avdl b/protocol/avdl/identify_common.avdl index bc3cd5d52589..320ea934138d 100644 --- a/protocol/avdl/identify_common.avdl +++ b/protocol/avdl/identify_common.avdl @@ -13,7 +13,8 @@ protocol identifyCommon { NEW_5, REMOTE_FAIL_6, REMOTE_WORKING_7, - REMOTE_CHANGED_8 + REMOTE_CHANGED_8, + NEW_ELDEST_9 } record TrackDiff { diff --git a/protocol/js/keybase_v1.js b/protocol/js/keybase_v1.js index 78837c6150a6..35da7f412fe3 100644 --- a/protocol/js/keybase_v1.js +++ b/protocol/js/keybase_v1.js @@ -205,7 +205,8 @@ export default { 'new': 5, 'remoteFail': 6, 'remoteWorking': 7, - 'remoteChanged': 8 + 'remoteChanged': 8, + 'newEldest': 9 }, 'TrackStatus': { 'newOk': 1, @@ -296,7 +297,8 @@ export default { 'new': 5, 'remoteFail': 6, 'remoteWorking': 7, - 'remoteChanged': 8 + 'remoteChanged': 8, + 'newEldest': 9 }, 'TrackStatus': { 'newOk': 1, @@ -608,7 +610,8 @@ export default { 'new': 5, 'remoteFail': 6, 'remoteWorking': 7, - 'remoteChanged': 8 + 'remoteChanged': 8, + 'newEldest': 9 }, 'TrackStatus': { 'newOk': 1, @@ -704,7 +707,8 @@ export default { 'new': 5, 'remoteFail': 6, 'remoteWorking': 7, - 'remoteChanged': 8 + 'remoteChanged': 8, + 'newEldest': 9 }, 'TrackStatus': { 'newOk': 1, @@ -919,7 +923,8 @@ export default { 'new': 5, 'remoteFail': 6, 'remoteWorking': 7, - 'remoteChanged': 8 + 'remoteChanged': 8, + 'newEldest': 9 }, 'TrackStatus': { 'newOk': 1, diff --git a/protocol/json/identify.json b/protocol/json/identify.json index 5f369ce55826..c7f5e947ddc2 100644 --- a/protocol/json/identify.json +++ b/protocol/json/identify.json @@ -174,7 +174,7 @@ }, { "type" : "enum", "name" : "TrackDiffType", - "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8" ] + "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8", "NEW_ELDEST_9" ] }, { "type" : "record", "name" : "TrackDiff", diff --git a/protocol/json/identify_ui.json b/protocol/json/identify_ui.json index 0c5f0844c9a3..9693486a8589 100644 --- a/protocol/json/identify_ui.json +++ b/protocol/json/identify_ui.json @@ -174,7 +174,7 @@ }, { "type" : "enum", "name" : "TrackDiffType", - "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8" ] + "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8", "NEW_ELDEST_9" ] }, { "type" : "record", "name" : "TrackDiff", diff --git a/protocol/json/pgp.json b/protocol/json/pgp.json index 589b6c2e6f16..17782539bf7b 100644 --- a/protocol/json/pgp.json +++ b/protocol/json/pgp.json @@ -174,7 +174,7 @@ }, { "type" : "enum", "name" : "TrackDiffType", - "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8" ] + "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8", "NEW_ELDEST_9" ] }, { "type" : "record", "name" : "TrackDiff", diff --git a/protocol/json/prove.json b/protocol/json/prove.json index 4d548466c781..4cb0f42d84e7 100644 --- a/protocol/json/prove.json +++ b/protocol/json/prove.json @@ -174,7 +174,7 @@ }, { "type" : "enum", "name" : "TrackDiffType", - "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8" ] + "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8", "NEW_ELDEST_9" ] }, { "type" : "record", "name" : "TrackDiff", diff --git a/protocol/json/track.json b/protocol/json/track.json index 612dbfd9c6e8..101d690c6480 100644 --- a/protocol/json/track.json +++ b/protocol/json/track.json @@ -174,7 +174,7 @@ }, { "type" : "enum", "name" : "TrackDiffType", - "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8" ] + "symbols" : [ "NONE_0", "ERROR_1", "CLASH_2", "REVOKED_3", "UPGRADED_4", "NEW_5", "REMOTE_FAIL_6", "REMOTE_WORKING_7", "REMOTE_CHANGED_8", "NEW_ELDEST_9" ] }, { "type" : "record", "name" : "TrackDiff",