diff --git a/go.mod b/go.mod index f719bc0b..3af028b9 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 github.com/glebarez/sqlite v1.11.0 github.com/go-gormigrate/gormigrate/v2 v2.1.4 + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 github.com/gofrs/uuid/v5 v5.3.2 github.com/google/go-cmp v0.7.0 github.com/gorilla/mux v1.8.1 @@ -131,7 +132,6 @@ require ( github.com/glebarez/go-sqlite v1.22.0 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect github.com/go-jose/go-jose/v4 v4.1.0 // indirect - github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect diff --git a/hscontrol/policy/v2/types.go b/hscontrol/policy/v2/types.go index a2541da6..571ce46c 100644 --- a/hscontrol/policy/v2/types.go +++ b/hscontrol/policy/v2/types.go @@ -1,8 +1,6 @@ package v2 import ( - "bytes" - "encoding/json" "errors" "fmt" "net/netip" @@ -10,6 +8,8 @@ import ( "strconv" "strings" + "github.com/go-json-experiment/json" + "github.com/juanfont/headscale/hscontrol/types" "github.com/juanfont/headscale/hscontrol/util" "github.com/prometheus/common/model" @@ -609,10 +609,8 @@ type AliasWithPorts struct { } func (ve *AliasWithPorts) UnmarshalJSON(b []byte) error { - // TODO(kradalby): use encoding/json/v2 (go-json-experiment) - dec := json.NewDecoder(bytes.NewReader(b)) var v any - if err := dec.Decode(&v); err != nil { + if err := json.Unmarshal(b, &v); err != nil { return err } @@ -1741,9 +1739,13 @@ func unmarshalPolicy(b []byte) (*Policy, error) { } ast.Standardize() - acl := ast.Pack() - - if err = json.Unmarshal(acl, &policy); err != nil { + if err = json.Unmarshal(ast.Pack(), &policy, json.MatchCaseInsensitiveNames(true), json.RejectUnknownMembers(true)); err != nil { + var serr *json.SemanticError + if errors.As(err, &serr) && serr.Err == json.ErrUnknownName { + ptr := serr.JSONPointer + name := ptr.LastToken() + return nil, fmt.Errorf("unknown field %q", name) + } return nil, fmt.Errorf("parsing policy from bytes: %w", err) }