diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 405eb1a41..35a35dd76 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -259,11 +259,7 @@ type UserProfile struct { ID UserID LoginName string // "alice@smith.com"; for display purposes only (provider is not listed) DisplayName string // "Alice Smith" - ProfilePicURL string - - // Roles exists for legacy reasons, to keep old macOS clients - // happy. It JSON marshals as []. - Roles emptyStructJSONSlice + ProfilePicURL string `json:",omitempty"` } func (p *UserProfile) Equal(p2 *UserProfile) bool { @@ -279,16 +275,6 @@ func (p *UserProfile) Equal(p2 *UserProfile) bool { p.ProfilePicURL == p2.ProfilePicURL } -type emptyStructJSONSlice struct{} - -var emptyJSONSliceBytes = []byte("[]") - -func (emptyStructJSONSlice) MarshalJSON() ([]byte, error) { - return emptyJSONSliceBytes, nil -} - -func (emptyStructJSONSlice) UnmarshalJSON([]byte) error { return nil } - // RawMessage is a raw encoded JSON value. It implements Marshaler and // Unmarshaler and can be used to delay JSON decoding or precompute a JSON // encoding. diff --git a/tailcfg/tailcfg_clone.go b/tailcfg/tailcfg_clone.go index f7126ca41..aeeacebec 100644 --- a/tailcfg/tailcfg_clone.go +++ b/tailcfg/tailcfg_clone.go @@ -623,7 +623,6 @@ func (src *UserProfile) Clone() *UserProfile { LoginName string DisplayName string ProfilePicURL string - Roles emptyStructJSONSlice }{}) // Clone duplicates src into dst and reports whether it succeeded. diff --git a/tailcfg/tailcfg_test.go b/tailcfg/tailcfg_test.go index 7532fc281..dd81af5d6 100644 --- a/tailcfg/tailcfg_test.go +++ b/tailcfg/tailcfg_test.go @@ -10,7 +10,6 @@ "reflect" "regexp" "strconv" - "strings" "testing" "time" @@ -649,28 +648,6 @@ 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) - } -} - func TestEndpointTypeMarshal(t *testing.T) { eps := []EndpointType{ EndpointUnknownType, diff --git a/tailcfg/tailcfg_view.go b/tailcfg/tailcfg_view.go index 55c244fbf..4b56b8c09 100644 --- a/tailcfg/tailcfg_view.go +++ b/tailcfg/tailcfg_view.go @@ -1403,7 +1403,6 @@ func (v UserProfileView) ID() UserID { return v.ж.ID } func (v UserProfileView) LoginName() string { return v.ж.LoginName } func (v UserProfileView) DisplayName() string { return v.ж.DisplayName } func (v UserProfileView) ProfilePicURL() string { return v.ж.ProfilePicURL } -func (v UserProfileView) Roles() emptyStructJSONSlice { return v.ж.Roles } func (v UserProfileView) Equal(v2 UserProfileView) bool { return v.ж.Equal(v2.ж) } // A compilation failure here means this code must be regenerated, with the command at the top of this file. @@ -1412,5 +1411,4 @@ func (v UserProfileView) Equal(v2 UserProfileView) bool { return v.ж.Equal(v2. LoginName string DisplayName string ProfilePicURL string - Roles emptyStructJSONSlice }{})