gnunet-gns-registrar

GNU Name System registrar
Log | Files | Refs | README

commit 86fb4f92dd0a6624e3cd7e7f25781c011483c642
parent c72db71ea48e9023b2f2dbb68d1e144a5c729731
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Wed,  6 Dec 2023 12:39:32 +0100

Add registration metadata record. Show expiration time.

Diffstat:
Mpkg/rest/gnsregistrar.go | 80+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mweb/templates/name.html | 2+-
2 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/pkg/rest/gnsregistrar.go b/pkg/rest/gnsregistrar.go @@ -26,12 +26,19 @@ import ( "io" "net/http" "os" + "time" "github.com/gorilla/mux" "gopkg.in/ini.v1" "taler.net/taler-go.git/pkg/merchant" ) + +type RegistrationMetadata struct { + Expiration uint64 `json:"expiration"` + Paid bool `json:"paid"` +} + type IdentityInfo struct { Pubkey string `json:"pubkey"` Name string `json:"name"` @@ -51,6 +58,7 @@ type RecordData struct { IsRelativeExpiration bool `json:"is_relative_expiration"` IsSupplemental bool `json:"is_supplemental"` IsShadow bool `json:"is_shadow"` + IsMaintenance bool `json:"is_maintenance"` } @@ -84,12 +92,14 @@ type Registrar struct { Merchant merchant.Merchant // Relative record expiration (NOT registration expiration!) - RelativeDelegationExpiration uint64 + RelativeDelegationExpiration time.Duration + + // Registration expiration (NOT record expiration!) + RelativeRegistrationExpiration time.Duration // Name of our root zone RootZoneName string - // Key of our root zone RootZoneKey string @@ -140,17 +150,37 @@ func (t *Registrar) registerName(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var namestoreRequest NamestoreRecord var delegationRecord RecordData + var metadataRecord RecordData var gnunetError GnunetError + var registrationMetadata RegistrationMetadata w.Header().Set("Content-Type", "text/html; charset=utf-8") delegationRecord.IsPrivate = false delegationRecord.IsRelativeExpiration = true delegationRecord.IsSupplemental = false + delegationRecord.IsMaintenance = false delegationRecord.IsShadow = false - delegationRecord.RecordType = "PKEY" // FIXME - delegationRecord.RelativeExpiration = t.RelativeDelegationExpiration + delegationRecord.RecordType = "PKEY" // FIXME get from value + delegationRecord.RelativeExpiration = uint64(t.RelativeDelegationExpiration.Microseconds()) delegationRecord.Value = r.URL.Query().Get("zkey") + metadataRecord.IsPrivate = true + metadataRecord.IsRelativeExpiration = true + metadataRecord.IsSupplemental = false + metadataRecord.IsMaintenance = true + metadataRecord.IsShadow = false + metadataRecord.RecordType = "TXT" // FIXME use new recory type + metadataRecord.RelativeExpiration = uint64(t.RelativeDelegationExpiration.Microseconds()) + registrationMetadata = RegistrationMetadata{ + Paid: false, + Expiration: uint64(time.Now().Add(t.RelativeRegistrationExpiration).UnixMicro()), + } + metadataRecordValue, err := json.Marshal(registrationMetadata) + if nil != err { + http.Redirect(w, r, "/name?label="+vars["label"] + "&error=Registration failed", http.StatusSeeOther) + return + } + metadataRecord.Value = string(metadataRecordValue) namestoreRequest.RecordName = vars["label"] - namestoreRequest.Records = []RecordData{delegationRecord} + namestoreRequest.Records = []RecordData{delegationRecord,metadataRecord} reqString, _ := json.Marshal(namestoreRequest) // FIXME handle errors here fmt.Println(namestoreRequest) @@ -161,7 +191,7 @@ func (t *Registrar) registerName(w http.ResponseWriter, r *http.Request) { json.NewDecoder(resp.Body).Decode(&gnunetError) fmt.Println(gnunetError.Code) fmt.Println(err) - http.Redirect(w, r, "/name?label="+r.URL.Query().Get("label") + "&error=" + gnunetError.Description, http.StatusSeeOther) + http.Redirect(w, r, "/name?label="+vars["label"] + "&error=" + gnunetError.Description, http.StatusSeeOther) return } http.Redirect(w, r, "/name/"+ vars["label"] + "?registered=true", http.StatusSeeOther) @@ -178,29 +208,30 @@ func (t *Registrar) searchPage(w http.ResponseWriter, r *http.Request) { func (t *Registrar) buyPage(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) if t.RegistrationCost == 0 { - http.Redirect(w, r, "/name/"+vars["label"]+"/register?zkey="+r.URL.Query().Get("zkey"), http.StatusSeeOther) + http.Redirect(w, r, "/name/"+vars["label"]+"/register?zkey="+r.URL.Query().Get("zkey"), http.StatusSeeOther) + return } http.Redirect(w, r, "/name/"+vars["label"]+"?error=Not implemented", http.StatusSeeOther) return } func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) { + var metadataResponse RegistrationMetadata var namestoreResponse NamestoreRecord vars := mux.Vars(r) w.Header().Set("Content-Type", "text/html; charset=utf-8") var available = false var value = "" + var registeredUntil = "unkown" var registered = r.URL.Query().Get("registered") == "true" // FIXME redirect back if label empty - resp, err := http.Get(t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + vars["label"]) + resp, err := http.Get(t.GnunetUrl + "/namestore/" + t.RootZoneName + "/" + vars["label"] + "?include_maintenance=yes") if err != nil { fmt.Printf("Failed to get zone contents") return } defer resp.Body.Close() - if http.StatusNotFound == resp.StatusCode { - available = true - } else if http.StatusOK == resp.StatusCode { + if http.StatusOK == resp.StatusCode { respData, err := io.ReadAll(resp.Body) if err != nil { fmt.Printf("Failed to get zone contents" + err.Error()) @@ -211,11 +242,24 @@ func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) { fmt.Printf("Failed to get zone contents" + err.Error()) return } - value = namestoreResponse.Records[0].Value + for _, record := range namestoreResponse.Records { + if record.RecordType == "PKEY" { + value = record.Value + } + if record.RecordType == "TXT" { + err = json.Unmarshal([]byte(record.Value), &metadataResponse) + if err != nil { + fmt.Printf("Failed to get zone contents" + err.Error()) + return + } + registeredUntil = time.UnixMicro(int64(metadataResponse.Expiration)).String() + } + } } else { fmt.Printf("Failed to get zone contents" + err.Error()) return } + available = value == "" fullData := map[string]interface{}{ "label": vars["label"], "error": r.URL.Query().Get("error"), @@ -225,6 +269,7 @@ func (t *Registrar) namePage(w http.ResponseWriter, r *http.Request) { "currentValue": value, "suffixHint": t.SuffixHint, "registrationPolicy": t.RegistrationPolicy, + "registeredUntil": registeredUntil, "registrationSuccess": registered, } t.NameTpl.Execute(w, fullData) @@ -308,10 +353,17 @@ func (t *Registrar) Initialize(cfgfile string) { fmt.Println(err) } t.RegistrationCost = t.Cfg.Section("gns-registrar").Key("registration_cost").MustUint64(0) - t.RelativeDelegationExpiration = t.Cfg.Section("gns-registrar").Key("relative_delegation_expiration").MustUint64(86400000) + recordExp := t.Cfg.Section("gns-registrar").Key("relative_delegation_expiration").MustString("24h") + registrationExp := t.Cfg.Section("gns-registrar").Key("registration_expiration").MustString("8760h") + fmt.Println(recordExp) + fmt.Println(registrationExp) + t.RelativeRegistrationExpiration, _ = time.ParseDuration(registrationExp) + t.RelativeDelegationExpiration, _ = time.ParseDuration(recordExp) + fmt.Println(t.RelativeDelegationExpiration) + fmt.Println(t.RelativeRegistrationExpiration) t.RegistrationCostCurrency = t.Cfg.Section("gns-registrar").Key("registration_cost_currency").MustString("EUR") t.SuffixHint = t.Cfg.Section("gns-registrar").Key("suffix_hint").MustString("example.alt") - t.RootZoneName = t.Cfg.Section("gns-registrar").Key("root_zone_name").MustString("master") + t.RootZoneName = t.Cfg.Section("gns-registrar").Key("root_zone_name").MustString("test") t.GnunetUrl = t.Cfg.Section("gns-registrar").Key("gnunet_baseurl_private").MustString("http://localhost:7776") resp, err := http.Get(t.GnunetUrl + "/identity/name/" + t.RootZoneName) if err != nil { diff --git a/web/templates/name.html b/web/templates/name.html @@ -53,7 +53,7 @@ </div> </form> <form action="/renew" method="get" class="align-items-center"> - <span>Registration valid until: <i>placeholder</i></span><br/> + <span>Registration valid until: <i>{{.registeredUntil}}</i></span><br/> {{if .modificationAllowed}} <span>Registration extension cost: <i>23 EUR</i></span><br/> <input class="btn btn-primary" type="submit" value="Extend registration">