summaryrefslogtreecommitdiffstats
path: root/matterclient/matterclient.go
diff options
context:
space:
mode:
Diffstat (limited to 'matterclient/matterclient.go')
-rw-r--r--matterclient/matterclient.go294
1 files changed, 0 insertions, 294 deletions
diff --git a/matterclient/matterclient.go b/matterclient/matterclient.go
deleted file mode 100644
index ffe88aa4..00000000
--- a/matterclient/matterclient.go
+++ /dev/null
@@ -1,294 +0,0 @@
-package matterclient
-
-import (
- "encoding/json"
- "fmt"
- "strings"
- "sync"
- "time"
-
- "github.com/gorilla/websocket"
- lru "github.com/hashicorp/golang-lru"
- "github.com/jpillora/backoff"
- prefixed "github.com/matterbridge/logrus-prefixed-formatter"
- "github.com/mattermost/mattermost-server/v5/model"
- "github.com/sirupsen/logrus"
-)
-
-type Credentials struct {
- Login string
- Team string
- Pass string
- Token string
- CookieToken bool
- Server string
- NoTLS bool
- SkipTLSVerify bool
- SkipVersionCheck bool
-}
-
-type Message struct {
- Raw *model.WebSocketEvent
- Post *model.Post
- Team string
- Channel string
- Username string
- Text string
- Type string
- UserID string
-}
-
-//nolint:golint
-type Team struct {
- Team *model.Team
- Id string
- Channels []*model.Channel
- MoreChannels []*model.Channel
- Users map[string]*model.User
-}
-
-type MMClient struct {
- sync.RWMutex
- *Credentials
-
- Team *Team
- OtherTeams []*Team
- Client *model.Client4
- User *model.User
- Users map[string]*model.User
- MessageChan chan *Message
- WsClient *websocket.Conn
- WsQuit bool
- WsAway bool
- WsConnected bool
- WsSequence int64
- WsPingChan chan *model.WebSocketResponse
- ServerVersion string
- OnWsConnect func()
-
- logger *logrus.Entry
- rootLogger *logrus.Logger
- lruCache *lru.Cache
- allevents bool
-}
-
-// New will instantiate a new Matterclient with the specified login details without connecting.
-func New(login string, pass string, team string, server string) *MMClient {
- rootLogger := logrus.New()
- rootLogger.SetFormatter(&prefixed.TextFormatter{
- PrefixPadding: 13,
- DisableColors: true,
- })
-
- cred := &Credentials{
- Login: login,
- Pass: pass,
- Team: team,
- Server: server,
- }
-
- cache, _ := lru.New(500)
- return &MMClient{
- Credentials: cred,
- MessageChan: make(chan *Message, 100),
- Users: make(map[string]*model.User),
- rootLogger: rootLogger,
- lruCache: cache,
- logger: rootLogger.WithFields(logrus.Fields{"prefix": "matterclient"}),
- }
-}
-
-// SetDebugLog activates debugging logging on all Matterclient log output.
-func (m *MMClient) SetDebugLog() {
- m.rootLogger.SetFormatter(&prefixed.TextFormatter{
- PrefixPadding: 13,
- DisableColors: true,
- FullTimestamp: false,
- ForceFormatting: true,
- })
-}
-
-// SetLogLevel tries to parse the specified level and if successful sets
-// the log level accordingly. Accepted levels are: 'debug', 'info', 'warn',
-// 'error', 'fatal' and 'panic'.
-func (m *MMClient) SetLogLevel(level string) {
- l, err := logrus.ParseLevel(level)
- if err != nil {
- m.logger.Warnf("Failed to parse specified log-level '%s': %#v", level, err)
- } else {
- m.rootLogger.SetLevel(l)
- }
-}
-
-func (m *MMClient) EnableAllEvents() {
- m.allevents = true
-}
-
-// Login tries to connect the client with the loging details with which it was initialized.
-func (m *MMClient) Login() error {
- // check if this is a first connect or a reconnection
- firstConnection := true
- if m.WsConnected {
- firstConnection = false
- }
- m.WsConnected = false
- if m.WsQuit {
- return nil
- }
- b := &backoff.Backoff{
- Min: time.Second,
- Max: 5 * time.Minute,
- Jitter: true,
- }
-
- // do initialization setup
- if err := m.initClient(firstConnection, b); err != nil {
- return err
- }
-
- if err := m.doLogin(firstConnection, b); err != nil {
- return err
- }
-
- if err := m.initUser(); err != nil {
- return err
- }
-
- if m.Team == nil {
- validTeamNames := make([]string, len(m.OtherTeams))
- for i, t := range m.OtherTeams {
- validTeamNames[i] = t.Team.Name
- }
- return fmt.Errorf("Team '%s' not found in %v", m.Credentials.Team, validTeamNames)
- }
-
- m.wsConnect()
-
- return nil
-}
-
-// Logout disconnects the client from the chat server.
-func (m *MMClient) Logout() error {
- m.logger.Debugf("logout as %s (team: %s) on %s", m.Credentials.Login, m.Credentials.Team, m.Credentials.Server)
- m.WsQuit = true
- m.WsClient.Close()
- m.WsClient.UnderlyingConn().Close()
- if strings.Contains(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN) {
- m.logger.Debug("Not invalidating session in logout, credential is a token")
- return nil
- }
- _, resp := m.Client.Logout()
- if resp.Error != nil {
- return resp.Error
- }
- return nil
-}
-
-// WsReceiver implements the core loop that manages the connection to the chat server. In
-// case of a disconnect it will try to reconnect. A call to this method is blocking until
-// the 'WsQuite' field of the MMClient object is set to 'true'.
-func (m *MMClient) WsReceiver() {
- for {
- var rawMsg json.RawMessage
- var err error
-
- if m.WsQuit {
- m.logger.Debug("exiting WsReceiver")
- return
- }
-
- if !m.WsConnected {
- time.Sleep(time.Millisecond * 100)
- continue
- }
-
- if _, rawMsg, err = m.WsClient.ReadMessage(); err != nil {
- m.logger.Error("error:", err)
- // reconnect
- m.wsConnect()
- }
-
- var event model.WebSocketEvent
- if err := json.Unmarshal(rawMsg, &event); err == nil && event.IsValid() {
- m.logger.Debugf("WsReceiver event: %#v", event)
- msg := &Message{Raw: &event, Team: m.Credentials.Team}
- m.parseMessage(msg)
- // check if we didn't empty the message
- if msg.Text != "" {
- m.MessageChan <- msg
- continue
- }
- // if we have file attached but the message is empty, also send it
- if msg.Post != nil {
- if msg.Text != "" || len(msg.Post.FileIds) > 0 || msg.Post.Type == "slack_attachment" {
- m.MessageChan <- msg
- continue
- }
- }
- if m.allevents {
- m.MessageChan <- msg
- continue
- }
- switch msg.Raw.Event {
- case model.WEBSOCKET_EVENT_USER_ADDED,
- model.WEBSOCKET_EVENT_USER_REMOVED,
- model.WEBSOCKET_EVENT_CHANNEL_CREATED,
- model.WEBSOCKET_EVENT_CHANNEL_DELETED:
- m.MessageChan <- msg
- continue
- }
- }
-
- var response model.WebSocketResponse
- if err := json.Unmarshal(rawMsg, &response); err == nil && response.IsValid() {
- m.logger.Debugf("WsReceiver response: %#v", response)
- m.parseResponse(response)
- }
- }
-}
-
-// StatusLoop implements a ping-cycle that ensures that the connection to the chat servers
-// remains alive. In case of a disconnect it will try to reconnect. A call to this method
-// is blocking until the 'WsQuite' field of the MMClient object is set to 'true'.
-func (m *MMClient) StatusLoop() {
- retries := 0
- backoff := time.Second * 60
- if m.OnWsConnect != nil {
- m.OnWsConnect()
- }
- m.logger.Debug("StatusLoop:", m.OnWsConnect != nil)
- for {
- if m.WsQuit {
- return
- }
- if m.WsConnected {
- if err := m.checkAlive(); err != nil {
- m.logger.Errorf("Connection is not alive: %#v", err)
- }
- select {
- case <-m.WsPingChan:
- m.logger.Debug("WS PONG received")
- backoff = time.Second * 60
- case <-time.After(time.Second * 5):
- if retries > 3 {
- m.logger.Debug("StatusLoop() timeout")
- m.Logout()
- m.WsQuit = false
- err := m.Login()
- if err != nil {
- m.logger.Errorf("Login failed: %#v", err)
- break
- }
- if m.OnWsConnect != nil {
- m.OnWsConnect()
- }
- go m.WsReceiver()
- } else {
- retries++
- backoff = time.Second * 5
- }
- }
- }
- time.Sleep(backoff)
- }
-}