summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-07-20 13:11:59 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2022-07-20 13:11:59 +0200
commitbec18e5abf34fbaef97aec8372934a27bdc15e7f (patch)
tree93380ecc5012634e7b7374d42fe21d8934228bd6
parent605fbe46f447e2c12694cb0c230df704d88c36b4 (diff)
downloadtaler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.tar.gz
taler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.tar.bz2
taler-mailbox-bec18e5abf34fbaef97aec8372934a27bdc15e7f.zip
delete API
-rw-r--r--pkg/rest/mailbox.go94
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