Skip to content

Commit 71c6790

Browse files
committed
feat: add /vouchers endpoint
We have a way to GET a voucher by GUID but there's no way to know the vouchers on the server. We need _at least_ an API like this to list the GUIDs it knows about. We definitely need more fields exposed but this will get us started and it's closer to having something which resembles real life in production at least. Signed-off-by: Antonio Murdaca <[email protected]>
1 parent 87f36ea commit 71c6790

File tree

5 files changed

+49
-2
lines changed

5 files changed

+49
-2
lines changed

api/handlers/vouchers.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ import (
99
"crypto/x509"
1010
"database/sql"
1111
"encoding/hex"
12+
"encoding/json"
1213
"encoding/pem"
1314
"fmt"
1415
"io"
1516
"net/http"
1617

18+
"github.com/samber/lo"
19+
1720
"github.com/fido-device-onboard/go-fdo"
1821

1922
"github.com/fido-device-onboard/go-fdo-server/internal/utils"
@@ -27,9 +30,27 @@ import (
2730
)
2831

2932
func GetVoucherHandler(w http.ResponseWriter, r *http.Request) {
30-
guidHex := r.URL.Query().Get("guid")
33+
guidHex := r.PathValue("guid")
34+
3135
if guidHex == "" {
32-
http.Error(w, "GUID is required", http.StatusBadRequest)
36+
dbVouchers, err := db.FetchVouchers()
37+
if err != nil {
38+
slog.Debug("Error querying database", "error", err)
39+
http.Error(w, err.Error(), http.StatusInternalServerError)
40+
return
41+
}
42+
43+
w.Header().Set("Content-Type", "application/json")
44+
45+
vouchers := lo.Map(dbVouchers, func(v db.Voucher, _ int) string {
46+
return hex.EncodeToString(v.GUID)
47+
})
48+
49+
if err := json.NewEncoder(w).Encode(vouchers); err != nil {
50+
http.Error(w, "Error encoding vouchers", http.StatusInternalServerError)
51+
return
52+
}
53+
w.WriteHeader(http.StatusOK)
3354
return
3455
}
3556

api/routes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func (h *HTTPHandler) RegisterRoutes() *http.ServeMux {
5757
apiRouter.Handle("/rvinfo", handlers.RvInfoHandler(h.rvInfo))
5858
apiRouter.HandleFunc("/owner/redirect", handlers.OwnerInfoHandler)
5959
apiRouter.Handle("GET /to0/{guid}", handlers.To0Handler(h.rvInfo, h.state))
60+
apiRouter.HandleFunc("GET /vouchers/{guid}", handlers.GetVoucherHandler)
6061
apiRouter.HandleFunc("GET /vouchers", handlers.GetVoucherHandler)
6162
apiRouter.Handle("POST /owner/vouchers", handlers.InsertVoucherHandler(h.rvInfo))
6263

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/fido-device-onboard/go-fdo v0.0.0-20250512135234-b46a4b0731f2
77
github.com/fido-device-onboard/go-fdo/fsim v0.0.0-20250512135234-b46a4b0731f2
88
github.com/fido-device-onboard/go-fdo/sqlite v0.0.0-20250512135234-b46a4b0731f2
9+
github.com/samber/lo v1.51.0
910
github.com/spf13/cobra v1.9.1
1011
golang.org/x/time v0.11.0
1112
hermannm.dev/devlog v0.5.0
@@ -21,4 +22,5 @@ require (
2122
golang.org/x/crypto v0.38.0 // indirect
2223
golang.org/x/sys v0.33.0 // indirect
2324
golang.org/x/term v0.32.0 // indirect
25+
golang.org/x/text v0.25.0 // indirect
2426
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ github.com/nwidger/jsoncolor v0.3.2/go.mod h1:Cs34umxLbJvgBMnVNVqhji9BhoT/N/KinH
3232
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3333
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3434
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
35+
github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI=
36+
github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
3537
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
3638
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
3739
github.com/segmentio/encoding v0.3.6 h1:E6lVLyDPseWEulBmCmAKPanDd3jiyGDo5gMcugCRwZQ=

internal/db/db.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,27 @@ func FetchVoucher(guid []byte) (Voucher, error) {
5757
return voucher, err
5858
}
5959

60+
func FetchVouchers() ([]Voucher, error) {
61+
var vouchers []Voucher
62+
rows, err := db.Query("SELECT guid, cbor FROM owner_vouchers")
63+
if err != nil {
64+
return nil, err
65+
}
66+
defer rows.Close()
67+
68+
for rows.Next() {
69+
var voucher Voucher
70+
if err := rows.Scan(&voucher.GUID, &voucher.CBOR); err != nil {
71+
return vouchers, err
72+
}
73+
vouchers = append(vouchers, voucher)
74+
}
75+
if err = rows.Err(); err != nil {
76+
return vouchers, err
77+
}
78+
return vouchers, err
79+
}
80+
6081
func FetchOwnerKeys() ([]OwnerKey, error) {
6182
rows, err := db.Query("SELECT type, pkcs8, x509_chain FROM owner_keys")
6283
if err != nil {

0 commit comments

Comments
 (0)