diff --git a/api4/apitestlib.go b/api4/apitestlib.go index 4dec81bb1d..3020500f39 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -240,6 +240,10 @@ func (me *TestHelper) CreateWebSocketSystemAdminClient() (*model.WebSocketClient return model.NewWebSocketClient4(fmt.Sprintf("ws://localhost:%v", me.App.Srv.ListenAddr.Port), me.SystemAdminClient.AuthToken) } +func (me *TestHelper) CreateWebSocketClientWithClient(client *model.Client4) (*model.WebSocketClient, *model.AppError) { + return model.NewWebSocketClient4(fmt.Sprintf("ws://localhost:%v", me.App.Srv.ListenAddr.Port), client.AuthToken) +} + func (me *TestHelper) CreateUser() *model.User { return me.CreateUserWithClient(me.Client) } diff --git a/api4/user_test.go b/api4/user_test.go index 397de123ba..e7f0ca8b6e 100644 --- a/api4/user_test.go +++ b/api4/user_test.go @@ -265,6 +265,82 @@ func TestCreateUserWithToken(t *testing.T) { }) } +func TestCreateUserWebSocketEvent(t *testing.T) { + th := Setup().InitBasic() + defer th.TearDown() + + t.Run("guest should not received new_user event but user should", func(t *testing.T) { + th.App.SetLicense(model.NewTestLicense("guests")) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.Enable = true }) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.GuestAccountsSettings.AllowEmailAccounts = true }) + + id := model.NewId() + guestPassword := "Pa$$word11" + guest := &model.User{ + Email: "success+" + id + "@simulator.amazonses.com", + Username: "un_" + id, + Nickname: "nn_" + id, + Password: guestPassword, + EmailVerified: true, + } + + guest, err := th.App.CreateGuest(guest) + require.Nil(t, err) + + _, err = th.App.AddUserToTeam(th.BasicTeam.Id, guest.Id, "") + require.Nil(t, err) + + _, err = th.App.AddUserToChannel(guest, th.BasicChannel) + require.Nil(t, err) + + guestClient := th.CreateClient() + + _, resp := guestClient.Login(guest.Email, guestPassword) + require.Nil(t, resp.Error) + + guestWSClient, err := th.CreateWebSocketClientWithClient(guestClient) + require.Nil(t, err) + defer guestWSClient.Close() + guestWSClient.Listen() + + userWSClient, err := th.CreateWebSocketClient() + require.Nil(t, err) + defer userWSClient.Close() + userWSClient.Listen() + + user := model.User{Email: th.GenerateTestEmail(), Nickname: "Corey Hulen", Password: "hello1", Username: GenerateTestUsername(), Roles: model.SYSTEM_ADMIN_ROLE_ID + " " + model.SYSTEM_USER_ROLE_ID} + + inviteId := th.BasicTeam.InviteId + + _, resp = th.Client.CreateUserWithInviteId(&user, inviteId) + CheckNoError(t, resp) + CheckCreatedStatus(t, resp) + + var userHasReceived bool + var guestHasReceived bool + + func() { + for { + select { + case ev := <-userWSClient.EventChannel: + if ev.Event == model.WEBSOCKET_EVENT_NEW_USER { + userHasReceived = true + } + case ev := <-guestWSClient.EventChannel: + if ev.Event == model.WEBSOCKET_EVENT_NEW_USER { + guestHasReceived = true + } + case <-time.After(2 * time.Second): + return + } + } + }() + + require.Truef(t, userHasReceived, "User should have received %s event", model.WEBSOCKET_EVENT_NEW_USER) + require.Falsef(t, guestHasReceived, "Guest should not have received %s event", model.WEBSOCKET_EVENT_NEW_USER) + }) +} + func TestCreateUserWithInviteId(t *testing.T) { th := Setup().InitBasic() defer th.TearDown() diff --git a/app/web_conn.go b/app/web_conn.go index 05214d0edd..839b898d7a 100644 --- a/app/web_conn.go +++ b/app/web_conn.go @@ -301,6 +301,28 @@ func (webCon *WebConn) SendHello() { webCon.Send <- msg } +func (webCon *WebConn) shouldSendEventToGuest(msg *model.WebSocketEvent) bool { + var userId string + var canSee bool + + switch msg.Event { + case model.WEBSOCKET_EVENT_USER_UPDATED: + userId = msg.Data["user"].(*model.User).Id + case model.WEBSOCKET_EVENT_NEW_USER: + userId = msg.Data["user_id"].(string) + default: + return true + } + + canSee, err := webCon.App.UserCanSeeOtherUser(webCon.UserId, userId) + if err != nil { + mlog.Error("webhub.shouldSendEvent.", mlog.Err(err)) + return false + } + + return canSee +} + func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool { // IMPORTANT: Do not send event if WebConn does not have a session if !webCon.IsAuthenticated() { @@ -369,13 +391,8 @@ func (webCon *WebConn) ShouldSendEvent(msg *model.WebSocketEvent) bool { return webCon.IsMemberOfTeam(msg.Broadcast.TeamId) } - if msg.Event == model.WEBSOCKET_EVENT_USER_UPDATED && webCon.GetSession().Props[model.SESSION_PROP_IS_GUEST] == "true" { - canSee, err := webCon.App.UserCanSeeOtherUser(webCon.UserId, msg.Data["user"].(*model.User).Id) - if err != nil { - mlog.Error("webhub.shouldSendEvent.", mlog.Err(err)) - return false - } - return canSee + if webCon.GetSession().Props[model.SESSION_PROP_IS_GUEST] == "true" { + return webCon.shouldSendEventToGuest(msg) } return true