From 283f34b9c6d207f0a103e7b4c7f6da2c7481c3ef Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Fri, 20 Apr 2018 08:44:18 -0400 Subject: MM-10007 Send an admin and regular WS events when a user is updated (#8588) * Add user.DeepCopy() function * Add omit admins/non-admins to WS broadcast and use for updating users * Updates per feedback and adding unit test for ShouldSendEvent --- model/user.go | 17 +++++++++++++++++ model/user_test.go | 32 ++++++++++++++++++++++++++++++++ model/utils.go | 8 ++++++++ model/utils_test.go | 12 ++++++++++++ model/websocket_message.go | 10 ++++++---- 5 files changed, 75 insertions(+), 4 deletions(-) (limited to 'model') diff --git a/model/user.go b/model/user.go index efe8f8db9..6fbdb09e8 100644 --- a/model/user.go +++ b/model/user.go @@ -96,6 +96,23 @@ type UserAuth struct { AuthService string `json:"auth_service,omitempty"` } +func (u *User) DeepCopy() *User { + copyUser := *u + if u.AuthData != nil { + copyUser.AuthData = NewString(*u.AuthData) + } + if u.Props != nil { + copyUser.Props = CopyStringMap(u.Props) + } + if u.NotifyProps != nil { + copyUser.NotifyProps = CopyStringMap(u.NotifyProps) + } + if u.Timezone != nil { + copyUser.Timezone = CopyStringMap(u.Timezone) + } + return ©User +} + // IsValid validates the user and returns an error if it isn't configured // correctly. func (u *User) IsValid() *AppError { diff --git a/model/user_test.go b/model/user_test.go index c1d1dafbd..645eaadff 100644 --- a/model/user_test.go +++ b/model/user_test.go @@ -8,6 +8,8 @@ import ( "net/http" "strings" "testing" + + "github.com/stretchr/testify/assert" ) func TestPasswordHash(t *testing.T) { @@ -22,6 +24,36 @@ func TestPasswordHash(t *testing.T) { } } +func TestUserDeepCopy(t *testing.T) { + id := NewId() + authData := "authdata" + mapKey := "key" + mapValue := "key" + + user := &User{Id: id, AuthData: NewString(authData), Props: map[string]string{}, NotifyProps: map[string]string{}, Timezone: map[string]string{}} + user.Props[mapKey] = mapValue + user.NotifyProps[mapKey] = mapValue + user.Timezone[mapKey] = mapValue + + copyUser := user.DeepCopy() + copyUser.Id = "someid" + *copyUser.AuthData = "changed" + copyUser.Props[mapKey] = "changed" + copyUser.NotifyProps[mapKey] = "changed" + copyUser.Timezone[mapKey] = "changed" + + assert.Equal(t, id, user.Id) + assert.Equal(t, authData, *user.AuthData) + assert.Equal(t, mapValue, user.Props[mapKey]) + assert.Equal(t, mapValue, user.NotifyProps[mapKey]) + assert.Equal(t, mapValue, user.Timezone[mapKey]) + + user = &User{Id: id} + copyUser = user.DeepCopy() + + assert.Equal(t, id, user.Id) +} + func TestUserJson(t *testing.T) { user := User{Id: NewId(), Username: NewId()} json := user.ToJson() diff --git a/model/utils.go b/model/utils.go index 2d61b49f6..9f8ef90e1 100644 --- a/model/utils.go +++ b/model/utils.go @@ -148,6 +148,14 @@ func GetMillis() int64 { return time.Now().UnixNano() / int64(time.Millisecond) } +func CopyStringMap(originalMap map[string]string) map[string]string { + copyMap := make(map[string]string) + for k, v := range originalMap { + copyMap[k] = v + } + return copyMap +} + // MapToJson converts a map to a json string func MapToJson(objmap map[string]string) string { b, _ := json.Marshal(objmap) diff --git a/model/utils_test.go b/model/utils_test.go index 92354c0a1..b7f5dc628 100644 --- a/model/utils_test.go +++ b/model/utils_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -47,6 +48,17 @@ func TestAppErrorJunk(t *testing.T) { } } +func TestCopyStringMap(t *testing.T) { + itemKey := "item1" + originalMap := make(map[string]string) + originalMap[itemKey] = "val1" + + copyMap := CopyStringMap(originalMap) + copyMap[itemKey] = "changed" + + assert.Equal(t, "val1", originalMap[itemKey]) +} + func TestMapJson(t *testing.T) { m := make(map[string]string) diff --git a/model/websocket_message.go b/model/websocket_message.go index 4a547bb6a..08c238480 100644 --- a/model/websocket_message.go +++ b/model/websocket_message.go @@ -57,10 +57,12 @@ type WebSocketMessage interface { } type WebsocketBroadcast struct { - OmitUsers map[string]bool `json:"omit_users"` // broadcast is omitted for users listed here - UserId string `json:"user_id"` // broadcast only occurs for this user - ChannelId string `json:"channel_id"` // broadcast only occurs for users in this channel - TeamId string `json:"team_id"` // broadcast only occurs for users in this team + OmitUsers map[string]bool `json:"omit_users"` // broadcast is omitted for users listed here + UserId string `json:"user_id"` // broadcast only occurs for this user + ChannelId string `json:"channel_id"` // broadcast only occurs for users in this channel + TeamId string `json:"team_id"` // broadcast only occurs for users in this team + ContainsSanitizedData bool `json:"-"` + ContainsSensitiveData bool `json:"-"` } type precomputedWebSocketEventJSON struct { -- cgit v1.2.3-1-g7c22