diff --git a/storage/e2e/manager.go b/storage/e2e/manager.go index 802e81ebe2329f5bd3714500e0229071eaea3bd3..5f12e6b449e35d91b3cfc3f15e0240cc89f6fdae 100644 --- a/storage/e2e/manager.go +++ b/storage/e2e/manager.go @@ -108,6 +108,31 @@ func loadManager(ctx *context, kv *versioned.KV, partnerID *id.ID) (*Manager, er return m, nil } +// clearManager removes the relationship between the partner +// and deletes the Send and Receive sessions +func clearManager(m *Manager, kv *versioned.KV) error { + kv = kv.Prefix(fmt.Sprintf(managerPrefix, m.partner)) + + if err := DeleteRelationship(m, Send); err != nil { + return errors.WithMessage(err, + "Failed to delete remove partner key relationship due to failure to " + + "delete the Send session buffer") + } + + if err := DeleteRelationship(m, Receive); err != nil { + return errors.WithMessage(err, + "Failed to delete remove partner key relationship due to failure to " + + "delete the Receive session buffer") + } + + if err := utility.DeleteCyclicKey(m.kv, originPartnerPubKey); err != nil { + jww.FATAL.Panicf("Failed to delete %s: %+v", originPartnerPubKey, + err) + } + + return nil +} + // NewReceiveSession creates a new Receive session using the latest private key // this user has sent and the new public key received from the partner. If the // session already exists, then it will not be overwritten and the extant diff --git a/storage/e2e/manager_test.go b/storage/e2e/manager_test.go index 907bbff91b561d2267b71371356ae7bf6f332b86..fed60f22bb7ba288a9b1d757d4431a706a784612 100644 --- a/storage/e2e/manager_test.go +++ b/storage/e2e/manager_test.go @@ -68,6 +68,30 @@ func TestLoadManager(t *testing.T) { } } +// Unit test for clearManager +func TestManager_ClearManager(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fatalf("clearManager error: " + + "Did not panic when loading deleted manager") + } + }() + + // Set up expected and test values + expectedM, kv := newTestManager(t) + + err := clearManager(expectedM, kv) + if err != nil { + t.Fatalf("clearManager returned an error: %v", err) + } + + // Attempt to load relationship + _, err = loadManager(expectedM.ctx, kv, expectedM.partner) + if err != nil { + t.Errorf("loadManager() returned an error: %v", err) + } +} + // Tests happy path of Manager.NewReceiveSession. func TestManager_NewReceiveSession(t *testing.T) { // Set up test values diff --git a/storage/e2e/relationship.go b/storage/e2e/relationship.go index a492a72ed51d0f48f08657d786bc8dc6a3c861ed..9089b04d871e6a394a563fc141cb24b5481726c2 100644 --- a/storage/e2e/relationship.go +++ b/storage/e2e/relationship.go @@ -84,6 +84,16 @@ func NewRelationship(manager *Manager, t RelationshipType, return r } +// DeleteRelationship is a function which removes +// the relationship and relationship fingerprint from the store +func DeleteRelationship(manager *Manager, t RelationshipType) error { + kv := manager.kv.Prefix(t.prefix()) + if err := deleteRelationshipFingerprint(kv); err != nil { + return err + } + return kv.Delete(relationshipKey, currentRelationshipVersion) +} + func LoadRelationship(manager *Manager, t RelationshipType) (*relationship, error) { kv := manager.kv.Prefix(t.prefix()) diff --git a/storage/e2e/relationshipFingerprint.go b/storage/e2e/relationshipFingerprint.go index a3702655319ccf0f14323d31f5b32b3fe59cb825..367dabdfd9a8e3e5debbac08f4f68ed7f9c3ab13 100644 --- a/storage/e2e/relationshipFingerprint.go +++ b/storage/e2e/relationshipFingerprint.go @@ -57,3 +57,9 @@ func loadRelationshipFingerprint(kv *versioned.KV) []byte { } return obj.Data } + +// deleteRelationshipFingerprint is a helper function which deletes a fingerprint from store +func deleteRelationshipFingerprint(kv *versioned.KV) error { + return kv.Delete(relationshipFingerprintKey, + currentRelationshipVersion) +} diff --git a/storage/e2e/relationship_test.go b/storage/e2e/relationship_test.go index 457e4f6dcd508abd2014248db7738f46badf947a..7ac35b3d429909531492a05cfe155dd9af6adaf4 100644 --- a/storage/e2e/relationship_test.go +++ b/storage/e2e/relationship_test.go @@ -68,6 +68,53 @@ func TestLoadRelationship(t *testing.T) { } } +// Shows that a deleted Relationship can no longer be pulled from store +func TestDeleteRelationship(t *testing.T) { + mgr := makeTestRelationshipManager(t) + sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams()) + + err := sb.save() + if err != nil { + t.Fatal(err) + } + + err = DeleteRelationship(mgr, Send) + if err != nil { + t.Fatalf("DeleteRelationship error: Could not delete manager: %v", err) + } + + _, err = LoadRelationship(mgr, Send) + if err == nil { + t.Fatalf("DeleteRelationship error: Should not have loaded deleted relationship: %v", err) + } +} + +// Shows that a deleted relationship fingerprint can no longer be pulled from store +func TestRelationship_deleteRelationshipFingerprint(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fatalf("deleteRelationshipFingerprint error: " + + "Did not panic when loading deleted fingerprint") + } + }() + + mgr := makeTestRelationshipManager(t) + sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams()) + + err := sb.save() + if err != nil { + t.Fatal(err) + } + + err = deleteRelationshipFingerprint(mgr.kv) + if err != nil { + t.Fatalf("deleteRelationshipFingerprint error: " + + "Could not delete fingerprint: %v", err) + } + + loadRelationshipFingerprint(mgr.kv) +} + // Shows that Relationship returns a valid session buff func TestNewRelationshipBuff(t *testing.T) { mgr := makeTestRelationshipManager(t) diff --git a/storage/e2e/store.go b/storage/e2e/store.go index e647cacab042388b667d383f670c8082c450b591..a7868e0aa5322510824453a621e4bc5f0deec605 100644 --- a/storage/e2e/store.go +++ b/storage/e2e/store.go @@ -187,6 +187,21 @@ func (s *Store) AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.In return nil } +// DeletePartner removes the associated contact from the E2E store +func (s *Store) DeletePartner(partnerId *id.ID) error { + m, ok := s.managers[*partnerId] + if !ok { + return errors.New(NoPartnerErrorStr) + } + + if err := clearManager(m, s.kv); err != nil { + return errors.WithMessagef(err, "Could not remove partner %s from store", partnerId) + } + + delete(s.managers, *partnerId) + return s.save() +} + func (s *Store) GetPartner(partnerID *id.ID) (*Manager, error) { s.mux.RLock() defer s.mux.RUnlock() diff --git a/storage/e2e/store_test.go b/storage/e2e/store_test.go index 944b2517df666e536db085d6ce3f0a001316aa2d..f5d3e7f7ccbc037ea6185470b857aaef3428a8b6 100644 --- a/storage/e2e/store_test.go +++ b/storage/e2e/store_test.go @@ -97,7 +97,10 @@ func TestStore_AddPartner(t *testing.T) { expectedManager := newManager(s.context, s.kv, partnerID, s.dhPrivateKey, pubKey, p, p) - s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p) + err := s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p) + if err != nil { + t.Fatalf("AddPartner returned an error: %v", err) + } m, exists := s.managers[*partnerID] if !exists { @@ -110,6 +113,30 @@ func TestStore_AddPartner(t *testing.T) { } } +// Unit test for DeletePartner +func TestStore_DeletePartner(t *testing.T) { + s, _, _ := makeTestStore() + partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t) + pubKey := diffieHellman.GeneratePublicKey(s.dhPrivateKey, s.grp) + p := params.GetDefaultE2ESessionParams() + + err := s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p) + if err != nil { + t.Fatalf("DeletePartner error: Could not add partner in set up: %v", err) + } + + err = s.DeletePartner(partnerID) + if err != nil { + t.Fatalf("DeletePartner received an error: %v", err) + } + + _, err = s.GetPartner(partnerID) + if err== nil { + t.Errorf("DeletePartner error: Should not be able to pull deleted partner from store") + } + +} + // Tests happy path of Store.GetPartner. func TestStore_GetPartner(t *testing.T) { s, _, _ := makeTestStore() diff --git a/storage/utility/dh.go b/storage/utility/dh.go index 9b0280ed1ef4bd96e71d15fcc788b5633c51fe03..6295e446d3563127c4c1262733eb3abf8ac8b91e 100644 --- a/storage/utility/dh.go +++ b/storage/utility/dh.go @@ -42,3 +42,8 @@ func LoadCyclicKey(kv *versioned.KV, key string) (*cyclic.Int, error) { return cy, cy.GobDecode(vo.Data) } + +// DeleteCyclicKey deletes a given cyclic key from storage +func DeleteCyclicKey(kv *versioned.KV, key string) error { + return kv.Delete(key, currentCyclicVersion) +} diff --git a/storage/utility/dh_test.go b/storage/utility/dh_test.go index 4d4a31941faee3467f029ffca4dbc57f8fa9dafe..36fb3c5734af6ea7bd29479279f01b10522b803d 100644 --- a/storage/utility/dh_test.go +++ b/storage/utility/dh_test.go @@ -47,3 +47,27 @@ func TestLoadCyclicKey(t *testing.T) { t.Errorf("Stored int did not match received. Stored: %v, Received: %v", x, loaded) } } + +// Unit test for DeleteCyclicKey +func TestDeleteCyclicKey(t *testing.T) { + kv := make(ekv.Memstore) + vkv := versioned.NewKV(kv) + grp := getTestGroup() + x := grp.NewInt(77) + + intKey := "testKey" + err := StoreCyclicKey(vkv, x, intKey) + if err != nil { + t.Errorf("Failed to store cyclic key: %+v", err) + } + + err = DeleteCyclicKey(vkv, intKey) + if err != nil { + t.Fatalf("DeleteCyclicKey returned an error: %v", err) + } + + _, err = LoadCyclicKey(vkv, intKey) + if err == nil { + t.Errorf("DeleteCyclicKey error: Should not load deleted key: %+v", err) + } +}