diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-07-20 13:11:59 +0200 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-07-20 13:11:59 +0200 |
commit | bec18e5abf34fbaef97aec8372934a27bdc15e7f (patch) | |
tree | 93380ecc5012634e7b7374d42fe21d8934228bd6 | |
parent | 605fbe46f447e2c12694cb0c230df704d88c36b4 (diff) | |
download | taler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.tar.gz taler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.tar.bz2 taler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.zip |
delete API
-rw-r--r-- | pkg/rest/mailbox.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/pkg/rest/mailbox.go b/pkg/rest/mailbox.go index 7526e4b..1299389 100644 --- a/pkg/rest/mailbox.go +++ b/pkg/rest/mailbox.go @@ -19,6 +19,10 @@ package mailbox import ( + "bytes" + "crypto/ed25519" + "crypto/sha512" + "encoding/binary" "encoding/json" "fmt" "log" @@ -83,6 +87,23 @@ type VersionResponse struct { DeliveryPeriod uint64 `josn:"delivery_period"` } +// MessageDeletionRequest is used to request the deletion of already received +// messages from the mailbox. +type MessageDeletionRequest struct { + + // Number of messages to delete. (Starting from the beginning + // of the latest GET response). + Count int + + // SHA-512 hash over all messages to delete. + Checksum string + + // Signature by the mailbox's private key affirming + // the deletion of the messages, of purpuse + // TALER_SIGNATURE_WALLET_MAILBOX_DELETE_MESSAGES. + WalletSig string `json:"wallet_sig"` +} + // MailboxRateLimitedResponse is the JSON response when a rate limit is hit type MailboxRateLimitedResponse struct { @@ -227,6 +248,78 @@ func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) } +func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + var msg MessageDeletionRequest + var entries []inboxEntry + if r.Body == nil { + http.Error(w, "No request body", 400) + return + } + err := json.NewDecoder(r.Body).Decode(&msg) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + pkey, err := gnunetutil.DecodeStringToBinary(vars["mailbox"], 32) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + h := sha512.New() + h.Write(pkey) + h_mailbox := gnunetutil.EncodeBinaryToString(h.Sum(nil)) + err = m.Db.Where("h_mailbox = ? AND read = ? LIMIT ?", h_mailbox, true, msg.Count).Find(&entries).Error + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + if len(entries) < msg.Count { + w.WriteHeader(http.StatusNotFound) + return + } + h_all := sha512.New() + for _, entry := range entries { + eph, err := gnunetutil.DecodeStringToBinary(entry.EphemeralKey, 32) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + body, err := gnunetutil.DecodeStringToBinary(entry.Body, 256-32) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + h_all.Write(eph) + h_all.Write(body) + } + h_all_s := gnunetutil.EncodeBinaryToString(h_all.Sum(nil)) + if h_all_s != msg.Checksum { + w.WriteHeader(http.StatusNotFound) + return + } + pk := ed25519.PublicKey(pkey) + sig, err := gnunetutil.DecodeStringToBinary(msg.WalletSig, 64) + if nil != err { + w.WriteHeader(http.StatusForbidden) + return + } + var signed_msg bytes.Buffer + size := make([]byte, 4) + binary.BigEndian.PutUint32(size, 64+4+4) + purp := make([]byte, 4) + binary.BigEndian.PutUint32(purp, 23) // FIXME purpose + signed_msg.Write(size) + signed_msg.Write(purp) + signed_msg.Write(h_all.Sum(nil)) + if !ed25519.Verify(pk, signed_msg.Bytes(), sig) { + w.WriteHeader(http.StatusForbidden) + return + } + m.Db.Delete(&entries) + w.WriteHeader(http.StatusNoContent) +} + func (m *Mailbox) termsResponse(w http.ResponseWriter, r *http.Request) { tos.ServiceTermsResponse(m.Cfg.Section("mailbox"), w, r) } @@ -248,6 +341,7 @@ func (m *Mailbox) setupHandlers() { /* Mailbox API */ m.Router.HandleFunc("/{h_mailbox}", m.sendMessageResponse).Methods("POST") m.Router.HandleFunc("/{h_mailbox}", m.getMessagesResponse).Methods("GET") + m.Router.HandleFunc("/{h_mailbox}", m.deleteMessagesResponse).Methods("DELETE") } // Initialize the Mailbox instance with cfgfile |