[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet-go-plugins] branch master updated: reclaimid: initial revision.
From: |
gnunet |
Subject: |
[gnunet-go-plugins] branch master updated: reclaimid: initial revision. |
Date: |
Thu, 03 Nov 2022 15:00:01 +0100 |
This is an automated email from the git hooks/post-receive script.
bernd-fix pushed a commit to branch master
in repository gnunet-go-plugins.
The following commit(s) were added to refs/heads/master by this push:
new 6f1282c reclaimid: initial revision.
6f1282c is described below
commit 6f1282c4d1910fde3100c2f24cf38a344662c314
Author: Bernd Fix <brf@hoi-polloi.org>
AuthorDate: Thu Nov 3 13:17:23 2022 +0100
reclaimid: initial revision.
---
reclaimid/Makefile | 33 ++++++++
reclaimid/gui.htpl | 111 ++++++++++++++++++++++++
reclaimid/main.go | 146 ++++++++++++++++++++++++++++++++
reclaimid/plugin_test.go | 119 ++++++++++++++++++++++++++
reclaimid/records.go | 215 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 624 insertions(+)
diff --git a/reclaimid/Makefile b/reclaimid/Makefile
new file mode 100644
index 0000000..0f52007
--- /dev/null
+++ b/reclaimid/Makefile
@@ -0,0 +1,33 @@
+# This file is part of gnunet-go-plugins, a collection of plugins for
+# the GNUnet-implementation in Golang (gnunet.go). Plugins are used to
+# implement type-specific processing of resource records (e.g. GUI).
+# Copyright (C) 2022 by the authors:
+#
+# * Bernd Fix <brf@hoi-polloi.org> >Y<
+#
+# gnunet-go-plugins is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License,
+# or (at your option) any later version.
+#
+# gnunet-go is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# SPDX-License-Identifier: AGPL3.0-or-later
+
+
+all: ${GOPATH}/bin/plugin_reclaimid.so
+
+clean:
+ rm -f ${GOPATH}/bin/plugin_reclaimid.so
+
+test:
+ go test -v ./...
+
+${GOPATH}/bin/plugin_reclaimid.so: main.go records.go gui.htpl
+ go build -buildmode=plugin -trimpath -gcflags="-N -l" -o $@ ./...
diff --git a/reclaimid/gui.htpl b/reclaimid/gui.htpl
new file mode 100644
index 0000000..8317a72
--- /dev/null
+++ b/reclaimid/gui.htpl
@@ -0,0 +1,111 @@
+{{define "new_myrecords"}}
+ <!-- DEBUG: show template parameters -->
+ <div>
+ <h3>Template data:</h3>
+ <p>Ref = {{.Ref}}</p>
+ <p>Action = {{.Action}}</p>
+ <p>Button = {{.Button}}</p>
+ <p>Names: {{range $i,$v := .Names}}'{{$v}}',{{end}}</p>
+ <p>RRSpecs:</p>
+ <ul>
+ {{range $i,$s := .RRspecs}}
+ <li>Type = {{$s.Type}}, Flags = {{$s.Flags}}</li>
+ {{end}}
+ </ul>
+ <p>Params:</p>
+ <ul>
+ {{range $k,$v := .Params}}
+ <li>'{{$k}}' = '{{$v}}'</li>
+ {{end}}
+ </ul>
+ </div>
+
+ {{$data := .}}
+ <div>
+ <h3>Creating a new custom resource record for label "{{index .Params
"label"}}":</h3>
+ <div class="tabset">
+ {{range $i, $type := .RRspecs}}
+ <input type="radio" name="tabset" id="tab{{$i}}"
aria-controls="tab{{$i}}" {{if eq $i 0}}checked{{end}}>
+ <label for="tab{{$i}}">{{rrtype $type.Type}}</label>
+ {{end}}
+ <div class="tab-panels">
+ {{range $i, $spec := .RRspecs}}
+ <section id="tab{{$i}}" class="tab-panel">
+ {{$t := rrtype $spec.Type}}
+ {{$pf := setspecs $data.Params $spec}}
+ {{if eq $t "MYRECTYPE1"}}{{template "MYRECTYPE1"
$data}}{{end}}
+ {{if eq $t "MYRECTYPE2"}}{{template "MYRECTYPE2"
$data}}{{end}}
+ </section>
+ {{end}}
+ </div>
+ </div>
+ <a href="/"><button>Leave</button></a>
+ </div>
+{{end}}
+
+{{define "edit_myrecords"}}
+ <!-- DEBUG: show template parameters -->
+ <div>
+ <h3>Template data:</h3>
+ <p>Ref = {{.Ref}}</p>
+ <p>Action = {{.Action}}</p>
+ <p>Button = {{.Button}}</p>
+ <p>Names: {{range $i,$v := .Names}}'{{$v}}',{{end}}</p>
+ <ul>
+ {{range $k,$v := .Params}}
+ <li>'{{$k}}' = '{{$v}}'</li>
+ {{end}}
+ </ul>
+ </div>
+
+ <div>
+ <h3>Edit a resource record for label {{index .Params "label"}}:</h3>
+ <p><small>(Created: {{index .Params "created"}}, Last edited: {{index
.Params "modified"}})</small></p>
+ {{$t := rritype (index .Params "type")}}
+ {{if eq $t "MYRECTYPE1"}}{{template "MYRECTYPE1" .}}{{end}}
+ {{if eq $t "MYRECTYPE2"}}{{template "MYRECTYPE2" .}}{{end}}
+ </div>
+ <a href="/"><button>Leave</button></a>
+{{end}}
+
+{{define "MYRECTYPE1"}}
+ <h3>RECTYPE1</h3>
+ <form action="/action/{{.Action}}/rr/{{.Ref}}" {{if eq .Action
"upd"}}method="post"{{end}}>
+ <input type="hidden" name="type" value="{{index .Params "type"}}">
+ <table>
+ <tr>
+ <td align="right"><b>Attribute1:</b></td>
+ <td>
+ <input type="text" name="myrec1_text"
+ maxlength="63" size="63"
+ autofocus required
+ value="{{index .Params "myrec1_text"}}"
+ >
+ </td>
+ </tr>
+ {{template "RRCommon" .}}
+ <tr><td/><td><button id="submit">{{.Button}}
record</button></td></tr>
+ </table>
+ </form>
+{{end}}
+
+{{define "MYRECTYPE2"}}
+ <h3>RECTYPE2</h3>
+ <form action="/action/{{.Action}}/rr/{{.Ref}}" {{if eq .Action
"upd"}}method="post"{{end}}>
+ <input type="hidden" name="type" value="{{index .Params "type"}}">
+ <table>
+ <tr>
+ <td align="right"><b>Attribute1:</b></td>
+ <td>
+ <input type="text" name="myrec2_text"
+ maxlength="63" size="63"
+ autofocus required
+ value="{{index .Params "myrec2_text"}}"
+ >
+ </td>
+ </tr>
+ {{template "RRCommon" .}}
+ <tr><td/><td><button id="submit">{{.Button}}
record</button></td></tr>
+ </table>
+ </form>
+{{end}}
diff --git a/reclaimid/main.go b/reclaimid/main.go
new file mode 100644
index 0000000..fc24ecd
--- /dev/null
+++ b/reclaimid/main.go
@@ -0,0 +1,146 @@
+// This file is part of gnunet-go-plugins, a collection of plugins for
+// the GNUnet-implementation in Golang (gnunet.go). Plugins are used to
+// implement type-specific processing of resource records (e.g. GUI).
+// Copyright (C) 2022 by the authors:
+//
+// * Bernd Fix <brf@hoi-polloi.org> >Y<
+//
+// gnunet-go-plugins is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// gnunet-go is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: AGPL3.0-or-later
+
+package main
+
+import (
+ _ "embed"
+
+ "github.com/bfix/gospel/data"
+)
+
+//======================================================================
+// C U S T O M I Z A T I O N
+//======================================================================
+
+// List of handled resource record types.
+var handledTypes = []uint32{
+ 65544, // RECLAIM_ATTRIBUTE
+ 65545, // RECLAIM_TICKET
+ 65550, // RECLAIM_ATTRIBUTE_REF
+ 65552, // RECLAIM_OIDC_CLIENT
+ 65553, // RECLAIM_OIDC_REDIRECT
+ 65554, // RECLAIM_CREDENTIAL
+ 65555, // RECLAIM_PRESENTATION
+}
+
+//----------------------------------------------------------------------
+// Interface implementation
+//----------------------------------------------------------------------
+
+// Name returns the plugin name (sub-system name)
+func (p *CustomPlugin) Name() string {
+ return "Re:claimID"
+}
+
+// CanHandle returns a list of resource record types that are handled
+// by the plugin.
+func (p *CustomPlugin) CanHandle() (list []uint32) {
+ return handledTypes
+}
+
+// Compute a set of record specs allowed under a label with existing records
+func (p *CustomPlugin) Compatible(_ string, _ [][2]uint32) [][2]uint32 {
+ // simple case: no restrictions (all types, all flags)
+ list := make([][2]uint32, 0)
+ for _, t := range handledTypes {
+ list = append(list, [2]uint32{t, 0})
+ }
+ return list
+}
+
+// TemplateNames returns the names of the new / edit template
+// TODO: customize template names (see gui.htpl)
+func (p *CustomPlugin) TemplateNames() (string, string) {
+ return "new_reclaimid", "edit_reclaimid"
+}
+
+// Prefix returns the prefix for record attributes in map
+func (p *CustomPlugin) Prefix(t uint32) string {
+ switch t {
+ case 65544: // RECLAIM_ATTRIBUTE
+ return "reclaimid_attr"
+ case 65545: // RECLAIM_TICKET
+ case 65550: // RECLAIM_ATTRIBUTE_REF
+ case 65552: // RECLAIM_OIDC_CLIENT
+ case 65553: // RECLAIM_OIDC_REDIRECT
+ case 65554: // RECLAIM_CREDENTIAL
+ case 65555: // RECLAIM_PRESENTATION
+ }
+ return "unknown"
+}
+
+//======================================================================
+// No need to customize code beond this point...
+//======================================================================
+
+// Plugin is the instance of a custom implementation accessed by the
+// gnunet-go framework
+var Plugin = NewCustomPlugin()
+
+// ExamplePlugin is an example plugin for custom records that implements
+// the zonemaster.Plugin interface.
+type CustomPlugin struct{}
+
+// NewCustomPlugin creates an initialized plugin instance
+func NewCustomPlugin() CustomPlugin {
+ return CustomPlugin{}
+}
+
+//go:embed gui.htpl
+var tpl []byte
+
+// Template returns the new / edit template for resource record types
+// handled by the plugin.
+func (p *CustomPlugin) Template() string {
+ return string(tpl)
+}
+
+// Value returns a human-readable description of RR data
+func (p *CustomPlugin) Value(t uint32, rr []byte) (string, error) {
+ rec, err := GetInstance(t, rr)
+ if err != nil {
+ return "", err
+ }
+ return rec.Value()
+}
+
+// ToMap converts resource record data into GUI template variables
+func (p *CustomPlugin) ToMap(t uint32, rr []byte) (map[string]string, error) {
+ rec, err := GetInstance(t, rr)
+ if err != nil {
+ return nil, err
+ }
+ return rec.ToMap()
+}
+
+// FromMap converts a GUI template variables into resource record data
+func (p *CustomPlugin) FromMap(t uint32, vars map[string]string) ([]byte,
error) {
+ rec, err := GetInstance(t, nil)
+ if err != nil {
+ return nil, err
+ }
+ if err = rec.FromMap(vars); err != nil {
+ return nil, err
+ }
+ return data.Marshal(rec)
+}
diff --git a/reclaimid/plugin_test.go b/reclaimid/plugin_test.go
new file mode 100644
index 0000000..2a4f2fa
--- /dev/null
+++ b/reclaimid/plugin_test.go
@@ -0,0 +1,119 @@
+// This file is part of gnunet-go-plugins, a collection of plugins for
+// the GNUnet-implementation in Golang (gnunet.go). Plugins are used to
+// implement type-specific processing of resource records (e.g. GUI).
+// Copyright (C) 2022 by the authors:
+//
+// * Bernd Fix <brf@hoi-polloi.org> >Y<
+//
+// gnunet-go-plugins is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// gnunet-go is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: AGPL3.0-or-later
+
+package main
+
+import (
+ "testing"
+)
+
+func TestPluginCanHandle(t *testing.T) {
+ list := Plugin.CanHandle()
+ if len(list) == 0 {
+ t.Fatal("no type list received from plugin")
+ }
+ for _, rr := range list {
+ t.Logf("Can handle %d\n", rr)
+ }
+}
+
+func TestPluginCompatible(t *testing.T) {
+ in := make([][2]uint32, 0)
+ out := Plugin.Compatible("@", in)
+ for _, s := range out {
+ t.Logf("Compatible: type=%d, flags=%d\n", s[0], s[1])
+ }
+}
+
+func TestPluginPrefix(t *testing.T) {
+ for _, rr := range Plugin.CanHandle() {
+ t.Logf("Prefix: '%s' (%d)\n", Plugin.Prefix(rr), rr)
+ }
+}
+
+var (
+ recAttr = []byte{
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9a, 0x97, 0xbc, 0x98, 0x67, 0x57, 0x3d, 0x65,
+ 0x9e, 0x9d, 0x08, 0x62, 0x7a, 0xd3, 0xe3, 0xb9,
+ 0xb2, 0xe1, 0xce, 0x7e, 0xb8, 0xed, 0x3b, 0x8d,
+ 0x46, 0xd8, 0xe3, 0xdb, 0xe8, 0xbb, 0x45, 0x8b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
+ 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x72, 0x66,
+ 0x40, 0x68, 0x6f, 0x69, 0x2d, 0x70, 0x6f, 0x6c,
+ 0x6c, 0x6f, 0x69, 0x2e, 0x6f, 0x72, 0x67, 0x00,
+ }
+)
+
+func TestPluginValueAttribute(t *testing.T) {
+ s, err := Plugin.Value(65544, recAttr)
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("attribute: value='%s'\n", s)
+}
+
+func TestPluginToMap(t *testing.T) {
+ /*
+ params, err := Plugin.ToMap(90666, rec1)
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("ToMap: rec1 -> %v\n", params)
+
+ if params, err = Plugin.ToMap(90667, rec2); err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("ToMap: rec2 -> %v\n", params)
+ */
+}
+
+func TestPluginFromMap(t *testing.T) {
+ /*
+ params := map[string]string{
+ "rectype1_text": "foo",
+ }
+ rr, err := Plugin.FromMap(90666, params)
+ if err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("FromMap: rr=%s\n", hex.EncodeToString(rr))
+ if !bytes.Equal(rr, rec1) {
+ t.Fatal("FromMap for rectype1 failed")
+ }
+ params = map[string]string{
+ "rectype2_var1": "35",
+ "rectype2_var2": "66",
+ }
+ if rr, err = Plugin.FromMap(90667, params); err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("FromMap: rr=%s\n", hex.EncodeToString(rr))
+ if !bytes.Equal(rr, rec2) {
+ t.Fatal("FromMap for rectype2 failed")
+ }
+ */
+}
diff --git a/reclaimid/records.go b/reclaimid/records.go
new file mode 100644
index 0000000..6886b31
--- /dev/null
+++ b/reclaimid/records.go
@@ -0,0 +1,215 @@
+// This file is part of gnunet-go-plugins, a collection of plugins for
+// the GNUnet-implementation in Golang (gnunet.go). Plugins are used to
+// implement type-specific processing of resource records (e.g. GUI).
+// Copyright (C) 2022 by the authors:
+//
+// * Bernd Fix <brf@hoi-polloi.org> >Y<
+//
+// gnunet-go-plugins is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published
+// by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// gnunet-go is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: AGPL3.0-or-later
+
+package main
+
+import (
+ "bytes"
+ "encoding/base32"
+ "encoding/hex"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/bfix/gospel/data"
+)
+
+// ReclaimRecord interface impemented by custom types.
+type ReclaimRecord interface {
+ Value() (string, error)
+ ToMap() (map[string]string, error)
+ FromMap(map[string]string) error
+}
+
+// Get record instance for given type and data
+func GetInstance(t uint32, buf []byte) (rec ReclaimRecord, err error) {
+ switch t {
+ case 65544: // RECLAIM_ATTRIBUTE
+ rec = new(ReclaimAttribute)
+ case 65545: // RECLAIM_TICKET
+ case 65550: // RECLAIM_ATTRIBUTE_REF
+ case 65552: // RECLAIM_OIDC_CLIENT
+ case 65553: // RECLAIM_OIDC_REDIRECT
+ case 65554: // RECLAIM_CREDENTIAL
+ rec = new(ReclaimCredential)
+ case 65555: // RECLAIM_PRESENTATION
+ }
+ if buf != nil {
+ err = data.Unmarshal(rec, buf)
+ }
+ return
+}
+
+//======================================================================
+// Reclaim Resource Records
+//======================================================================
+
+//----------------------------------------------------------------------
+// Reclaim Attribute
+//----------------------------------------------------------------------
+
+// ReclaimAttribute record
+type ReclaimAttribute struct {
+ Type uint32 `order:"big"` // type
+ Flags uint32 `order:"big"` // claim
+ ID []byte `size:"32"` // Reclaim identifier
+ Credential []byte `size:"32"` // Reclaim identifier
+ NameLen uint16 `order:"big"` // length of name
+ Res1 uint16 `order:"big"` // reserved
+ DataLen uint16 `order:"big"` // length of data
+ Res2 uint16 `order:"big"` // reserved
+ Name []byte `size:"NameLen"` // name
+ Data []byte `size:"DataLen"` // binary data
+}
+
+// Value returns a human-readable representation of the record
+func (rec *ReclaimAttribute) Value() (string, error) {
+ wrt := new(bytes.Buffer)
+ wrt.WriteString(fmt.Sprintf("ID=%s,<br>", encodeBase32GNS(rec.ID)))
+ cred := encodeBase32GNS(rec.Credential)
+ if len(strings.ReplaceAll(cred, "0", "")) > 0 {
+ wrt.WriteString(fmt.Sprintf("Credential=%s,<br>", cred))
+ }
+ wrt.WriteString(fmt.Sprintf("Type=%d,<br>", rec.Type))
+ wrt.WriteString(fmt.Sprintf("Flags=%d,<br>", rec.Flags))
+ name := string(rec.Name)
+ val := string(rec.Data)[:rec.DataLen-1]
+ wrt.WriteString(fmt.Sprintf("[%s=%s]", name, val))
+ return wrt.String(), nil
+}
+
+// ToMap returns the parameter set for the record
+func (rec *ReclaimAttribute) ToMap() (params map[string]string, err error) {
+ params = make(map[string]string)
+ params["reclaim_attribute_id"] = encodeBase32GNS(rec.ID)
+ params["reclaim_attribute_credential"] = encodeBase32GNS(rec.Credential)
+ params["reclaim_attribute_type"] = fmt.Sprintf("%d", rec.Type)
+ params["reclaim_attribute_flags"] = fmt.Sprintf("%d", rec.Flags)
+ params["reclaim_attribute_key"] = string(rec.Name)
+ params["reclaim_attribute_value"] = string(rec.Data)[:rec.DataLen-1]
+ return
+}
+
+// FromMap reconstructs the record attributes from parameter list
+func (rec *ReclaimAttribute) FromMap(params map[string]string) error {
+ return nil
+}
+
+//----------------------------------------------------------------------
+// Reclaim Credential
+//----------------------------------------------------------------------
+
+// ReclaimCredential is a credential resource record data
+type ReclaimCredential struct {
+ Type uint32 `order:"big"` // credendial type
+ Flags uint32 `order:"big"` // flags
+ ID []byte `size:"32"` // credential ID
+ NameLen uint16 `order:"big"` // length of name
+ Res1 uint16 `order:"big"` // reserved
+ DataLen uint16 `order:"big"` // length of data
+ Res2 uint16 `order:"big"` // reserved
+ Name []byte `size:"NameLen"` // name
+ Data []byte `size:"DataLen"` // binary data
+}
+
+// Value returns a human-readable representation of the record
+//
+//nolint:unparam // error-free
+func (rec *ReclaimCredential) Value() (string, error) {
+ wrt := new(bytes.Buffer)
+ wrt.WriteString(fmt.Sprintf("ID=%s,<br>", encodeBase32GNS(rec.ID)))
+ wrt.WriteString(fmt.Sprintf("Type=%d,<br>", rec.Type))
+ wrt.WriteString(fmt.Sprintf("Flags=%d,<br>", rec.Flags))
+ name := string(rec.Name)
+ val := hex.EncodeToString(rec.Data)
+ wrt.WriteString(fmt.Sprintf("[%s=%s]", name, split(val, 64)))
+ return wrt.String(), nil
+}
+
+// ToMap returns the parameter set for the record
+//
+//nolint:unparam // error-free
+func (rec *ReclaimCredential) ToMap() (params map[string]string, err error) {
+ params = make(map[string]string)
+ params["reclaim_credential_id"] = encodeBase32GNS(rec.ID)
+ params["reclaim_credential_type"] = fmt.Sprintf("%d", rec.Type)
+ params["reclaim_credential_flags"] = fmt.Sprintf("%d", rec.Flags)
+ params["reclaim_credential_key"] = string(rec.Name)
+ params["reclaim_credential_value"] = hex.EncodeToString(rec.Data)
+ return
+}
+
+// FromMap reconstructs the record attributes from parameter list
+func (rec *ReclaimCredential) FromMap(params map[string]string) error {
+ return nil
+}
+
+//----------------------------------------------------------------------
+// Helpers
+//----------------------------------------------------------------------
+
+// Split a string into lines of given length
+func split(s string, chunk int) string {
+ out := ""
+ for len(s) > chunk {
+ if len(out) > 0 {
+ out += ",<br>"
+ }
+ out += s[:chunk]
+ s = s[chunk:]
+ }
+ return out
+}
+
+// Base32GNS encoding character set
+var cf32Enc = base32.NewEncoding("0123456789ABCDEFGHJKMNPQRSTVWXYZ")
+
+// Return a byte array encoded with Base32GNS
+func encodeBase32GNS(buf []byte) string {
+ return strings.TrimRight(cf32Enc.EncodeToString(buf), "=")
+}
+
+// Convert string to byte array using Base32GNS
+func decodeBase32GNS(s string) ([]byte, error) {
+ s = strings.ToUpper(s)
+ s = strings.NewReplacer("O", "0", "I", "1", "L", "1", "U",
"V").Replace(s)
+ return cf32Enc.DecodeString(s)
+}
+
+// Numbers convertable from parameter value (string)
+type Number interface {
+ uint16 | uint32 | int | int16 | int32 | float32 | float64
+}
+
+// convert parameter value (string) to given number type
+func asInt[T Number](params map[string]string, key string) (val T, err error) {
+ vs, ok := params[key]
+ if !ok {
+ err = fmt.Errorf("%s missing", key)
+ return
+ }
+ var v int
+ if v, err = strconv.Atoi(vs); err != nil {
+ return
+ }
+ return T(v), nil
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet-go-plugins] branch master updated: reclaimid: initial revision.,
gnunet <=