diff --git a/api/client.go b/api/client.go index c3ff5cd85229da9bcc54e0d06195b1f353dc3636..04ef12f039dce295c98ffc6a19b8bbd6ccc39007 100644 --- a/api/client.go +++ b/api/client.go @@ -743,6 +743,14 @@ func (c *Client) GetNodeRegistrationStatus() (int, int, error) { return numRegistered, len(nodes) - numStale, nil } +// DeleteRequest will delete a request, agnostic of request type +// for the given partner ID. If no request exists for this +// partner ID an error will be returned. +func (c *Client) DeleteRequest(partnerId *id.ID) error { + jww.DEBUG.Printf("Deleting request for partner ID: %s", partnerId) + return c.GetStorage().Auth().DeleteRequest(partnerId) +} + // DeleteAllRequests clears all requests from client's auth storage. func (c *Client) DeleteAllRequests() error { jww.DEBUG.Printf("Deleting all requests") diff --git a/bindings/client.go b/bindings/client.go index e543b80428c9b6ac9a5439c0534142bd8a1d17f1..dd44fc2ffba856d93b9e5c7b95db3a71a689d8e8 100644 --- a/bindings/client.go +++ b/bindings/client.go @@ -467,6 +467,19 @@ func (c *Client) GetNodeRegistrationStatus() (*NodeRegistrationsStatus, error) { return &NodeRegistrationsStatus{registered, total}, err } +// DeleteRequest will delete a request, agnostic of request type +// for the given partner ID. If no request exists for this +// partner ID an error will be returned. +func (c *Client) DeleteRequest(requesterUserId []byte) error { + requesterId, err := id.Unmarshal(requesterUserId) + if err != nil { + return err + } + + jww.DEBUG.Printf("Deleting request for partner ID: %s", requesterId) + return c.api.DeleteRequest(requesterId) +} + // DeleteAllRequests clears all requests from Client's auth storage. func (c *Client) DeleteAllRequests() error { return c.api.DeleteAllRequests() diff --git a/cmd/root.go b/cmd/root.go index aa9a1c716608fc5eb87ecadd566a7dad5f592083..08b4927142772d0ed5dc08f54e28422d6924f384 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -328,6 +328,10 @@ var rootCmd = &cobra.Command{ client.DeleteAllRequests() } + if viper.GetBool("delete-request") { + client.DeleteRequest(recipientID) + } + msg := message.Send{ Recipient: recipientID, Payload: []byte(msgBody), @@ -1110,6 +1114,12 @@ func init() { viper.BindPFlag("delete-all-requests", rootCmd.PersistentFlags().Lookup("delete-all-requests")) + rootCmd.PersistentFlags().Bool("delete-request", false, + "Delete the request for the specified ID given by the "+ + "destfile flag's contact file.") + viper.BindPFlag("delete-request", + rootCmd.PersistentFlags().Lookup("delete-request")) + rootCmd.Flags().BoolP("send-auth-request", "", false, "Send an auth request to the specified destination and wait"+ "for confirmation") diff --git a/storage/auth/store.go b/storage/auth/store.go index 069b828dbd663aa7e2fb658612041d70d5888b81..f0a48c6d7dd1c80b19d6c11aac046bb4da9a209d 100644 --- a/storage/auth/store.go +++ b/storage/auth/store.go @@ -479,6 +479,36 @@ func (s *Store) DeleteAllRequests() error { return nil } +// DeleteRequest deletes a request from Store given a partner ID. +// If the partner ID exists as a request, then the request will be deleted +// and the state stored. If the partner does not exist, then an error will +// be returned. +func (s *Store) DeleteRequest(partnerId *id.ID) error { + s.mux.Lock() + defer s.mux.Unlock() + + req, ok := s.requests[*partnerId] + if !ok { + return errors.Errorf("Request for %s does not exist", partnerId) + } + + switch req.rt { + case Sent: + s.deleteSentRequest(req) + case Receive: + s.deleteReceiveRequest(req) + } + + delete(s.requests, *partnerId) + + if err := s.save(); err != nil { + jww.FATAL.Panicf("Failed to store updated request map after "+ + "deleting receive request for partner %s: %+v", partnerId, err) + } + + return nil +} + // DeleteSentRequests deletes all Sent requests from Store. func (s *Store) DeleteSentRequests() error { s.mux.Lock() diff --git a/storage/auth/store_test.go b/storage/auth/store_test.go index 1fc808235b9d48c1c9b59027a32de86feabd535b..2963efc611c16360a0aaa0d8411f6ed448ac9acc 100644 --- a/storage/auth/store_test.go +++ b/storage/auth/store_test.go @@ -908,6 +908,28 @@ func TestStore_GetAllReceived_MixSentReceived(t *testing.T) { } +// Error case: Call DeleteRequest on a request that does +// not exist. +func TestStore_DeleteRequest_NonexistantRequest(t *testing.T) { + s, _, _ := makeTestStore(t) + c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)} + rng := csprng.NewSystemRNG() + _, sidhPubKey := genSidhAKeys(rng) + if err := s.AddReceived(c, sidhPubKey); err != nil { + t.Fatalf("AddReceived() returned an error: %+v", err) + } + if _, _, err := s.GetReceivedRequest(c.ID); err != nil { + t.Fatalf("GetReceivedRequest() returned an error: %+v", err) + } + + err := s.DeleteRequest(c.ID) + if err != nil { + t.Errorf("DeleteRequest should return an error " + + "when trying to delete a receive request") + } + +} + // Unit test. func TestStore_DeleteReceiveRequests(t *testing.T) { s, _, _ := makeTestStore(t)