gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taldir] 03/03: Enable test runs for registration


From: gnunet
Subject: [taler-taldir] 03/03: Enable test runs for registration
Date: Tue, 05 Jul 2022 12:40:46 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository taldir.

commit 493615f700e38ef7db25b3a0a8a034dc2cc7454d
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Tue Jul 5 12:40:38 2022 +0200

    Enable test runs for registration
---
 taldir.go        | 126 ++++++++++++++++++++++++++++++-------------------------
 test.sh          |  11 +++++
 validate_test.sh |   1 +
 3 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/taldir.go b/taldir.go
index 2b05657..302a1fb 100644
--- a/taldir.go
+++ b/taldir.go
@@ -12,7 +12,6 @@ import (
   "gorm.io/gorm"
   "encoding/base32"
   "math/rand"
-  "net/smtp"
   "crypto/sha512"
   "gorm.io/driver/postgres"
   "gopkg.in/ini.v1"
@@ -32,7 +31,7 @@ type VersionResponse struct {
   Methods []Method `json:"methods"`
 
   // fee for one month of registration
-  Monthly_fee string `json:"monthly_fee"`
+  MonthlyFee string `json:"monthly_fee"`
 
 }
 
@@ -41,7 +40,7 @@ type Method struct {
   Name string `json:"name"`
 
   // per challenge fee
-  Challenge_fee string `json:"challenge_fee"`
+  ChallengeFee string `json:"challenge_fee"`
 
 }
 
@@ -63,7 +62,7 @@ type RegisterMessage struct {
   Address string `json:"address"`
 
   // Public key of the user to register
-  Public_key string `json:"public_key"`
+  PublicKey string `json:"public_key"`
 
   // (HTTPS) endpoint URL for the inbox service for this address
   Inbox string `json:"inbox_url"`
@@ -81,11 +80,12 @@ type RegisterMessage struct {
 // The identity key hash is sha256(sha256(identity)|salt) where identity is
 // one of the identity key types supported (e.g. email)
 type Entry struct {
-  gorm.Model
-  HAddress string `json:"h_address"`
+  gorm.Model  `json:"-"`
+  HsAddress string `json:"-"`
+  Inbox string `json:"inbox_url"`
   PublicKey string `json:"public_key"`
-  RegisteredAt int64 `json:"valid_until"`
-  Duration int64 `json:"duration"`
+  RegisteredAt int64 `json:"-"`
+  Duration int64 `json:"-"`
 }
 
 // A validation is created when a registration for an entry is initiated.
@@ -93,10 +93,12 @@ type Entry struct {
 // validation reference. The validation reference is sent to the identity
 // depending on the out-of-band chennel defined through the identity key type.
 type Validation struct {
-  gorm.Model
+  gorm.Model `json:"-"`
   HAddress string `json:"h_address"`
   Method string `json:"method"`
-  ValidationReference string `json:"reference"`
+  Duration int64 `json:"duration"`
+  Inbox string `json:"inbox_url"`
+  Solution string `json:"solution"`
   PublicKey string `json:"public_key"`
 }
 
@@ -132,10 +134,14 @@ type ErrorDetail struct {
   Currency string `json:"currency,omitempty"`
 
   // Expected type (if applicable).
-  Type_expected string `json:"type_expected,omitempty"`
+  TypeExpected string `json:"type_expected,omitempty"`
 
   // Type that was provided instead (if applicable).
-  Type_actual string `json:"type_actual,omitempty"`
+  TypeActual string `json:"type_actual,omitempty"`
+}
+
+type ValidationConfirmation struct {
+  Solution string `json:"solution"`
 }
 
 // The main DB handle
@@ -147,29 +153,6 @@ var cfg *ini.File
 // Map of supported validators as defined in the configuration
 var validators map[string]bool
 
-// Send an email for email identities 
-func sendEmail(recipient string, ref Validation) {
-
-  from := 
cfg.Section("taldir-email").Key("sender").MustString("taldir@example.com")
-  to := []string{
-    recipient,
-  }
-
-  smtpHost := "localhost"
-  smtpPort := "587"
-
-  message := fmt.Sprintf("Please click here to validate your Taldir identity: 
%s%s",
-  cfg.Section("taldir").Key("host").MustString("http://localhost";),
-  ref.ValidationReference)
-
-  err := smtp.SendMail(smtpHost+":"+smtpPort, nil, from, to, []byte(message))
-  if err != nil {
-    fmt.Println(err)
-    return
-  }
-  fmt.Println("Email Sent Successfully!")
-}
-
 // Primary lookup function.
 // Allows the caller to query a wallet key using the hash(!) of the
 // identity, e.g. sha256(<email address>)
@@ -177,10 +160,12 @@ func getSingleEntry(w http.ResponseWriter, r 
*http.Request){
   vars := mux.Vars(r)
   var entry Entry
   //identityKeyHash := hashIdentityKey(vars["identity_key"])
-  var err = db.First(&entry, "h_address = ?", vars["h_address"]).Error
+  hs_address := saltHAddress(vars["h_address"])
+  var err = db.First(&entry, "hs_address = ?", hs_address).Error
   if err == nil {
     w.Header().Set("Content-Type", "application/json")
-    json.NewEncoder(w).Encode(entry)
+    resp, _ := json.Marshal(entry)
+    w.Write(resp)
     return
   }
   w.WriteHeader(http.StatusNotFound)
@@ -188,14 +173,14 @@ func getSingleEntry(w http.ResponseWriter, r 
*http.Request){
 
 // Hashes an identity key (e.g. sha256(<email address>)) with a salt for
 // Lookup and storage.
-func hashIdentityKey(idkey string) string {
+func saltHAddress(h_address string) string {
   salt := os.Getenv("TALDIR_SALT")
   if "" == salt {
     salt = cfg.Section("taldir").Key("salt").MustString("ChangeMe")
   }
   fmt.Println("Using salt " + salt)
   h := sha512.New()
-  h.Write([]byte(idkey))
+  h.Write([]byte(h_address))
   h.Write([]byte(salt))
   return base32.StdEncoding.EncodeToString(h.Sum(nil))
 }
@@ -206,12 +191,27 @@ func validationRequest(w http.ResponseWriter, r 
*http.Request){
   vars := mux.Vars(r)
   var entry Entry
   var validation Validation
-  err := db.First(&validation, "h_address = ?", vars["h_address"]).Error
+  var confirm ValidationConfirmation
+  var errDetail ErrorDetail
+  if r.Body == nil {
+    http.Error(w, "No request body", 400)
+    return
+  }
+  err := json.NewDecoder(r.Body).Decode(&confirm)
+  if err != nil {
+    errDetail.Code = 1006 //TALER_EC_JSON_INVALID
+    errDetail.Hint = "Unable to parse JSON"
+    resp, _ := json.Marshal(errDetail)
+    w.WriteHeader(400)
+    w.Write(resp)
+    return
+  }
+  err = db.First(&validation, "h_address = ?", vars["h_address"]).Error
   if err != nil {
     w.WriteHeader(http.StatusNotFound)
     return
   }
-  if vars["validation_code"] != validation.ValidationReference {
+  if confirm.Solution != validation.Solution {
     // FIXME how TF do we rate limit here??
     w.WriteHeader(http.StatusForbidden)
     return
@@ -223,19 +223,21 @@ func validationRequest(w http.ResponseWriter, r 
*http.Request){
     return
   }
   // FIXME are we still doing this??
-  //entry.IdentityKeyHash = hashIdentityKey(validation.IdentityKey)
-  entry.HAddress = validation.HAddress
+  entry.HsAddress = saltHAddress(validation.HAddress)
+  entry.Inbox = validation.Inbox
+  entry.Duration = validation.Duration
+  entry.RegisteredAt = time.Now().UnixMicro()
   entry.PublicKey = validation.PublicKey
-  err = db.First(&entry, "h_address = ?", entry.HAddress).Error
+  err = db.First(&entry, "hs_address = ?", entry.HsAddress).Error
   if err == nil {
-    // FIXME is this not in theory possible that we find such an entry??
-    w.WriteHeader(http.StatusConflict)
-    return
-  }
-  err = db.Create(&entry).Error
-  if err != nil {
-    w.WriteHeader(http.StatusInternalServerError)
+    db.Save(&entry)
     return
+  } else {
+    err = db.Create(&entry).Error
+    if err != nil {
+      w.WriteHeader(http.StatusInternalServerError)
+      return
+    }
   }
   w.WriteHeader(http.StatusNoContent)
 }
@@ -284,7 +286,8 @@ func registerRequest(w http.ResponseWriter, r 
*http.Request){
   validation.HAddress = base32.StdEncoding.EncodeToString(h.Sum(nil))
   // We first try if there is already an entry for this address which
   // is still valid and the duration is not extended.
-  err = db.First(&entry, "h_address = ?", validation.HAddress).Error
+  hs_address := saltHAddress(validation.HAddress)
+  err = db.First(&entry, "hs_address = ?", hs_address).Error
   if err != nil {
     lastRegValidity := entry.RegisteredAt + entry.Duration
     requestedValidity := time.Now().UnixMicro() + req.Duration
@@ -316,7 +319,10 @@ func registerRequest(w http.ResponseWriter, r 
*http.Request){
     w.WriteHeader(202)
     return
   } else {
-    validation.ValidationReference = generateToken()
+    validation.Solution = generateToken()
+    validation.Inbox = req.Inbox
+    validation.Duration = req.Duration
+    validation.PublicKey = req.PublicKey
     err = db.Create(&validation).Error
     if err != nil {
       // FIXME: API needs 400 error codes in such cases
@@ -334,7 +340,7 @@ func registerRequest(w http.ResponseWriter, r 
*http.Request){
     return
   }
   command := cfg.Section("taldir-" + vars["method"]).Key("command").String()
-  out, err := exec.Command(command, req.Address, 
validation.ValidationReference).Output()
+  out, err := exec.Command(command, req.Address, validation.Solution).Output()
   if err != nil {
     log.Fatal(err)
     db.Delete(&validation)
@@ -355,14 +361,14 @@ func configResponse(w http.ResponseWriter, r 
*http.Request) {
   for key, _ := range validators {
     var meth Method
     meth.Name = key
-    meth.Challenge_fee = cfg.Section("taldir-" + 
key).Key("challenge_fee").MustString("1 Kudos")
+    meth.ChallengeFee = cfg.Section("taldir-" + 
key).Key("challenge_fee").MustString("1 Kudos")
     i++
     meths = append(meths, meth)
   }
   cfg := VersionResponse{
     Version: "0:0:0",
     Name: "taler-directory",
-    Monthly_fee: cfg.Section("taldir").Key("monthly_fee").MustString("1 
Kudos"),
+    MonthlyFee: cfg.Section("taldir").Key("monthly_fee").MustString("1 Kudos"),
     Methods: meths,
   }
   w.Header().Set("Content-Type", "application/json")
@@ -370,6 +376,11 @@ func configResponse(w http.ResponseWriter, r 
*http.Request) {
   w.Write(response)
 }
 
+func validationPage(w http.ResponseWriter, r *http.Request) {
+  // FIXME provided HTML page here
+  return
+}
+
 func handleRequests() {
   myRouter := mux.NewRouter().StrictSlash(true)
 
@@ -386,7 +397,8 @@ func handleRequests() {
   //myRouter.HandleFunc("/validation/{reference}", 
validateSingleEntry).Methods("GET")
   myRouter.HandleFunc("/{h_address}", getSingleEntry).Methods("GET")
   myRouter.HandleFunc("/register/{method}", registerRequest).Methods("POST")
-  myRouter.HandleFunc("/register/{h_address}/{validation_code}", 
validationRequest).Methods("GET")
+  myRouter.HandleFunc("/register/{h_address}/{validation_code}", 
validationPage).Methods("GET")
+  myRouter.HandleFunc("/{h_address}", validationRequest).Methods("POST")
 
   
log.Fatal(http.ListenAndServe(cfg.Section("taldir").Key("bind_to").MustString("localhost:11000"),
 myRouter))
 }
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..de0e45d
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# New request
+curl -v localhost:11000/register/test --data '{"address": "abc@test", 
"public_key": "pkey", "inbox_url": "myinbox@xyz", "duration": 23}'
+# Read validation code from tempfile
+CODE=`cat validation_code`
+H_ADDRESS=`echo -n abc@test | openssl dgst -binary -sha512 | base32 -w0`
+echo "Code: $CODE; Address: $H_ADDRESS"
+# Validate
+curl -v localhost:11000/$H_ADDRESS --data "{\"solution\": \"${CODE}\"}"
+# Get mapping
+curl -v localhost:11000/$H_ADDRESS
diff --git a/validate_test.sh b/validate_test.sh
index 8a46772..cd1b6e4 100755
--- a/validate_test.sh
+++ b/validate_test.sh
@@ -1,2 +1,3 @@
 #!/bin/bash
 echo $1 $2
+echo $2 > validation_code

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]