gnunet-svn
[Top][All Lists]
Advanced

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

[taldir] 01/02: more error handling


From: gnunet
Subject: [taldir] 01/02: more error handling
Date: Thu, 23 Jan 2025 13:56:48 +0100

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

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

commit cd47ac4772a7739a21da47890775e5e469fad360
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Thu Jan 23 13:56:18 2025 +0100

    more error handling
---
 locales/de-DE/taldir.yml         |   1 +
 locales/en-US/taldir.yml         |   1 +
 pkg/rest/taldir.go               | 526 ++++++++++++++++++++-------------------
 web/templates/landing_email.html |   4 +-
 4 files changed, 271 insertions(+), 261 deletions(-)

diff --git a/locales/de-DE/taldir.yml b/locales/de-DE/taldir.yml
index 6f83e19..e727541 100644
--- a/locales/de-DE/taldir.yml
+++ b/locales/de-DE/taldir.yml
@@ -10,6 +10,7 @@ notYetLinked: "`%s` ist noch nicht mit einer 
Bezahlsystemadresse verlinkt. Du ka
 isLinked: "`%s` ist bereits mit einer Bezahlsystemadresse verlinkt"
 paymentSystemAddress: "Bezahlsystemadresse"
 linkIt: "Verlinken"
+aliasInvalid: "Alias '%s´ ist ungültig."
 lookup: "Suchen"
 lookupEmail: "E-Mail-Adresse nachschlagen"
 lookupEmailDescription: "Gib eine E-Mail-Adresse (z.B. `jdoe@example.com`) ein 
um die dazugehörige Bezahlsystemadresse nachzuschlagen. Wenn diese noch nicht 
verlinkt ist, und das Alias unter Dir gehört, hast du dann die Chance dieses 
mit einer Bazahlsystemadresse zu verlinken."
diff --git a/locales/en-US/taldir.yml b/locales/en-US/taldir.yml
index 7571397..b500d74 100644
--- a/locales/en-US/taldir.yml
+++ b/locales/en-US/taldir.yml
@@ -10,6 +10,7 @@ notYetLinked: "`%s` is not yet linked with any Payment System 
Address. You may u
 isLinked: "`%s` is linked with a Payment System Address"
 paymentSystemAddress: "Payment System Address"
 linkIt: "Link it"
+aliasInvalid: "Alias '%s´ is invalid."
 lookup: "Lookup"
 lookupEmail: "Lookup Email address"
 lookupEmailDescription: "Enter an email address (e.g. `jdoe@example.com`) to 
look up the associated Payment System Address. If it is still unlinked and 
under your control you will be given the option to link it with a Payment 
System Address after lookup."
diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go
index 52176fa..8c32b75 100644
--- a/pkg/rest/taldir.go
+++ b/pkg/rest/taldir.go
@@ -671,302 +671,310 @@ func (t *Taldir) validationPage(w http.ResponseWriter, 
r *http.Request) {
                        "version": t.Version,
                        "QRCode":     template.URL("data:image/png;base64," + 
encodedPng),
                        "WalletLink": template.URL(walletLink),
-               }
-               t.ValidationTpl.Execute(w, fullData)
-       } else {
-               expectedSolution := util.GenerateSolution(validation.TargetUri, 
validation.Challenge)
-               fullData := map[string]interface{}{
-                       "version": t.Version,
-                       "error": r.URL.Query().Get("error"),
-                       "target_uri": template.URL(validation.TargetUri),
-                       "address": template.URL(address),
-                       "haddress": template.URL(validation.HAddress),
-                       "solution": template.URL(expectedSolution),
-                       "tr": t.I18n.GetLocale(r).GetMessage,
-               }
-               t.ValidationTpl.Execute(w, fullData)
-       }
-       return
+      "productDisclaimer": 
template.HTML(t.I18n.GetLocale(r).GetMessage("productDisclaimer")),
+    }
+    t.ValidationTpl.Execute(w, fullData)
+  } else {
+    expectedSolution := util.GenerateSolution(validation.TargetUri, 
validation.Challenge)
+    fullData := map[string]interface{}{
+      "version": t.Version,
+      "error": r.URL.Query().Get("error"),
+      "target_uri": template.URL(validation.TargetUri),
+      "address": template.URL(address),
+      "haddress": template.URL(validation.HAddress),
+      "solution": template.URL(expectedSolution),
+      "productDisclaimer": 
template.HTML(t.I18n.GetLocale(r).GetMessage("productDisclaimer")),
+      "tr": t.I18n.GetLocale(r).GetMessage,
+    }
+    t.ValidationTpl.Execute(w, fullData)
+  }
+  return
 }
 
 // ClearDatabase nukes the database (for tests)
 func (t *Taldir) ClearDatabase() {
-       t.Db.Where("1 = 1").Delete(&entry{})
-       t.Db.Where("1 = 1").Delete(&validation{})
+  t.Db.Where("1 = 1").Delete(&entry{})
+  t.Db.Where("1 = 1").Delete(&validation{})
 }
 
 func (t *Taldir) termsResponse(w http.ResponseWriter, r *http.Request) {
-       tos.ServiceTermsResponse(t.Cfg.Section("taldir"), w, r)
+  tos.ServiceTermsResponse(t.Cfg.Section("taldir"), w, r)
 }
 
 func (t *Taldir) privacyResponse(w http.ResponseWriter, r *http.Request) {
-       tos.PrivacyPolicyResponse(t.Cfg.Section("taldir"), w, r)
+  tos.PrivacyPolicyResponse(t.Cfg.Section("taldir"), w, r)
 }
 
 func (t *Taldir) landingPage(w http.ResponseWriter, r *http.Request) {
-       w.Header().Set("Content-Type", "text/html; charset=utf-8")
-       translateFunc := t.I18n.GetLocale(r).GetMessage
-       fullData := map[string]interface{}{
-               "validators": t.Validators,
-               "version": t.Version,
+  w.Header().Set("Content-Type", "text/html; charset=utf-8")
+  translateFunc := t.I18n.GetLocale(r).GetMessage
+  fullData := map[string]interface{}{
+    "validators": t.Validators,
+    "version": t.Version,
     "lookupOrRegisterCardTitle": 
template.HTML(translateFunc("lookupOrRegister")),
     "selectAliasToLookupOrLinkCardText": 
template.HTML(translateFunc("selectAliasToLookupOrLink")),
     "productDisclaimer": template.HTML(translateFunc("productDisclaimer")),
-               "error": r.URL.Query().Get("error"),
-               "tr": translateFunc,
-       }
-       err := t.LandingPageTpl.Execute(w, fullData)
-       if err != nil {
-               fmt.Println(err)
-       }
-       return
+    "error": translateFunc(r.URL.Query().Get("error")),
+    "tr": translateFunc,
+  }
+  err := t.LandingPageTpl.Execute(w, fullData)
+  if err != nil {
+    fmt.Println(err)
+  }
+  return
 }
 
 func (t *Taldir) methodLookupResultPage(w http.ResponseWriter, r 
*http.Request) {
-       var entry entry
-       vars := mux.Vars(r)
-       w.Header().Set("Content-Type", "text/html; charset=utf-8")
-
-       // Check if this validation method is supported or not.
-       val, ok := t.Validators[vars["method"]]
-       if !ok {
-               w.WriteHeader(404)
-               return
-       }
-
-       // Check if alias is valid
-       alias := r.URL.Query().Get("address")
-       err := val.isAliasValid(alias)
-       if nil != err {
-               http.Redirect(w, r, fmt.Sprintf("/?error=%s", err), 
http.StatusSeeOther)
-               return
-       }
-       hAddressBin := sha512.Sum512([]byte(r.URL.Query().Get("address")))
-       hAddress := gnunetutil.EncodeBinaryToString(hAddressBin[:])
-       hsAddress := saltHAddress(hAddress, t.Salt)
-       found := false
-       err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
-       if err != nil {
-               log.Printf("`%s` not found.\n", hAddress)
-       } else {
-               found = true
-       }
-       fullData := map[string]interface{}{
-               "version": t.Version,
-               "available": !found,
-               "method": val.Name,
-               "address": r.URL.Query().Get("address"),
-               "result": entry.TargetUri,
-               "error": r.URL.Query().Get("error"),
-               "tr": t.I18n.GetLocale(r).GetMessage,
-       }
-       err = t.LookupResultPageTpl.Execute(w, fullData)
-       if err != nil {
-               fmt.Println(err)
-       }
-       return
+  var entry entry
+  vars := mux.Vars(r)
+  w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+  // Check if this validation method is supported or not.
+  val, ok := t.Validators[vars["method"]]
+  if !ok {
+    w.WriteHeader(404)
+    return
+  }
+
+  // Check if alias is valid
+  alias := r.URL.Query().Get("address")
+  err := val.isAliasValid(alias)
+  emsg := ""
+  found := false
+  if nil != err {
+    log.Printf("Not a valid alias\n")
+    emsg = t.I18n.GetLocale(r).GetMessage("aliasInvalid", alias)
+    http.Redirect(w, r, fmt.Sprintf("/landing/" + val.Name + "?error=%s", 
emsg), http.StatusSeeOther)
+    return
+  } else {
+    hAddressBin := sha512.Sum512([]byte(r.URL.Query().Get("address")))
+    hAddress := gnunetutil.EncodeBinaryToString(hAddressBin[:])
+    hsAddress := saltHAddress(hAddress, t.Salt)
+    err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
+    if err != nil {
+      log.Printf("`%s` not found.\n", hAddress)
+    } else {
+      found = true
+    }
+  }
+  fullData := map[string]interface{}{
+    "version": t.Version,
+    "available": !found,
+    "method": val.Name,
+    "address": r.URL.Query().Get("address"),
+    "result": entry.TargetUri,
+    "error": emsg,
+    "productDisclaimer": 
template.HTML(t.I18n.GetLocale(r).GetMessage("productDisclaimer")),
+    "tr": t.I18n.GetLocale(r).GetMessage,
+  }
+  err = t.LookupResultPageTpl.Execute(w, fullData)
+  if err != nil {
+    fmt.Println(err)
+  }
+  return
 }
 
 func (t *Taldir) methodLandingPage(w http.ResponseWriter, r *http.Request) {
-       vars := mux.Vars(r)
-       w.Header().Set("Content-Type", "text/html; charset=utf-8")
-
-       // Check if this validation method is supported or not.
-       val, ok := t.Validators[vars["method"]]
-       if !ok {
-               w.WriteHeader(404)
-               return
-       }
-       fullData := map[string]interface{}{
-               "version": t.Version,
-               "error": r.URL.Query().Get("error"),
-               "tr": t.I18n.GetLocale(r).GetMessage,
-       }
-       err := val.LandingPageTpl.Execute(w, fullData)
-       if err != nil {
-               fmt.Println(err)
-       }
-       return
+  vars := mux.Vars(r)
+  w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+  // Check if this validation method is supported or not.
+  val, ok := t.Validators[vars["method"]]
+  if !ok {
+    w.WriteHeader(404)
+    return
+  }
+  fullData := map[string]interface{}{
+    "version": t.Version,
+    "error": r.URL.Query().Get("error"),
+    "productDisclaimer": 
template.HTML(t.I18n.GetLocale(r).GetMessage("productDisclaimer")),
+    "tr": t.I18n.GetLocale(r).GetMessage,
+  }
+  err := val.LandingPageTpl.Execute(w, fullData)
+  if err != nil {
+    fmt.Println(err)
+  }
+  return
 }
 
 func (t *Taldir) setupHandlers() {
-       t.Router = mux.NewRouter().StrictSlash(true)
+  t.Router = mux.NewRouter().StrictSlash(true)
 
-       /* ToS API */
-       t.Router.HandleFunc("/terms", t.termsResponse).Methods("GET")
-       t.Router.HandleFunc("/privacy", t.privacyResponse).Methods("GET")
+  /* ToS API */
+  t.Router.HandleFunc("/terms", t.termsResponse).Methods("GET")
+  t.Router.HandleFunc("/privacy", t.privacyResponse).Methods("GET")
 
-       /* Config API */
-       t.Router.HandleFunc("/config", t.configResponse).Methods("GET")
+  /* Config API */
+  t.Router.HandleFunc("/config", t.configResponse).Methods("GET")
 
-       /* Assets HTML */
-       t.Router.PathPrefix("/css").Handler(http.StripPrefix("/css", 
http.FileServer(http.Dir("./static/css"))))
-       
t.Router.PathPrefix("/fontawesome").Handler(http.StripPrefix("/fontawesome", 
http.FileServer(http.Dir("./static/fontawesome"))))
+  /* Assets HTML */
+  t.Router.PathPrefix("/css").Handler(http.StripPrefix("/css", 
http.FileServer(http.Dir("./static/css"))))
+  t.Router.PathPrefix("/fontawesome").Handler(http.StripPrefix("/fontawesome", 
http.FileServer(http.Dir("./static/fontawesome"))))
 
-       /* Registration API */
-       t.Router.HandleFunc("/", t.landingPage).Methods("GET")
-       t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET")
-       t.Router.HandleFunc("/lookup/{method}", 
t.methodLookupResultPage).Methods("GET")
-       t.Router.HandleFunc("/landing/{method}", 
t.methodLandingPage).Methods("GET")
-       t.Router.HandleFunc("/register/{method}", 
t.registerRequest).Methods("POST")
-       t.Router.HandleFunc("/register/{h_address}/{challenge}", 
t.validationPage).Methods("GET")
-       t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST")
+  /* Registration API */
+  t.Router.HandleFunc("/", t.landingPage).Methods("GET")
+  t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET")
+  t.Router.HandleFunc("/lookup/{method}", 
t.methodLookupResultPage).Methods("GET")
+  t.Router.HandleFunc("/landing/{method}", t.methodLandingPage).Methods("GET")
+  t.Router.HandleFunc("/register/{method}", t.registerRequest).Methods("POST")
+  t.Router.HandleFunc("/register/{h_address}/{challenge}", 
t.validationPage).Methods("GET")
+  t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST")
 
 }
 
 var pluralizeClient = pluralize.NewClient()
 
 func getFuncs(current *i18n.Locale) template.FuncMap {
-       return template.FuncMap{
-               "plural": func(word string, count int) string {
-                       return pluralizeClient.Pluralize(word, count, true)
-               },
-       }
+  return template.FuncMap{
+    "plural": func(word string, count int) string {
+      return pluralizeClient.Pluralize(word, count, true)
+    },
+  }
 }
 
 // Initialize the Taldir instance with cfgfile
 func (t *Taldir) Initialize(cfgfile string, version string) {
-       _cfg, err := ini.LooseLoad(cfgfile)
-       if err != nil {
-               log.Fatalf("Failed to read config: %v", err)
-               os.Exit(1)
-       }
-       t.Cfg = _cfg
-       t.I18n, err = i18n.New(i18n.Glob("./locales/*/*", i18n.LoaderConfig{
-               // Set custom functions per locale!
-               Funcs: getFuncs,
-       }), "en-US", "de-DE")
-       if err != nil {
-               panic(err)
-       }
-       if t.Cfg.Section("taldir").Key("production").MustBool(false) {
-               fmt.Println("Production mode enabled")
-       }
-
-       navTplFile := 
t.Cfg.Section("taldir").Key("navigation").MustString("web/templates/nav.html")
-       footerTplFile := 
t.Cfg.Section("taldir").Key("footer").MustString("web/templates/footer.html")
-       t.Version = version
-       t.BaseUrl = 
t.Cfg.Section("taldir").Key("base_url").MustString("http://localhost:11000";)
-       t.Validators = make(map[string]Validator)
-       for _, sec := range t.Cfg.Sections() {
-               if !strings.HasPrefix(sec.Name(), "taldir-validator-") {
-                       continue
-               }
-               if !sec.HasKey("type") {
-                       log.Printf("`type` key in section `[%s]` not found, 
disabling validator.\n", sec.Name())
-                       continue
-               }
-               vname := strings.TrimPrefix(sec.Name(), "taldir-validator-")
-               vlandingPageTplFile := 
sec.Key("registration_page").MustString("web/templates/landing_" + vname + 
".html")
-               vlandingPageTpl, err := 
template.ParseFiles(vlandingPageTplFile, navTplFile, footerTplFile)
-               if err != nil {
-                       log.Printf("`%s` template not found, disabling 
validator `%s`.\n", vlandingPageTplFile, vname)
-                       continue
-               }
-               t.Validators[vname] = Validator{
-                       Name: vname,
-                       LandingPageTpl: vlandingPageTpl,
-                       ChallengeFee: 
sec.Key("challenge_fee").MustString("KUDOS:0"),
-                       PaymentRequired: sec.Key("enabled").MustBool(false),
-                       Command: sec.Key("command").MustString(""),
-                       Type: ValidatorType(sec.Key("type").MustString("")),
-                               ValidAliasRegex: 
sec.Key("valid_alias_regex").MustString(""),
-               }
-       }
-       t.ChallengeBytes = 
t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16)
-       t.ValidationInitiationMax = 
t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt64(3)
-       t.SolutionAttemptsMax = 
t.Cfg.Section("taldir").Key("solution_attempt_max").MustInt(3)
-
-       validationTTLStr := 
t.Cfg.Section("taldir").Key("validation_timeframe").MustString("5m")
-       t.ValidPMSRegex = 
t.Cfg.Section("taldir").Key("valid_payment_system_address_regex").MustString("[A-Z]+")
-       t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-
-       retryTimeframeStr := 
t.Cfg.Section("taldir").Key("solution_attempt_timeframe").MustString("1h")
-       t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-       t.MonthlyFee = 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:0")
-
-       psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s 
sslmode=disable",
-       t.Cfg.Section("taldir-pq").Key("host").MustString("localhost"),
-       t.Cfg.Section("taldir-pq").Key("port").MustInt64(5432),
-       t.Cfg.Section("taldir-pq").Key("user").MustString("taldir"),
-       t.Cfg.Section("taldir-pq").Key("password").MustString("secret"),
-       t.Cfg.Section("taldir-pq").Key("db_name").MustString("taldir"))
-       _db, err := gorm.Open(postgres.Open(psqlconn), &gorm.Config{
-               Logger: logger.Default.LogMode(logger.Silent),
-       })
-       if err != nil {
-               panic(err)
-       }
-       t.Db = _db
-       if err := t.Db.AutoMigrate(&entry{}); err != nil {
-               panic(err)
-       }
-       if err := t.Db.AutoMigrate(&validation{}); err != nil {
-               panic(err)
-       }
-       if 
t.Cfg.Section("taldir").Key("purge_mappings_on_startup_dangerous").MustBool(false)
 {
-               log.Println("DANGER Purging mappings!")
-               tx := t.Db.Where("1 = 1").Delete(&entry{})
-               log.Printf("Deleted %d entries.\n", tx.RowsAffected)
-       }
-       // Clean up validations
-       validationExpStr := 
t.Cfg.Section("taldir").Key("validation_expiration").MustString("24h")
-       validationExp, err := time.ParseDuration(validationExpStr)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-       go func() {
-               for true {
-                       tx := t.Db.Where("created_at < ?", 
time.Now().Add(-validationExp)).Delete(&validation{})
-                       log.Printf("Cleaned up %d stale validations.\n", 
tx.RowsAffected)
-                       time.Sleep(validationExp)
-               }
-       }()
-       validationLandingTplFile := 
t.Cfg.Section("taldir").Key("validation_landing").MustString("web/templates/validation_landing.html")
-       t.ValidationTpl, err = template.ParseFiles(validationLandingTplFile, 
navTplFile, footerTplFile)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-       landingTplFile := 
t.Cfg.Section("taldir").Key("landing_page").MustString("web/templates/landing.html")
-       t.LandingPageTpl, err = template.ParseFiles(landingTplFile, navTplFile, 
footerTplFile)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-       lookupResultTplFile := 
t.Cfg.Section("taldir").Key("lookup_result_page").MustString("web/templates/lookup_result.html")
-       t.LookupResultPageTpl, err = template.ParseFiles(lookupResultTplFile, 
navTplFile, footerTplFile)
-       if err != nil {
-               log.Fatal(err)
-               os.Exit(1)
-       }
-       t.Salt = os.Getenv("TALDIR_SALT")
-       if "" == t.Salt {
-               t.Salt = 
t.Cfg.Section("taldir").Key("salt").MustString("ChangeMe")
-       }
-       //merchURL := 
t.Cfg.Section("taldir").Key("merchant_base_url").MustString("http://merchant.taldir/";)
-       //merchToken := 
t.Cfg.Section("taldir").Key("merchant_token").MustString("secretAccessToken")
-       //t.Merchant = merchant.NewMerchant(merchURL, merchToken)
-       //merchConfig, err := t.Merchant.GetConfig()
-       //if nil != err {
-       //      log.Fatal("Failed to get merchant config")
-       //      os.Exit(1)
-       //}
-       //registrationCost, _ := talerutil.ParseAmount(t.MonthlyFee)
-       //currencySpec, currencySupported := 
merchConfig.Currencies[registrationCost.Currency]
-       //for !currencySupported {
-       //      log.Fatalf("Currency `%s' not supported by merchant!\n", 
registrationCost.Currency)
-       //      os.Exit(1)
-       //}
-       //t.CurrencySpec = currencySpec
-       t.setupHandlers()
+  _cfg, err := ini.LooseLoad(cfgfile)
+  if err != nil {
+    log.Fatalf("Failed to read config: %v", err)
+    os.Exit(1)
+  }
+  t.Cfg = _cfg
+  t.I18n, err = i18n.New(i18n.Glob("./locales/*/*", i18n.LoaderConfig{
+    // Set custom functions per locale!
+    Funcs: getFuncs,
+  }), "en-US", "de-DE")
+  if err != nil {
+    panic(err)
+  }
+  if t.Cfg.Section("taldir").Key("production").MustBool(false) {
+    fmt.Println("Production mode enabled")
+  }
+
+  navTplFile := 
t.Cfg.Section("taldir").Key("navigation").MustString("web/templates/nav.html")
+  footerTplFile := 
t.Cfg.Section("taldir").Key("footer").MustString("web/templates/footer.html")
+  t.Version = version
+  t.BaseUrl = 
t.Cfg.Section("taldir").Key("base_url").MustString("http://localhost:11000";)
+  t.Validators = make(map[string]Validator)
+  for _, sec := range t.Cfg.Sections() {
+    if !strings.HasPrefix(sec.Name(), "taldir-validator-") {
+      continue
+    }
+    if !sec.HasKey("type") {
+      log.Printf("`type` key in section `[%s]` not found, disabling 
validator.\n", sec.Name())
+      continue
+    }
+    vname := strings.TrimPrefix(sec.Name(), "taldir-validator-")
+    vlandingPageTplFile := 
sec.Key("registration_page").MustString("web/templates/landing_" + vname + 
".html")
+    vlandingPageTpl, err := template.ParseFiles(vlandingPageTplFile, 
navTplFile, footerTplFile)
+    if err != nil {
+      log.Printf("`%s` template not found, disabling validator `%s`.\n", 
vlandingPageTplFile, vname)
+      continue
+    }
+    t.Validators[vname] = Validator{
+      Name: vname,
+      LandingPageTpl: vlandingPageTpl,
+      ChallengeFee: sec.Key("challenge_fee").MustString("KUDOS:0"),
+      PaymentRequired: sec.Key("enabled").MustBool(false),
+      Command: sec.Key("command").MustString(""),
+      Type: ValidatorType(sec.Key("type").MustString("")),
+      ValidAliasRegex: sec.Key("valid_alias_regex").MustString(""),
+    }
+  }
+  t.ChallengeBytes = t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16)
+  t.ValidationInitiationMax = 
t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt64(3)
+  t.SolutionAttemptsMax = 
t.Cfg.Section("taldir").Key("solution_attempt_max").MustInt(3)
+
+  validationTTLStr := 
t.Cfg.Section("taldir").Key("validation_timeframe").MustString("5m")
+  t.ValidPMSRegex = 
t.Cfg.Section("taldir").Key("valid_payment_system_address_regex").MustString("[A-Z]+")
+  t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+
+  retryTimeframeStr := 
t.Cfg.Section("taldir").Key("solution_attempt_timeframe").MustString("1h")
+  t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+  t.MonthlyFee = 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:0")
+
+  psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s 
sslmode=disable",
+  t.Cfg.Section("taldir-pq").Key("host").MustString("localhost"),
+  t.Cfg.Section("taldir-pq").Key("port").MustInt64(5432),
+  t.Cfg.Section("taldir-pq").Key("user").MustString("taldir"),
+  t.Cfg.Section("taldir-pq").Key("password").MustString("secret"),
+  t.Cfg.Section("taldir-pq").Key("db_name").MustString("taldir"))
+  _db, err := gorm.Open(postgres.Open(psqlconn), &gorm.Config{
+    Logger: logger.Default.LogMode(logger.Silent),
+  })
+  if err != nil {
+    panic(err)
+  }
+  t.Db = _db
+  if err := t.Db.AutoMigrate(&entry{}); err != nil {
+    panic(err)
+  }
+  if err := t.Db.AutoMigrate(&validation{}); err != nil {
+    panic(err)
+  }
+  if 
t.Cfg.Section("taldir").Key("purge_mappings_on_startup_dangerous").MustBool(false)
 {
+    log.Println("DANGER Purging mappings!")
+    tx := t.Db.Where("1 = 1").Delete(&entry{})
+    log.Printf("Deleted %d entries.\n", tx.RowsAffected)
+  }
+  // Clean up validations
+  validationExpStr := 
t.Cfg.Section("taldir").Key("validation_expiration").MustString("24h")
+  validationExp, err := time.ParseDuration(validationExpStr)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+  go func() {
+    for true {
+      tx := t.Db.Where("created_at < ?", 
time.Now().Add(-validationExp)).Delete(&validation{})
+      log.Printf("Cleaned up %d stale validations.\n", tx.RowsAffected)
+      time.Sleep(validationExp)
+    }
+  }()
+  validationLandingTplFile := 
t.Cfg.Section("taldir").Key("validation_landing").MustString("web/templates/validation_landing.html")
+  t.ValidationTpl, err = template.ParseFiles(validationLandingTplFile, 
navTplFile, footerTplFile)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+  landingTplFile := 
t.Cfg.Section("taldir").Key("landing_page").MustString("web/templates/landing.html")
+  t.LandingPageTpl, err = template.ParseFiles(landingTplFile, navTplFile, 
footerTplFile)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+  lookupResultTplFile := 
t.Cfg.Section("taldir").Key("lookup_result_page").MustString("web/templates/lookup_result.html")
+  t.LookupResultPageTpl, err = template.ParseFiles(lookupResultTplFile, 
navTplFile, footerTplFile)
+  if err != nil {
+    log.Fatal(err)
+    os.Exit(1)
+  }
+  t.Salt = os.Getenv("TALDIR_SALT")
+  if "" == t.Salt {
+    t.Salt = t.Cfg.Section("taldir").Key("salt").MustString("ChangeMe")
+  }
+  //merchURL := 
t.Cfg.Section("taldir").Key("merchant_base_url").MustString("http://merchant.taldir/";)
+  //merchToken := 
t.Cfg.Section("taldir").Key("merchant_token").MustString("secretAccessToken")
+  //t.Merchant = merchant.NewMerchant(merchURL, merchToken)
+  //merchConfig, err := t.Merchant.GetConfig()
+  //if nil != err {
+  //   log.Fatal("Failed to get merchant config")
+  //   os.Exit(1)
+  //}
+  //registrationCost, _ := talerutil.ParseAmount(t.MonthlyFee)
+  //currencySpec, currencySupported := 
merchConfig.Currencies[registrationCost.Currency]
+  //for !currencySupported {
+  //   log.Fatalf("Currency `%s' not supported by merchant!\n", 
registrationCost.Currency)
+  //   os.Exit(1)
+  //}
+  //t.CurrencySpec = currencySpec
+  t.setupHandlers()
 }
diff --git a/web/templates/landing_email.html b/web/templates/landing_email.html
index 26b92e2..efd752a 100644
--- a/web/templates/landing_email.html
+++ b/web/templates/landing_email.html
@@ -15,9 +15,9 @@
       {{if .error}}
       <div class="container pt-5">
         <div id="ebanner" class="alert alert-danger" role="alert">
-          <h4 class="alert-heading">An error occured!</h4>
+          <h4 class="alert-heading">Error</h4>
           <hr>
-          <p class="mb-0">{{.error}}.</p>
+          <p class="mb-0">{{.error}}</p>
         </div>
       </div>
       {{end}}

-- 
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]