gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet-go-plugins] 03/03: reclaimid: first version (no new/edit).


From: gnunet
Subject: [gnunet-go-plugins] 03/03: reclaimid: first version (no new/edit).
Date: Fri, 11 Nov 2022 11:59:25 +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.

commit 49730e3532f17bebf5e7aa0bc990f7fd449e6ced
Author: Bernd Fix <brf@hoi-polloi.org>
AuthorDate: Fri Nov 11 11:58:28 2022 +0100

    reclaimid: first version (no new/edit).
---
 reclaimid/Makefile       |   2 +-
 reclaimid/gui.htpl       | 303 +++++++++++++++++++++++++++++++----------------
 reclaimid/jwt.go         |  55 +++++++++
 reclaimid/main.go        |   3 -
 reclaimid/plugin_test.go |  10 ++
 reclaimid/records.go     | 106 +++++------------
 reclaimid/utility.go     | 106 +++++++++++++++++
 7 files changed, 405 insertions(+), 180 deletions(-)

diff --git a/reclaimid/Makefile b/reclaimid/Makefile
index 0f52007..2c471c6 100644
--- a/reclaimid/Makefile
+++ b/reclaimid/Makefile
@@ -29,5 +29,5 @@ clean:
 test:
        go test -v ./...
 
-${GOPATH}/bin/plugin_reclaimid.so: main.go records.go gui.htpl
+${GOPATH}/bin/plugin_reclaimid.so: main.go records.go utility.go jwt.go 
gui.htpl
        go build -buildmode=plugin -trimpath -gcflags="-N -l" -o $@ ./...
diff --git a/reclaimid/gui.htpl b/reclaimid/gui.htpl
index 8317a72..b576279 100644
--- a/reclaimid/gui.htpl
+++ b/reclaimid/gui.htpl
@@ -1,111 +1,212 @@
-{{define "new_myrecords"}}
-    <!-- DEBUG: show template parameters -->
+{{define "new_reclaimid"}}
+    <div>{{template "logo"}}</div>
     <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>
+        <h2>Creating new records is not allowed</h2>
+        <p>
+            New records are created by using the appropriate tools provided by 
the
+            <a href="https://reclaimid.gitlab.io/"; target="_blank">re:claimID 
project</a>.
+        </p>
         <a href="/"><button>Leave</button></a>
     </div>
 {{end}}
 
-{{define "edit_myrecords"}}
-    <!-- DEBUG: show template parameters -->
+{{define "edit_reclaimid"}}
+    <div>{{template "logo"}}</div>
     <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}}
+        <h2>Editing records is not allowed</h2>
+        <p>
+            Existing records are managed by using the appropriate tools 
provided
+            by the <a href="https://reclaimid.gitlab.io/"; 
target="_blank">re:claimID
+            project</a>.
+        </p>
+        <a href="/"><button>Leave</button></a>
     </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>
+{{define "logo"}}
+<img src="data:image/png;base64,
+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
+IHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA0LjQuMC1FeGl2MiI+
+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5
+bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczp4bXBN
+TT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRw
+Oi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpk
+Yz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczpleGlmPSJodHRw
+Oi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOkdJTVA9Imh0dHA6Ly93d3cuZ2lt
+cC5vcmcveG1wLyIKICAgIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAv
+IgogICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIgogICB4bXBNTTpE
+b2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6YjQ1YjY3OTctMGQ3ZS00NjQ3LWEzNjUtZWMwYmZj
+MTJiNDcxIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjQ3YmQwMTBkLTE2NDYtNDEzNi1i
+OTU3LTAwNDkwYjAxNDNlMyIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmMz
+MTVkODI5LWRkNzUtNGI2OS1hNTgxLTI3YzZhNTA4NDk2NCIKICAgZGM6Rm9ybWF0PSJpbWFnZS9w
+bmciCiAgIGV4aWY6Q29sb3JTcGFjZT0iMSIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjgzMCIK
+ICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjE0MyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQ
+bGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjY4MTE0MTYzMTQyMDQ4IgogICBH
+SU1QOlZlcnNpb249IjIuMTAuMzIiCiAgIHRpZmY6Q29tcHJlc3Npb249IjEiCiAgIHRpZmY6T3Jp
+ZW50YXRpb249IjEiCiAgIHRpZmY6UGhvdG9tZXRyaWNJbnRlcnByZXRhdGlvbj0iMiIKICAgdGlm
+ZjpSZXNvbHV0aW9uVW5pdD0iMiIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHht
+cDpNZXRhZGF0YURhdGU9IjIwMjI6MTE6MTBUMjI6MDI6NDMrMDE6MDAiCiAgIHhtcDpNb2RpZnlE
+YXRlPSIyMDIyOjExOjEwVDIyOjAyOjQzKzAxOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8
+cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0
+RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6OTc0ZWY2MjQt
+ZDU5OS00MDc3LTg0ZmEtNmQ0NmEyOTNkMjM2IgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJH
+aW1wIDIuMTAgKExpbnV4KSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0xMS0xMFQyMjowMjo0Mysw
+MTowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3Jp
+cHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAK
+ICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz7hZgNtAAAABmJL
+R0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5gsKFQIrkMN5EwAAE2pJ
+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"/>
 {{end}}
diff --git a/reclaimid/jwt.go b/reclaimid/jwt.go
new file mode 100644
index 0000000..411e673
--- /dev/null
+++ b/reclaimid/jwt.go
@@ -0,0 +1,55 @@
+// 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 (
+       "encoding/base64"
+       "fmt"
+       "strings"
+)
+
+//----------------------------------------------------------------------
+// JSON Web Token (JWT) handling
+//----------------------------------------------------------------------
+
+func decodeJWT(in string) string {
+       parts := strings.Split(in, ".")
+       if len(parts) != 3 {
+               return "(invalid:parts)"
+       }
+       var s1, s2, s3 []byte
+       var err error
+       if s1, err = base64.StdEncoding.DecodeString(parts[0]); err != nil {
+               return "(invalid:header)"
+       }
+       jwt := fmt.Sprintf("<br>&nbsp;&nbsp;Header: %s", string(s1))
+       if s2, err = base64.StdEncoding.DecodeString(parts[1]); err != nil {
+               return "(invalid:payload)"
+       }
+       jwt += fmt.Sprintf("<br>&nbsp;&nbsp;Payload: %s<br>", string(s2))
+
+       if s3, err = base64.StdEncoding.DecodeString(parts[2]); err != nil {
+               return "(invalid:signature)"
+       }
+       return jwt + fmt.Sprintf("<br>&nbsp;&nbsp;Signature: %s<br>", 
split(string(s3), "&nbsp;&nbsp;", 64))
+}
diff --git a/reclaimid/main.go b/reclaimid/main.go
index 34db340..fb4f178 100644
--- a/reclaimid/main.go
+++ b/reclaimid/main.go
@@ -93,9 +93,6 @@ func (p *CustomPlugin) Prefix(t uint32) string {
 // No need to customize code beond this point...
 //======================================================================
 
-// Utility function
-type Utility func(fcn string, args ...any) any
-
 // Plugin is the instance of a custom implementation accessed by the
 // gnunet-go framework
 var Plugin = NewCustomPlugin()
diff --git a/reclaimid/plugin_test.go b/reclaimid/plugin_test.go
index 2a4f2fa..3e28a4a 100644
--- a/reclaimid/plugin_test.go
+++ b/reclaimid/plugin_test.go
@@ -23,6 +23,7 @@
 package main
 
 import (
+       "encoding/hex"
        "testing"
 )
 
@@ -117,3 +118,12 @@ func TestPluginFromMap(t *testing.T) {
                }
        */
 }
+
+func TestPluginAttributeEncoding(t *testing.T) {
+       s := 
"0000008000001T5BYEPR4CBE0T83PG94YV19T571YSBZT9VWMGNZ56FW3KV5V5BZ000000000000000000000000000000000000000000000000000000000M00000KCNPP2TBCC9S6CG38DXMJTW3FDHP6YT9EDXS6E00"
+       buf, err := decodeBase32GNS(s)
+       if err != nil {
+               t.Error(err)
+       }
+       t.Log(hex.EncodeToString(buf))
+}
diff --git a/reclaimid/records.go b/reclaimid/records.go
index 5e8a8d0..1f88a53 100644
--- a/reclaimid/records.go
+++ b/reclaimid/records.go
@@ -24,9 +24,7 @@ package main
 
 import (
        "bytes"
-       "encoding/base32"
        "fmt"
-       "strconv"
        "strings"
 
        "github.com/bfix/gospel/data"
@@ -69,7 +67,7 @@ func GetInstance(t uint32, buf []byte) (rec ReclaimRecord, 
err error) {
 // ReclaimAttribute record
 type ReclaimAttribute struct {
        Type        uint32 `order:"big"`    // type
-       Flags       uint32 `order:"big"`    // claim
+       Flags       uint32 `order:"big"`    // flags
        ID          []byte `size:"32"`      // Reclaim identifier
        Attestation []byte `size:"32"`      // Attestation
        NameLen     uint32 `order:"big"`    // length of name
@@ -86,17 +84,8 @@ func (rec *ReclaimAttribute) Value(inv Utility) (string, 
error) {
        if len(strings.ReplaceAll(cred, "0", "")) > 0 {
                wrt.WriteString(fmt.Sprintf("Credential=%s,<br>", cred))
        }
-       var ok bool
-       var rtype string
-       if inv != nil {
-               rtype, ok = inv("gns_type_name", rec.Type).(string)
-       }
-       if ok {
-               wrt.WriteString(fmt.Sprintf("Type=%s,<br>", rtype))
-       } else {
-               wrt.WriteString(fmt.Sprintf("Type=%d,<br>", rec.Type))
-       }
-       wrt.WriteString(fmt.Sprintf("Flags=%d,<br>", rec.Flags))
+       wrt.WriteString(fmt.Sprintf("Type=%s,<br>", reclaimType(rec.Type)))
+       wrt.WriteString(fmt.Sprintf("Flags=%s,<br>", reclaimFlags(rec.Flags)))
        name := string(rec.Name)
        val := string(rec.Data)[:rec.DataLen-1]
        wrt.WriteString(fmt.Sprintf("[%s=%s]", name, val))
@@ -129,8 +118,10 @@ type ReclaimCredential struct {
        Type    uint32 `order:"big"`    // credendial type
        Flags   uint32 `order:"big"`    // flags
        ID      []byte `size:"32"`      // credential ID
-       NameLen uint32 `order:"big"`    // length of name
-       DataLen uint32 `order:"big"`    // length of data
+       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
 }
@@ -139,18 +130,9 @@ type ReclaimCredential struct {
 func (rec *ReclaimCredential) Value(inv Utility) (string, error) {
        wrt := new(bytes.Buffer)
        wrt.WriteString(fmt.Sprintf("ID=%s,<br>", encodeBase32GNS(rec.ID)))
-       var ok bool
-       var rtype string
-       if inv != nil {
-               rtype, ok = inv("gns_type_name", rec.Type).(string)
-       }
-       if ok {
-               wrt.WriteString(fmt.Sprintf("Type=%s,<br>", rtype))
-       } else {
-               wrt.WriteString(fmt.Sprintf("Type=%d,<br>", rec.Type))
-       }
-       wrt.WriteString(fmt.Sprintf("Flags=%d,<br>", rec.Flags))
-       wrt.WriteString(fmt.Sprintf("[%s=%s]", string(rec.Name), 
string(rec.Data)))
+       wrt.WriteString(fmt.Sprintf("Type=%s,<br>", reclaimType(rec.Type)))
+       wrt.WriteString(fmt.Sprintf("Flags=%s,<br>", reclaimFlags(rec.Flags)))
+       wrt.WriteString(fmt.Sprintf("[%s=%s]", string(rec.Name), 
decodeJWT(string(rec.Data))))
        return wrt.String(), nil
 }
 
@@ -171,59 +153,33 @@ func (rec *ReclaimCredential) FromMap(inv Utility, params 
map[string]string) err
 }
 
 //----------------------------------------------------------------------
-// Helpers
+// Reclaim types and flags
 //----------------------------------------------------------------------
 
-// Split a string into lines of given length
-//
-//nolint:deadcode // might be used, might be not...
-func split(s string, chunk int) string {
-       out := ""
-       for len(s) > chunk {
-               if len(out) > 0 {
-                       out += ",<br>"
-               }
-               out += s[:chunk]
-               s = s[chunk:]
-       }
-       out += s
-       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
+// Reclaim types and flags
 //
-//nolint:deadcode // might be used, might be not...
-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)
-}
+//nolint:stylecheck // my style...
+const (
+       RECLAIM_TYPE_STRING = 1
+)
 
-// Numbers convertable from parameter value (string)
-type Number interface {
-       uint16 | uint32 | int | int16 | int32 | float32 | float64
+// get the reclaim type name
+func reclaimType(t uint32) string {
+       switch t {
+       case RECLAIM_TYPE_STRING:
+               return "STRING"
+       }
+       return "UNKNOWN"
 }
 
-// convert parameter value (string) to given number type
-//
-//nolint:deadcode // might be used, might be not...
-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
+// get reclaim flags as names
+func reclaimFlags(f uint32) string {
+       if f == 0 {
+               return "None"
        }
-       var v int
-       if v, err = strconv.Atoi(vs); err != nil {
-               return
+       s := fmt.Sprintf("%b", f)
+       for len(s) < 32 {
+               s = "0" + s
        }
-       return T(v), nil
+       return strings.TrimRight(s, "0")
 }
diff --git a/reclaimid/utility.go b/reclaimid/utility.go
new file mode 100644
index 0000000..b91bdf7
--- /dev/null
+++ b/reclaimid/utility.go
@@ -0,0 +1,106 @@
+// 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-plugons 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 (
+       "encoding/base32"
+       "fmt"
+       "strconv"
+       "strings"
+)
+
+// Utility function for exported ZoneMaster utility helpers
+type Utility func(fcn string, args ...any) any
+
+// GNSType returns the name of a GNSType
+func (u Utility) GNSType(t uint32) string {
+       rtype, ok := u("gns_type_name", t).(string)
+       if !ok {
+               return fmt.Sprintf("GNSType(%d)", t)
+       }
+       return rtype
+}
+
+// GNSFlags returns the list of GNS flags by name
+func (u Utility) GNSFlags(f uint32) string {
+       flags, ok := u("gns_flags", f).([]string)
+       if !ok {
+               return fmt.Sprintf("GNSFlags(%d)", f)
+       }
+       if len(flags) == 0 {
+               return "None"
+       }
+       return strings.Join(flags, ",")
+}
+
+// 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
+//
+//nolint:deadcode // might be used, might be not...
+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
+}
+
+// Split a string into lines of given length
+func split(s, prefix string, chunk int) (out string) {
+       for len(s) > chunk {
+               if len(out) > 0 {
+                       out += ",<br>"
+               }
+               out += prefix + s[:chunk]
+               s = s[chunk:]
+       }
+       if len(out) > 0 {
+               out += ",<br>"
+       }
+       out += prefix + s
+       return
+}

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