- internal/{address,identity,protocol,tce,transport,verify} -> pkg/ so
external Go projects can import the verified core; invariant tests
updated for the new paths
- Config.TrustProxy: key rate limiting by X-Forwarded-For when the relay
sits behind a reverse proxy (off by default, header never trusted
otherwise)
- examples/service + examples/approve: complete passwordless login round
trip (mint request -> wallet approves -> local verify), run live in CI
- docs/SERVICE-GUIDE.md: the integration recipe
98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
package protocol_test
|
|
|
|
import (
|
|
"go/parser"
|
|
"go/token"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func scanPackageProtocol(t *testing.T, dir string) []string {
|
|
t.Helper()
|
|
entries, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
t.Fatalf("read dir %s: %v", dir, err)
|
|
}
|
|
var files []string
|
|
for _, e := range entries {
|
|
if e.IsDir() || filepath.Ext(e.Name()) != ".go" {
|
|
continue
|
|
}
|
|
if len(e.Name()) <= 8 || e.Name()[len(e.Name())-8:] != "_test.go" {
|
|
files = append(files, filepath.Join(dir, e.Name()))
|
|
}
|
|
}
|
|
return files
|
|
}
|
|
|
|
func importsOfProtocol(t *testing.T, path string) []string {
|
|
t.Helper()
|
|
fset := token.NewFileSet()
|
|
f, err := parser.ParseFile(fset, path, nil, parser.ImportsOnly)
|
|
if err != nil {
|
|
t.Fatalf("parse %s: %v", path, err)
|
|
}
|
|
var out []string
|
|
for _, imp := range f.Imports {
|
|
p, err := strconv.Unquote(imp.Path.Value)
|
|
if err != nil {
|
|
t.Fatalf("bad import path in %s: %v", path, err)
|
|
}
|
|
out = append(out, p)
|
|
}
|
|
return out
|
|
}
|
|
|
|
func sourceOfProtocol(t *testing.T, path string) string {
|
|
t.Helper()
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read %s: %v", path, err)
|
|
}
|
|
return string(b)
|
|
}
|
|
|
|
func TestNoJSONImport(t *testing.T) {
|
|
for _, f := range scanPackageProtocol(t, ".") {
|
|
for _, imp := range importsOfProtocol(t, f) {
|
|
if imp == "encoding/json" {
|
|
t.Errorf("%s imports encoding/json; PROTOCOL.md forbids JSON in the wire codec", f)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNoSigningInCodec(t *testing.T) {
|
|
re := regexp.MustCompile(`ed25519\.(Sign|NewKeyFromSeed|GenerateKey)`)
|
|
for _, f := range scanPackageProtocol(t, ".") {
|
|
if re.MatchString(sourceOfProtocol(t, f)) {
|
|
t.Errorf("%s performs ed25519 signing; signing must live only in internal/identity/signer", f)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAllowedImports(t *testing.T) {
|
|
allowed := map[string]bool{
|
|
"bytes": true,
|
|
"crypto/ed25519": true, // Verify only; signing lives in internal/identity/signer
|
|
"crypto/subtle": true,
|
|
"errors": true,
|
|
"fmt": true,
|
|
"git.n1ko.dev/Niko/niko_trust/pkg/address": true,
|
|
"git.n1ko.dev/Niko/niko_trust/pkg/tce": true,
|
|
}
|
|
for _, f := range scanPackageProtocol(t, ".") {
|
|
for _, imp := range importsOfProtocol(t, f) {
|
|
switch imp {
|
|
case "go/token", "go/parser", "os", "path/filepath", "regexp", "strconv":
|
|
continue // test-only helpers
|
|
}
|
|
if !allowed[imp] {
|
|
t.Errorf("%s imports %s, which is outside the allowed protocol dependency set", f, imp)
|
|
}
|
|
}
|
|
}
|
|
}
|