diff --git a/group/description.go b/group/description.go index 2b8c4e6..be7c276 100644 --- a/group/description.go +++ b/group/description.go @@ -116,6 +116,18 @@ type UserDescription struct { Permissions Permissions `json:"permissions"` } +// Custom MarshalJSON in order to omit ompty fields +func (u UserDescription) MarshalJSON() ([]byte, error) { + uu := make(map[string]any, 2) + if u.Password.Type != "" { + uu["password"] = &u.Password + } + if u.Permissions.name != "" || u.Permissions.permissions != nil { + uu["permissions"] = &u.Permissions + } + return json.Marshal(uu) +} + // Description represents a group description together with some metadata // about the JSON file it was deserialised from. type Description struct { diff --git a/group/description_test.go b/group/description_test.go index 1c71edf..0812e72 100644 --- a/group/description_test.go +++ b/group/description_test.go @@ -8,6 +8,53 @@ import ( "testing" ) +func TestMarshalUserDescription(t *testing.T) { + tests := []string{ + `{}`, + `{"permissions":"present"}`, + `{"password":"secret"}`, + `{"password":"secret","permissions":"present"}`, + `{"password":"secret","permissions":["present"]}`, + `{"password":{"type":"wildcard"},"permissions":"observe"}`, + `{"password":{"type":"wildcard"},"permissions":[]}`, + } + + for _, test := range tests { + var u UserDescription + err := json.Unmarshal([]byte(test), &u) + if err != nil { + t.Errorf("Unmarshal %v: %v", t, err) + continue + } + v, err := json.Marshal(u) + if err != nil || string(v) != test { + t.Errorf("Marshal %v: got %v %v", test, string(v), err) + } + } +} + +func TestEmptyJSON(t *testing.T) { + type emptyTest struct { + value any + result string + name string + } + + emptyTests := []emptyTest{ + {Password{}, "{}", "password"}, + {Permissions{}, "null", "permissions"}, + {UserDescription{}, "{}", "user description"}, + } + + for _, v := range emptyTests { + b, err := json.Marshal(v.value) + if err != nil || string(b) != v.result { + t.Errorf("Marshal empty %v: %#v %v, expected %#v", + v.name, string(b), err, v.result) + } + } +} + var descJSON = ` { "max-history-age": 10, @@ -218,7 +265,7 @@ func TestWritableGroups(t *testing.T) { pw := "pw" err = SetUserPassword("test", "jch", Password{ - Type: "", + Type: "plain", Key: &pw, }) if err != nil {