taler-mailbox

Service for asynchronous wallet-to-wallet payment messages
Log | Files | Refs | Submodules | README | LICENSE

commit 7ab2ebec5062e1387486eafdb221bb69e590f5bb
parent 6556849263efcebad73eb5d9c8e7b3a3a1112af0
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Wed, 23 Apr 2025 07:37:44 +0200

make simple freee post and get work

Diffstat:
Mpkg/rest/mailbox.go | 105+++++++++++++++++++++++++++++++++++++------------------------------------------
1 file changed, 49 insertions(+), 56 deletions(-)

diff --git a/pkg/rest/mailbox.go b/pkg/rest/mailbox.go @@ -25,6 +25,7 @@ import ( "encoding/binary" "encoding/json" "fmt" + "io" "log" "net/http" "os" @@ -34,13 +35,13 @@ import ( gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util" "github.com/gorilla/mux" + "github.com/schanzen/taler-go/pkg/merchant" + tos "github.com/schanzen/taler-go/pkg/rest" + talerutil "github.com/schanzen/taler-go/pkg/util" "gopkg.in/ini.v1" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" - "github.com/schanzen/taler-go/pkg/merchant" - tos "github.com/schanzen/taler-go/pkg/rest" - talerutil "github.com/schanzen/taler-go/pkg/util" ) type TalerMailboxBoxySize int @@ -65,6 +66,9 @@ type Mailbox struct { // Base URL BaseUrl string + + // MessageFee for sending message + MessageFee *talerutil.Amount } // VersionResponse is the JSON response of the /config enpoint @@ -122,9 +126,6 @@ type InboxEntry struct { // ORM gorm.Model `json:"-"` - // and only used once (ephemeral). - EphemeralKey string `json:"ephemeral_key"` - // Encrypted message. Must be exactly 256-32 bytes long. Body []byte @@ -134,8 +135,6 @@ type InboxEntry struct { // Order ID OrderID string - // Read flag - Read bool } func (m *Mailbox) configResponse(w http.ResponseWriter, r *http.Request) { @@ -149,7 +148,7 @@ func (m *Mailbox) configResponse(w http.ResponseWriter, r *http.Request) { Version: "0:0:0", Name: "taler-mailbox", MessageBodyBytes: m.MessageBodyBytes, - MessageFee: m.Cfg.Section("mailbox").Key("message_fee").MustString("KUDOS:1"), + MessageFee: m.MessageFee.String(), DeliveryPeriod: uint64(dp.Microseconds()), } w.Header().Set("Content-Type", "application/json") @@ -164,8 +163,9 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) { // FIXME rate limit // FIXME timeout // FIXME possibly limit results here - err := m.Db.Where("h_mailbox = ? AND read = ?", vars["h_mailbox"], false).Find(&entries).Error + err := m.Db.Where("h_mailbox = ?", vars["h_mailbox"]).Find(&entries).Error if err != nil { + log.Printf("%v", err) w.WriteHeader(http.StatusInternalServerError) return } @@ -177,32 +177,26 @@ func (m *Mailbox) getMessagesResponse(w http.ResponseWriter, r *http.Request) { etag := entries[0].ID w.Header().Add("ETag", fmt.Sprintf("%d", etag)) for _, entry := range entries { - eph, err := gnunetutil.DecodeStringToBinary(entry.EphemeralKey, 32) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - w.Write(eph) w.Write(entry.Body) } - w.WriteHeader(http.StatusOK) } func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var entry InboxEntry - var body = make([]byte, m.MessageBodyBytes) + //var body = make([]byte, m.MessageBodyBytes) if r.Body == nil { - http.Error(w, "No request body", 400) + http.Error(w, "No request body", http.StatusBadRequest) return } if r.ContentLength != m.MessageBodyBytes { - w.WriteHeader(http.StatusBadRequest) + http.Error(w, "Wrong message size", http.StatusBadRequest) return } - _, err := r.Body.Read(body) + body, err := io.ReadAll(r.Body) //.Read(body) if err != nil { - w.WriteHeader(http.StatusBadRequest) + log.Printf("%v", err) + http.Error(w, "Cannot read body", http.StatusBadRequest) return } tx := m.Db.Where("h_mailbox = ?", vars["h_mailbox"]) @@ -213,36 +207,35 @@ func (m *Mailbox) sendMessageResponse(w http.ResponseWriter, r *http.Request) { return } err = m.Db.First(&entry, "h_mailbox = ? AND body = ?", vars["h_mailbox"], body).Error - // FIXME actual cost - cost, _ := talerutil.ParseAmount("KUDOS:1") if err != nil { entry.HMailbox = vars["h_mailbox"] entry.Body = body - entry.Read = false } - if len(entry.OrderID) == 0 { - // Add new order for new entry - orderID, newOrderErr := m.Merchant.AddNewOrder(*cost, "Mailbox message dispatch", m.BaseUrl) - if newOrderErr != nil { - fmt.Println(newOrderErr) + if !m.MessageFee.IsZero() { + if len(entry.OrderID) == 0 { + // Add new order for new entry + orderID, newOrderErr := m.Merchant.AddNewOrder(*m.MessageFee, "Mailbox message dispatch", m.BaseUrl) + if newOrderErr != nil { + fmt.Println(newOrderErr) + w.WriteHeader(http.StatusInternalServerError) + return + } + entry.OrderID = orderID + } + // Check if order paid. + _, _, payto, paytoErr := m.Merchant.IsOrderPaid(entry.OrderID) + if paytoErr != nil { + fmt.Println(paytoErr) w.WriteHeader(http.StatusInternalServerError) + log.Println(paytoErr) + return + } + if len(payto) != 0 { + m.Db.Save(&entry) + w.WriteHeader(http.StatusPaymentRequired) + w.Header().Set("Taler", payto) return } - entry.OrderID = orderID - } - // Check if order paid. - _, _, payto, paytoErr := m.Merchant.IsOrderPaid(entry.OrderID) - if paytoErr != nil { - fmt.Println(paytoErr) - w.WriteHeader(http.StatusInternalServerError) - log.Println(paytoErr) - return - } - if len(payto) != 0 { - m.Db.Save(&entry) - w.WriteHeader(http.StatusPaymentRequired) - w.Header().Set("Taler", payto) - return } // In this case, this order was paid m.Db.Save(&entry) @@ -322,12 +315,6 @@ func (m *Mailbox) deleteMessagesResponse(w http.ResponseWriter, r *http.Request) } h_all := sha512.New() for _, entry := range entries { - eph, err := gnunetutil.DecodeStringToBinary(entry.EphemeralKey, 32) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - h_all.Write(eph) h_all.Write(entry.Body) } if !bytes.Equal(h_all.Sum(nil), checksum) { @@ -375,12 +362,18 @@ func (m *Mailbox) Initialize(cfgfile string) { } m.BaseUrl = m.Cfg.Section("mailbox").Key("base_url").MustString("https://example.com") m.MessageBodyBytes = m.Cfg.Section("mailbox").Key("message_body_bytes").MustInt64(256) + // FIXME actual cost + m.MessageFee, err = talerutil.ParseAmount(m.Cfg.Section("mailbox").Key("message_fee").MustString("KUDOS:1")) + if err != nil { + fmt.Printf("Failed to parse cost: %v", err) + os.Exit(1) + } psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", - m.Cfg.Section("mailbox-pq").Key("host").MustString("localhost"), - m.Cfg.Section("mailbox-pq").Key("port").MustInt64(5432), - m.Cfg.Section("mailbox-pq").Key("user").MustString("taler-mailbox"), - m.Cfg.Section("mailbox-pq").Key("password").MustString("secret"), - m.Cfg.Section("mailbox-pq").Key("db_name").MustString("taler-mailbox")) + m.Cfg.Section("mailbox-pq").Key("host").MustString("localhost"), + m.Cfg.Section("mailbox-pq").Key("port").MustInt64(5432), + m.Cfg.Section("mailbox-pq").Key("user").MustString("taler-mailbox"), + m.Cfg.Section("mailbox-pq").Key("password").MustString("secret"), + m.Cfg.Section("mailbox-pq").Key("db_name").MustString("taler-mailbox")) _db, err := gorm.Open(postgres.Open(psqlconn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), })