func (m *MMClient) WsReceiver() { for { var rawMsg json.RawMessage var err error if m.WsQuit { m.log.Debug("exiting WsReceiver") return } if !m.WsConnected { time.Sleep(time.Millisecond * 100) continue } if _, rawMsg, err = m.WsClient.ReadMessage(); err != nil { m.log.Error("error:", err) // reconnect m.Login() } var event model.WebSocketEvent if err := json.Unmarshal(rawMsg, &event); err == nil && event.IsValid() { m.log.Debugf("WsReceiver: %#v", event) msg := &Message{Raw: &event, Team: m.Credentials.Team} m.parseMessage(msg) m.MessageChan <- msg continue } var response model.WebSocketResponse if err := json.Unmarshal(rawMsg, &response); err == nil && response.IsValid() { m.log.Debugf("WsReceiver: %#v", response) m.parseResponse(response) continue } } }
func TestWebSocketAuthentication(t *testing.T) { th := Setup().InitBasic() WebSocketClient, err := th.CreateWebSocketClient() if err != nil { t.Fatal(err) } WebSocketClient.Listen() time.Sleep(300 * time.Millisecond) if resp := <-WebSocketClient.ResponseChannel; resp.Status != model.STATUS_OK { t.Fatal("should have responded OK to authentication challenge") } WebSocketClient.SendMessage("ping", nil) time.Sleep(300 * time.Millisecond) if resp := <-WebSocketClient.ResponseChannel; resp.Data["text"].(string) != "pong" { t.Fatal("wrong response") } WebSocketClient.Close() authToken := WebSocketClient.AuthToken WebSocketClient.AuthToken = "junk" if err := WebSocketClient.Connect(); err != nil { t.Fatal(err) } WebSocketClient.Listen() if resp := <-WebSocketClient.ResponseChannel; resp != nil { t.Fatal("should have closed") } WebSocketClient.Close() if conn, _, err := websocket.DefaultDialer.Dial(WebSocketClient.ApiUrl+"/users/websocket", nil); err != nil { t.Fatal("should have connected") } else { req := &model.WebSocketRequest{} req.Seq = 1 req.Action = "ping" conn.WriteJSON(req) closedAutomatically := false hitNotAuthedError := false go func() { time.Sleep(10 * time.Second) conn.Close() if !closedAutomatically { t.Fatal("should have closed automatically in 5 seconds") } }() for { if _, rawMsg, err := conn.ReadMessage(); err != nil { closedAutomatically = true conn.Close() break } else { var response model.WebSocketResponse if err := json.Unmarshal(rawMsg, &response); err != nil && !response.IsValid() { t.Fatal("should not have failed") } else { if response.Error == nil || response.Error.Id != "api.web_socket_router.not_authenticated.app_error" { t.Log(response.Error.Id) t.Fatal("wrong error") continue } hitNotAuthedError = true } } } if !hitNotAuthedError { t.Fatal("should have received a not authenticated response") } } header := http.Header{} header.Set(model.HEADER_AUTH, "BEARER "+authToken) if conn, _, err := websocket.DefaultDialer.Dial(WebSocketClient.ApiUrl+"/users/websocket", header); err != nil { t.Fatal("should have connected") } else { if _, rawMsg, err := conn.ReadMessage(); err != nil { t.Fatal("should not have closed automatically") } else { var event model.WebSocketEvent if err := json.Unmarshal(rawMsg, &event); err != nil && !event.IsValid() { t.Fatal("should not have failed") } else if event.Event != model.WEBSOCKET_EVENT_HELLO { t.Log(event.ToJson()) t.Fatal("should have helloed") } } conn.Close() } }