tailcfg: remove UserProfile.Roles field, add tests for legacy behavior
Old macOS clients required we populate this field to a non-null value so we were unable to remove this field before. Instead, keep the field but change its type to a custom empty struct that can marshal/unmarshal JSON. And lock it in with a test. Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
e698973196
commit
c25ecddd1b
|
@ -155,9 +155,22 @@ type UserProfile struct {
|
||||||
LoginName string // "alice@smith.com"; for display purposes only (provider is not listed)
|
LoginName string // "alice@smith.com"; for display purposes only (provider is not listed)
|
||||||
DisplayName string // "Alice Smith"
|
DisplayName string // "Alice Smith"
|
||||||
ProfilePicURL string
|
ProfilePicURL string
|
||||||
Roles []RoleID // deprecated; clients should not rely on Roles
|
|
||||||
|
// Roles exists for legacy reasons, to keep old macOS clients
|
||||||
|
// happy. It JSON marshals as [].
|
||||||
|
Roles emptyStructJSONSlice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type emptyStructJSONSlice struct{}
|
||||||
|
|
||||||
|
var emptyJSONSliceBytes = []byte("[]")
|
||||||
|
|
||||||
|
func (emptyStructJSONSlice) MarshalJSON() ([]byte, error) {
|
||||||
|
return emptyJSONSliceBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (emptyStructJSONSlice) UnmarshalJSON([]byte) error { return nil }
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
ID NodeID
|
ID NodeID
|
||||||
StableID StableNodeID
|
StableID StableNodeID
|
||||||
|
|
|
@ -6,6 +6,7 @@ package tailcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
"encoding"
|
||||||
|
"encoding/json"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -476,3 +477,25 @@ func TestCloneNode(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUserProfileJSONMarshalForMac(t *testing.T) {
|
||||||
|
// Old macOS clients had a bug where they required
|
||||||
|
// UserProfile.Roles to be non-null. Lock that in
|
||||||
|
// 1.0.x/1.2.x clients are gone in the wild.
|
||||||
|
// See mac commit 0242c08a2ca496958027db1208f44251bff8488b (Sep 30).
|
||||||
|
// It was fixed in at least 1.4.x, and perhaps 1.2.x.
|
||||||
|
j, err := json.Marshal(UserProfile{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
const wantSub = `"Roles":[]`
|
||||||
|
if !strings.Contains(string(j), wantSub) {
|
||||||
|
t.Fatalf("didn't contain %#q; got: %s", wantSub, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// And back:
|
||||||
|
var up UserProfile
|
||||||
|
if err := json.Unmarshal(j, &up); err != nil {
|
||||||
|
t.Fatalf("Unmarshal: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue