Compare commits
	
		
			45 Commits
		
	
	
		
			v1.0.0-rc1
			...
			v1.1.2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d6ee55e35f | ||
|   | aef64eec32 | ||
|   | c4193d5ccd | ||
|   | 0c94186818 | ||
|   | 9039720013 | ||
|   | a3470f8aec | ||
|   | 01badde21d | ||
|   | a37b232dd9 | ||
|   | 579ee48385 | ||
|   | dd985d1dad | ||
|   | d2caea70a2 | ||
|   | 21143cf5ee | ||
|   | dc2aed698d | ||
|   | 37c350f19f | ||
|   | 9e03fcf162 | ||
|   | 8d4521c1df | ||
|   | 9226252336 | ||
|   | f4fb83e787 | ||
|   | e7fcb25107 | ||
|   | 5a85258f74 | ||
|   | 2f7df2df43 | ||
|   | ad3a753718 | ||
|   | e45c551880 | ||
|   | e59d338d4e | ||
|   | 7a86044f7a | ||
|   | 8b98f605bc | ||
|   | 7c773ebae0 | ||
|   | e84417430d | ||
|   | 5a8d7b5f6d | ||
|   | cfb8107138 | ||
|   | 43bd779fb7 | ||
|   | 7f9a400776 | ||
|   | ce1c5873ac | ||
|   | 85ff1995fd | ||
|   | b963f83c6a | ||
|   | f6297ebbb0 | ||
|   | a5259f56c5 | ||
|   | 3f75ed9c18 | ||
|   | 49ece51167 | ||
|   | e77c3eb20a | ||
|   | 59b2a5f8d0 | ||
|   | 28710d0bc7 | ||
|   | ad4d461606 | ||
|   | 67905089ba | ||
|   | f2483af561 | 
| @@ -1,7 +1,7 @@ | |||||||
| language: go | language: go | ||||||
| go: | go: | ||||||
|     #- 1.7.x |     #- 1.7.x | ||||||
|     - 1.8.x |     - 1.9.x | ||||||
|       # - tip |       # - tip | ||||||
|  |  | ||||||
| # we have everything vendored | # we have everything vendored | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ Has a REST API. | |||||||
|  |  | ||||||
| # Requirements | # Requirements | ||||||
| Accounts to one of the supported bridges | Accounts to one of the supported bridges | ||||||
| * [Mattermost](https://github.com/mattermost/platform/) 3.5.x - 3.10.x, 4.0.x | * [Mattermost](https://github.com/mattermost/platform/) 3.8.x - 3.10.x, 4.0.x - 4.2.x | ||||||
| * [IRC](http://www.mirc.com/servers.html) | * [IRC](http://www.mirc.com/servers.html) | ||||||
| * [XMPP](https://jabber.org) | * [XMPP](https://jabber.org) | ||||||
| * [Gitter](https://gitter.im) | * [Gitter](https://gitter.im) | ||||||
| @@ -53,7 +53,7 @@ See https://github.com/42wim/matterbridge/wiki | |||||||
|  |  | ||||||
| # Installing | # Installing | ||||||
| ## Binaries | ## Binaries | ||||||
| * Latest stable release [v1.0.0-rc1](https://github.com/42wim/matterbridge/releases/latest) | * Latest stable release [v1.1.2](https://github.com/42wim/matterbridge/releases/latest) | ||||||
| * Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)   | * Development releases (follows master) can be downloaded [here](https://dl.bintray.com/42wim/nightly/)   | ||||||
|  |  | ||||||
| ## Building | ## Building | ||||||
|   | |||||||
| @@ -61,16 +61,16 @@ func (b *Api) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
| } | } | ||||||
| func (b *Api) JoinChannel(channel string) error { | func (b *Api) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Api) Send(msg config.Message) error { | func (b *Api) Send(msg config.Message) (string, error) { | ||||||
| 	b.Lock() | 	b.Lock() | ||||||
| 	defer b.Unlock() | 	defer b.Unlock() | ||||||
| 	b.Messages.Enqueue(&msg) | 	b.Messages.Enqueue(&msg) | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Api) handlePostMessage(c echo.Context) error { | func (b *Api) handlePostMessage(c echo.Context) error { | ||||||
|   | |||||||
| @@ -19,9 +19,9 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type Bridger interface { | type Bridger interface { | ||||||
| 	Send(msg config.Message) error | 	Send(msg config.Message) (string, error) | ||||||
| 	Connect() error | 	Connect() error | ||||||
| 	JoinChannel(channel string) error | 	JoinChannel(channel config.ChannelInfo) error | ||||||
| 	Disconnect() error | 	Disconnect() error | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -92,16 +92,10 @@ func (b *Bridge) JoinChannels() error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error { | func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map[string]bool) error { | ||||||
| 	mychannel := "" |  | ||||||
| 	for ID, channel := range channels { | 	for ID, channel := range channels { | ||||||
| 		if !exists[ID] { | 		if !exists[ID] { | ||||||
| 			mychannel = channel.Name |  | ||||||
| 			log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID) | 			log.Infof("%s: joining %s (%s)", b.Account, channel.Name, ID) | ||||||
| 			if b.Protocol == "irc" && channel.Options.Key != "" { | 			err := b.JoinChannel(channel) | ||||||
| 				log.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name) |  | ||||||
| 				mychannel = mychannel + " " + channel.Options.Key |  | ||||||
| 			} |  | ||||||
| 			err := b.JoinChannel(mychannel) |  | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return err | 				return err | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ type Message struct { | |||||||
| 	Protocol  string    `json:"protocol"` | 	Protocol  string    `json:"protocol"` | ||||||
| 	Gateway   string    `json:"gateway"` | 	Gateway   string    `json:"gateway"` | ||||||
| 	Timestamp time.Time `json:"timestamp"` | 	Timestamp time.Time `json:"timestamp"` | ||||||
|  | 	ID        string    `json:"id"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type ChannelInfo struct { | type ChannelInfo struct { | ||||||
| @@ -42,6 +43,7 @@ type Protocol struct { | |||||||
| 	AuthCode               string // steam | 	AuthCode               string // steam | ||||||
| 	BindAddress            string // mattermost, slack // DEPRECATED | 	BindAddress            string // mattermost, slack // DEPRECATED | ||||||
| 	Buffer                 int    // api | 	Buffer                 int    // api | ||||||
|  | 	Charset                string // irc | ||||||
| 	EditSuffix             string // mattermost, slack, discord, telegram, gitter | 	EditSuffix             string // mattermost, slack, discord, telegram, gitter | ||||||
| 	EditDisable            bool   // mattermost, slack, discord, telegram, gitter | 	EditDisable            bool   // mattermost, slack, discord, telegram, gitter | ||||||
| 	IconURL                string // mattermost, slack | 	IconURL                string // mattermost, slack | ||||||
| @@ -77,6 +79,7 @@ type Protocol struct { | |||||||
| 	UseSASL                bool   // IRC | 	UseSASL                bool   // IRC | ||||||
| 	UseTLS                 bool   // IRC | 	UseTLS                 bool   // IRC | ||||||
| 	UseFirstName           bool   // telegram | 	UseFirstName           bool   // telegram | ||||||
|  | 	UseUserName            bool   // discord | ||||||
| 	UseInsecureURL         bool   // telegram | 	UseInsecureURL         bool   // telegram | ||||||
| 	WebhookBindAddress     string // mattermost, slack | 	WebhookBindAddress     string // mattermost, slack | ||||||
| 	WebhookURL             string // mattermost, slack | 	WebhookURL             string // mattermost, slack | ||||||
| @@ -85,6 +88,7 @@ type Protocol struct { | |||||||
|  |  | ||||||
| type ChannelOptions struct { | type ChannelOptions struct { | ||||||
| 	Key        string // irc | 	Key        string // irc | ||||||
|  | 	WebhookURL string // discord | ||||||
| } | } | ||||||
|  |  | ||||||
| type Bridge struct { | type Bridge struct { | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ type bdiscord struct { | |||||||
| 	guildID        string | 	guildID        string | ||||||
| 	webhookID      string | 	webhookID      string | ||||||
| 	webhookToken   string | 	webhookToken   string | ||||||
|  | 	channelInfoMap map[string]*config.ChannelInfo | ||||||
| 	sync.RWMutex | 	sync.RWMutex | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -37,11 +38,10 @@ func New(cfg config.Protocol, account string, c chan config.Message) *bdiscord { | |||||||
| 	b.Remote = c | 	b.Remote = c | ||||||
| 	b.Account = account | 	b.Account = account | ||||||
| 	b.userMemberMap = make(map[string]*discordgo.Member) | 	b.userMemberMap = make(map[string]*discordgo.Member) | ||||||
|  | 	b.channelInfoMap = make(map[string]*config.ChannelInfo) | ||||||
| 	if b.Config.WebhookURL != "" { | 	if b.Config.WebhookURL != "" { | ||||||
| 		flog.Debug("Configuring Discord Incoming Webhook") | 		flog.Debug("Configuring Discord Incoming Webhook") | ||||||
| 		webhookURLSplit := strings.Split(b.Config.WebhookURL, "/") | 		b.webhookID, b.webhookToken = b.splitURL(b.Config.WebhookURL) | ||||||
| 		b.webhookToken = webhookURLSplit[len(webhookURLSplit)-1] |  | ||||||
| 		b.webhookID = webhookURLSplit[len(webhookURLSplit)-2] |  | ||||||
| 	} | 	} | ||||||
| 	return b | 	return b | ||||||
| } | } | ||||||
| @@ -99,44 +99,57 @@ func (b *bdiscord) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *bdiscord) JoinChannel(channel string) error { | func (b *bdiscord) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	idcheck := strings.Split(channel, "ID:") | 	b.channelInfoMap[channel.ID] = &channel | ||||||
|  | 	idcheck := strings.Split(channel.Name, "ID:") | ||||||
| 	if len(idcheck) > 1 { | 	if len(idcheck) > 1 { | ||||||
| 		b.UseChannelID = true | 		b.UseChannelID = true | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *bdiscord) Send(msg config.Message) error { | func (b *bdiscord) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	channelID := b.getChannelID(msg.Channel) | 	channelID := b.getChannelID(msg.Channel) | ||||||
| 	if channelID == "" { | 	if channelID == "" { | ||||||
| 		flog.Errorf("Could not find channelID for %v", msg.Channel) | 		flog.Errorf("Could not find channelID for %v", msg.Channel) | ||||||
| 		return nil | 		return "", nil | ||||||
| 	} | 	} | ||||||
| 	if b.Config.WebhookURL == "" { |  | ||||||
| 		flog.Debugf("Broadcasting using token (API)") |  | ||||||
| 		if msg.Event == config.EVENT_USER_ACTION { |  | ||||||
| 			msg.Username = "_" + msg.Username |  | ||||||
| 			msg.Text = msg.Text + "_" |  | ||||||
| 		} |  | ||||||
| 		b.c.ChannelMessageSend(channelID, msg.Username+msg.Text) |  | ||||||
| 	} else { |  | ||||||
| 		flog.Debugf("Broadcasting using Webhook") |  | ||||||
| 	if msg.Event == config.EVENT_USER_ACTION { | 	if msg.Event == config.EVENT_USER_ACTION { | ||||||
| 		msg.Text = "_" + msg.Text + "_" | 		msg.Text = "_" + msg.Text + "_" | ||||||
| 	} | 	} | ||||||
| 		b.c.WebhookExecute( |  | ||||||
| 			b.webhookID, | 	wID := b.webhookID | ||||||
| 			b.webhookToken, | 	wToken := b.webhookToken | ||||||
|  | 	if ci, ok := b.channelInfoMap[msg.Channel+b.Account]; ok { | ||||||
|  | 		if ci.Options.WebhookURL != "" { | ||||||
|  | 			wID, wToken = b.splitURL(ci.Options.WebhookURL) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if wID == "" { | ||||||
|  | 		flog.Debugf("Broadcasting using token (API)") | ||||||
|  | 		if msg.ID != "" { | ||||||
|  | 			_, err := b.c.ChannelMessageEdit(channelID, msg.ID, msg.Username+msg.Text) | ||||||
|  | 			return msg.ID, err | ||||||
|  | 		} | ||||||
|  | 		res, err := b.c.ChannelMessageSend(channelID, msg.Username+msg.Text) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", err | ||||||
|  | 		} | ||||||
|  | 		return res.ID, err | ||||||
|  | 	} | ||||||
|  | 	flog.Debugf("Broadcasting using Webhook") | ||||||
|  | 	err := b.c.WebhookExecute( | ||||||
|  | 		wID, | ||||||
|  | 		wToken, | ||||||
| 		true, | 		true, | ||||||
| 		&discordgo.WebhookParams{ | 		&discordgo.WebhookParams{ | ||||||
| 			Content:   msg.Text, | 			Content:   msg.Text, | ||||||
| 			Username:  msg.Username, | 			Username:  msg.Username, | ||||||
| 			AvatarURL: msg.Avatar, | 			AvatarURL: msg.Avatar, | ||||||
| 		}) | 		}) | ||||||
| 	} | 	return "", err | ||||||
| 	return nil |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) { | func (b *bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdate) { | ||||||
| @@ -157,7 +170,7 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// if using webhooks, do not relay if it's ours | 	// if using webhooks, do not relay if it's ours | ||||||
| 	if b.Config.WebhookURL != "" && m.Author.Bot && m.Author.ID == b.webhookID { | 	if b.useWebhook() && m.Author.Bot && b.isWebhookID(m.Author.ID) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -179,13 +192,18 @@ func (b *bdiscord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreat | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	rmsg := config.Message{Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg", | 	rmsg := config.Message{Account: b.Account, Avatar: "https://cdn.discordapp.com/avatars/" + m.Author.ID + "/" + m.Author.Avatar + ".jpg", | ||||||
| 		UserID: m.Author.ID} | 		UserID: m.Author.ID, ID: m.ID} | ||||||
|  |  | ||||||
| 	rmsg.Channel = b.getChannelName(m.ChannelID) | 	rmsg.Channel = b.getChannelName(m.ChannelID) | ||||||
| 	if b.UseChannelID { | 	if b.UseChannelID { | ||||||
| 		rmsg.Channel = "ID:" + m.ChannelID | 		rmsg.Channel = "ID:" + m.ChannelID | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !b.Config.UseUserName { | ||||||
| 		rmsg.Username = b.getNick(m.Author) | 		rmsg.Username = b.getNick(m.Author) | ||||||
|  | 	} else { | ||||||
|  | 		rmsg.Username = m.Author.Username | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if b.Config.ShowEmbeds && m.Message.Embeds != nil { | 	if b.Config.ShowEmbeds && m.Message.Embeds != nil { | ||||||
| 		for _, embed := range m.Message.Embeds { | 		for _, embed := range m.Message.Embeds { | ||||||
| @@ -309,3 +327,41 @@ func (b *bdiscord) stripCustomoji(text string) string { | |||||||
| 	re := regexp.MustCompile("<(:.*?:)[0-9]+>") | 	re := regexp.MustCompile("<(:.*?:)[0-9]+>") | ||||||
| 	return re.ReplaceAllString(text, `$1`) | 	return re.ReplaceAllString(text, `$1`) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // splitURL splits a webhookURL and returns the id and token | ||||||
|  | func (b *bdiscord) splitURL(url string) (string, string) { | ||||||
|  | 	webhookURLSplit := strings.Split(url, "/") | ||||||
|  | 	return webhookURLSplit[len(webhookURLSplit)-2], webhookURLSplit[len(webhookURLSplit)-1] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // useWebhook returns true if we have a webhook defined somewhere | ||||||
|  | func (b *bdiscord) useWebhook() bool { | ||||||
|  | 	if b.Config.WebhookURL != "" { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	for _, channel := range b.channelInfoMap { | ||||||
|  | 		if channel.Options.WebhookURL != "" { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // isWebhookID returns true if the specified id is used in a defined webhook | ||||||
|  | func (b *bdiscord) isWebhookID(id string) bool { | ||||||
|  | 	if b.Config.WebhookURL != "" { | ||||||
|  | 		wID, _ := b.splitURL(b.Config.WebhookURL) | ||||||
|  | 		if wID == id { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for _, channel := range b.channelInfoMap { | ||||||
|  | 		if channel.Options.WebhookURL != "" { | ||||||
|  | 			wID, _ := b.splitURL(channel.Options.WebhookURL) | ||||||
|  | 			if wID == id { | ||||||
|  | 				return true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,9 +2,9 @@ package bgitter | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"github.com/42wim/go-gitter" | ||||||
| 	"github.com/42wim/matterbridge/bridge/config" | 	"github.com/42wim/matterbridge/bridge/config" | ||||||
| 	log "github.com/Sirupsen/logrus" | 	log "github.com/Sirupsen/logrus" | ||||||
| 	"github.com/sromku/go-gitter" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -13,6 +13,7 @@ type Bgitter struct { | |||||||
| 	Config  *config.Protocol | 	Config  *config.Protocol | ||||||
| 	Remote  chan config.Message | 	Remote  chan config.Message | ||||||
| 	Account string | 	Account string | ||||||
|  | 	User    *gitter.User | ||||||
| 	Users   []gitter.User | 	Users   []gitter.User | ||||||
| 	Rooms   []gitter.Room | 	Rooms   []gitter.Room | ||||||
| } | } | ||||||
| @@ -36,7 +37,7 @@ func (b *Bgitter) Connect() error { | |||||||
| 	var err error | 	var err error | ||||||
| 	flog.Info("Connecting") | 	flog.Info("Connecting") | ||||||
| 	b.c = gitter.New(b.Config.Token) | 	b.c = gitter.New(b.Config.Token) | ||||||
| 	_, err = b.c.GetUser() | 	b.User, err = b.c.GetUser() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		flog.Debugf("%#v", err) | 		flog.Debugf("%#v", err) | ||||||
| 		return err | 		return err | ||||||
| @@ -51,10 +52,10 @@ func (b *Bgitter) Disconnect() error { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bgitter) JoinChannel(channel string) error { | func (b *Bgitter) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	roomID, err := b.c.GetRoomId(channel) | 	roomID, err := b.c.GetRoomId(channel.Name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return fmt.Errorf("Could not find roomID for %v. Please create the room on gitter.im", channel) | 		return fmt.Errorf("Could not find roomID for %v. Please create the room on gitter.im", channel.Name) | ||||||
| 	} | 	} | ||||||
| 	room, err := b.c.GetRoom(roomID) | 	room, err := b.c.GetRoom(roomID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -78,15 +79,16 @@ func (b *Bgitter) JoinChannel(channel string) error { | |||||||
| 		for event := range stream.Event { | 		for event := range stream.Event { | ||||||
| 			switch ev := event.Data.(type) { | 			switch ev := event.Data.(type) { | ||||||
| 			case *gitter.MessageReceived: | 			case *gitter.MessageReceived: | ||||||
| 				// check for ZWSP to see if it's not an echo | 				if ev.Message.From.ID != b.User.ID { | ||||||
| 				if !strings.HasSuffix(ev.Message.Text, "") { |  | ||||||
| 					flog.Debugf("Sending message from %s on %s to gateway", ev.Message.From.Username, b.Account) | 					flog.Debugf("Sending message from %s on %s to gateway", ev.Message.From.Username, b.Account) | ||||||
| 					rmsg := config.Message{Username: ev.Message.From.Username, Text: ev.Message.Text, Channel: room, | 					rmsg := config.Message{Username: ev.Message.From.Username, Text: ev.Message.Text, Channel: room, | ||||||
| 						Account: b.Account, Avatar: b.getAvatar(ev.Message.From.Username), UserID: ev.Message.From.ID} | 						Account: b.Account, Avatar: b.getAvatar(ev.Message.From.Username), UserID: ev.Message.From.ID, | ||||||
|  | 						ID: ev.Message.ID} | ||||||
| 					if strings.HasPrefix(ev.Message.Text, "@"+ev.Message.From.Username) { | 					if strings.HasPrefix(ev.Message.Text, "@"+ev.Message.From.Username) { | ||||||
| 						rmsg.Event = config.EVENT_USER_ACTION | 						rmsg.Event = config.EVENT_USER_ACTION | ||||||
| 						rmsg.Text = strings.Replace(rmsg.Text, "@"+ev.Message.From.Username+" ", "", -1) | 						rmsg.Text = strings.Replace(rmsg.Text, "@"+ev.Message.From.Username+" ", "", -1) | ||||||
| 					} | 					} | ||||||
|  | 					flog.Debugf("Message is %#v", rmsg) | ||||||
| 					b.Remote <- rmsg | 					b.Remote <- rmsg | ||||||
| 				} | 				} | ||||||
| 			case *gitter.GitterConnectionClosed: | 			case *gitter.GitterConnectionClosed: | ||||||
| @@ -97,15 +99,26 @@ func (b *Bgitter) JoinChannel(channel string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bgitter) Send(msg config.Message) error { | func (b *Bgitter) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	roomID := b.getRoomID(msg.Channel) | 	roomID := b.getRoomID(msg.Channel) | ||||||
| 	if roomID == "" { | 	if roomID == "" { | ||||||
| 		flog.Errorf("Could not find roomID for %v", msg.Channel) | 		flog.Errorf("Could not find roomID for %v", msg.Channel) | ||||||
| 		return nil | 		return "", nil | ||||||
| 	} | 	} | ||||||
| 	// add ZWSP because gitter echoes our own messages | 	if msg.ID != "" { | ||||||
| 	return b.c.SendMessage(roomID, msg.Username+msg.Text+" ") | 		flog.Debugf("updating message with id %s", msg.ID) | ||||||
|  | 		_, err := b.c.UpdateMessage(roomID, msg.ID, msg.Username+msg.Text) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", err | ||||||
|  | 		} | ||||||
|  | 		return "", nil | ||||||
|  | 	} | ||||||
|  | 	resp, err := b.c.SendMessage(roomID, msg.Username+msg.Text) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return resp.ID, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bgitter) getRoomID(channel string) string { | func (b *Bgitter) getRoomID(channel string) string { | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| package birc | package birc | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"crypto/tls" | 	"crypto/tls" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/42wim/go-ircevent" | 	"github.com/42wim/go-ircevent" | ||||||
| @@ -117,16 +118,34 @@ func (b *Birc) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Birc) JoinChannel(channel string) error { | func (b *Birc) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	b.i.Join(channel) | 	if channel.Options.Key != "" { | ||||||
|  | 		flog.Debugf("using key %s for channel %s", channel.Options.Key, channel.Name) | ||||||
|  | 		b.i.Join(channel.Name + " " + channel.Options.Key) | ||||||
|  | 	} else { | ||||||
|  | 		b.i.Join(channel.Name) | ||||||
|  | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Birc) Send(msg config.Message) error { | func (b *Birc) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	if strings.HasPrefix(msg.Text, "!") { | 	if strings.HasPrefix(msg.Text, "!") { | ||||||
| 		b.Command(&msg) | 		b.Command(&msg) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if b.Config.Charset != "" { | ||||||
|  | 		buf := new(bytes.Buffer) | ||||||
|  | 		w, err := charset.NewWriter(b.Config.Charset, buf) | ||||||
|  | 		if err != nil { | ||||||
|  | 			flog.Errorf("charset from utf-8 conversion failed: %s", err) | ||||||
|  | 			return "", err | ||||||
|  | 		} | ||||||
|  | 		fmt.Fprintf(w, msg.Text) | ||||||
|  | 		w.Close() | ||||||
|  | 		msg.Text = buf.String() | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	for _, text := range strings.Split(msg.Text, "\n") { | 	for _, text := range strings.Split(msg.Text, "\n") { | ||||||
| 		if len(text) > b.Config.MessageLength { | 		if len(text) > b.Config.MessageLength { | ||||||
| 			text = text[:b.Config.MessageLength] + " <message clipped>" | 			text = text[:b.Config.MessageLength] + " <message clipped>" | ||||||
| @@ -140,7 +159,7 @@ func (b *Birc) Send(msg config.Message) error { | |||||||
| 			flog.Debugf("flooding, dropping message (queue at %d)", len(b.Local)) | 			flog.Debugf("flooding, dropping message (queue at %d)", len(b.Local)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Birc) doSend() { | func (b *Birc) doSend() { | ||||||
| @@ -260,6 +279,10 @@ func (b *Birc) handlePrivMsg(event *irc.Event) { | |||||||
| 	re := regexp.MustCompile(`[[:cntrl:]](\d+,|)\d+`) | 	re := regexp.MustCompile(`[[:cntrl:]](\d+,|)\d+`) | ||||||
| 	msg = re.ReplaceAllString(msg, "") | 	msg = re.ReplaceAllString(msg, "") | ||||||
|  |  | ||||||
|  | 	var r io.Reader | ||||||
|  | 	var err error | ||||||
|  | 	mycharset := b.Config.Charset | ||||||
|  | 	if mycharset == "" { | ||||||
| 		// detect what were sending so that we convert it to utf-8 | 		// detect what were sending so that we convert it to utf-8 | ||||||
| 		detector := chardet.NewTextDetector() | 		detector := chardet.NewTextDetector() | ||||||
| 		result, err := detector.DetectBest([]byte(msg)) | 		result, err := detector.DetectBest([]byte(msg)) | ||||||
| @@ -268,12 +291,13 @@ func (b *Birc) handlePrivMsg(event *irc.Event) { | |||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		flog.Debugf("detected %s confidence %#v", result.Charset, result.Confidence) | 		flog.Debugf("detected %s confidence %#v", result.Charset, result.Confidence) | ||||||
| 	var r io.Reader | 		mycharset = result.Charset | ||||||
| 	r, err = charset.NewReader(result.Charset, strings.NewReader(msg)) |  | ||||||
| 		// if we're not sure, just pick ISO-8859-1 | 		// if we're not sure, just pick ISO-8859-1 | ||||||
| 		if result.Confidence < 80 { | 		if result.Confidence < 80 { | ||||||
| 		r, err = charset.NewReader("ISO-8859-1", strings.NewReader(msg)) | 			mycharset = "ISO-8859-1" | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  | 	r, err = charset.NewReader(mycharset, strings.NewReader(msg)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		flog.Errorf("charset to utf-8 conversion failed: %s", err) | 		flog.Errorf("charset to utf-8 conversion failed: %s", err) | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -63,28 +63,28 @@ func (b *Bmatrix) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmatrix) JoinChannel(channel string) error { | func (b *Bmatrix) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	resp, err := b.mc.JoinRoom(channel, "", nil) | 	resp, err := b.mc.JoinRoom(channel.Name, "", nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	b.Lock() | 	b.Lock() | ||||||
| 	b.RoomMap[resp.RoomID] = channel | 	b.RoomMap[resp.RoomID] = channel.Name | ||||||
| 	b.Unlock() | 	b.Unlock() | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmatrix) Send(msg config.Message) error { | func (b *Bmatrix) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	channel := b.getRoomID(msg.Channel) | 	channel := b.getRoomID(msg.Channel) | ||||||
| 	flog.Debugf("Sending to channel %s", channel) | 	flog.Debugf("Sending to channel %s", channel) | ||||||
| 	if msg.Event == config.EVENT_USER_ACTION { | 	if msg.Event == config.EVENT_USER_ACTION { | ||||||
| 		b.mc.SendMessageEvent(channel, "m.room.message", | 		b.mc.SendMessageEvent(channel, "m.room.message", | ||||||
| 			matrix.TextMessage{"m.emote", msg.Username + msg.Text}) | 			matrix.TextMessage{"m.emote", msg.Username + msg.Text}) | ||||||
| 		return nil | 		return "", nil | ||||||
| 	} | 	} | ||||||
| 	b.mc.SendText(channel, msg.Username+msg.Text) | 	b.mc.SendText(channel, msg.Username+msg.Text) | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmatrix) getRoomID(channel string) string { | func (b *Bmatrix) getRoomID(channel string) string { | ||||||
| @@ -100,7 +100,7 @@ func (b *Bmatrix) getRoomID(channel string) string { | |||||||
| func (b *Bmatrix) handlematrix() error { | func (b *Bmatrix) handlematrix() error { | ||||||
| 	syncer := b.mc.Syncer.(*matrix.DefaultSyncer) | 	syncer := b.mc.Syncer.(*matrix.DefaultSyncer) | ||||||
| 	syncer.OnEventType("m.room.message", func(ev *matrix.Event) { | 	syncer.OnEventType("m.room.message", func(ev *matrix.Event) { | ||||||
| 		if (ev.Content["msgtype"].(string) == "m.text" || ev.Content["msgtype"].(string) == "m.emote") && ev.Sender != b.UserID { | 		if (ev.Content["msgtype"].(string) == "m.text" || ev.Content["msgtype"].(string) == "m.notice" || ev.Content["msgtype"].(string) == "m.emote") && ev.Sender != b.UserID { | ||||||
| 			b.RLock() | 			b.RLock() | ||||||
| 			channel, ok := b.RoomMap[ev.RoomID] | 			channel, ok := b.RoomMap[ev.RoomID] | ||||||
| 			b.RUnlock() | 			b.RUnlock() | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package bmattermost | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
|  | 	"fmt" | ||||||
| 	"github.com/42wim/matterbridge/bridge/config" | 	"github.com/42wim/matterbridge/bridge/config" | ||||||
| 	"github.com/42wim/matterbridge/matterclient" | 	"github.com/42wim/matterbridge/matterclient" | ||||||
| 	"github.com/42wim/matterbridge/matterhook" | 	"github.com/42wim/matterbridge/matterhook" | ||||||
| @@ -23,6 +24,7 @@ type MMMessage struct { | |||||||
| 	Channel  string | 	Channel  string | ||||||
| 	Username string | 	Username string | ||||||
| 	UserID   string | 	UserID   string | ||||||
|  | 	ID       string | ||||||
| } | } | ||||||
|  |  | ||||||
| type Bmattermost struct { | type Bmattermost struct { | ||||||
| @@ -61,6 +63,12 @@ func (b *Bmattermost) Connect() error { | |||||||
| 			b.mh = matterhook.New(b.Config.WebhookURL, | 			b.mh = matterhook.New(b.Config.WebhookURL, | ||||||
| 				matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify, | 				matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify, | ||||||
| 					BindAddress: b.Config.WebhookBindAddress}) | 					BindAddress: b.Config.WebhookBindAddress}) | ||||||
|  | 		} else if b.Config.Token != "" { | ||||||
|  | 			flog.Info("Connecting using token (sending)") | ||||||
|  | 			err := b.apiLogin() | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
| 		} else if b.Config.Login != "" { | 		} else if b.Config.Login != "" { | ||||||
| 			flog.Info("Connecting using login/password (sending)") | 			flog.Info("Connecting using login/password (sending)") | ||||||
| 			err := b.apiLogin() | 			err := b.apiLogin() | ||||||
| @@ -81,7 +89,14 @@ func (b *Bmattermost) Connect() error { | |||||||
| 		b.mh = matterhook.New(b.Config.WebhookURL, | 		b.mh = matterhook.New(b.Config.WebhookURL, | ||||||
| 			matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify, | 			matterhook.Config{InsecureSkipVerify: b.Config.SkipTLSVerify, | ||||||
| 				DisableServer: true}) | 				DisableServer: true}) | ||||||
| 		if b.Config.Login != "" { | 		if b.Config.Token != "" { | ||||||
|  | 			flog.Info("Connecting using token (receiving)") | ||||||
|  | 			err := b.apiLogin() | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			go b.handleMatter() | ||||||
|  | 		} else if b.Config.Login != "" { | ||||||
| 			flog.Info("Connecting using login/password (receiving)") | 			flog.Info("Connecting using login/password (receiving)") | ||||||
| 			err := b.apiLogin() | 			err := b.apiLogin() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| @@ -90,6 +105,13 @@ func (b *Bmattermost) Connect() error { | |||||||
| 			go b.handleMatter() | 			go b.handleMatter() | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return nil | ||||||
|  | 	} else if b.Config.Token != "" { | ||||||
|  | 		flog.Info("Connecting using token (sending and receiving)") | ||||||
|  | 		err := b.apiLogin() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  | 		go b.handleMatter() | ||||||
| 	} else if b.Config.Login != "" { | 	} else if b.Config.Login != "" { | ||||||
| 		flog.Info("Connecting using login/password (sending and receiving)") | 		flog.Info("Connecting using login/password (sending and receiving)") | ||||||
| 		err := b.apiLogin() | 		err := b.apiLogin() | ||||||
| @@ -98,8 +120,8 @@ func (b *Bmattermost) Connect() error { | |||||||
| 		} | 		} | ||||||
| 		go b.handleMatter() | 		go b.handleMatter() | ||||||
| 	} | 	} | ||||||
| 	if b.Config.WebhookBindAddress == "" && b.Config.WebhookURL == "" && b.Config.Login == "" { | 	if b.Config.WebhookBindAddress == "" && b.Config.WebhookURL == "" && b.Config.Login == "" && b.Config.Token == "" { | ||||||
| 		return errors.New("No connection method found. See that you have WebhookBindAddress, WebhookURL or Login/Password/Server/Team configured.") | 		return errors.New("No connection method found. See that you have WebhookBindAddress, WebhookURL or Token/Login/Password/Server/Team configured.") | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -108,15 +130,19 @@ func (b *Bmattermost) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmattermost) JoinChannel(channel string) error { | func (b *Bmattermost) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	// we can only join channels using the API | 	// we can only join channels using the API | ||||||
| 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | ||||||
| 		return b.mc.JoinChannel(b.mc.GetChannelId(channel, "")) | 		id := b.mc.GetChannelId(channel.Name, "") | ||||||
|  | 		if id == "" { | ||||||
|  | 			return fmt.Errorf("Could not find channel ID for channel %s", channel.Name) | ||||||
|  | 		} | ||||||
|  | 		return b.mc.JoinChannel(id) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmattermost) Send(msg config.Message) error { | func (b *Bmattermost) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	if msg.Event == config.EVENT_USER_ACTION { | 	if msg.Event == config.EVENT_USER_ACTION { | ||||||
| 		msg.Text = "*" + msg.Text + "*" | 		msg.Text = "*" + msg.Text + "*" | ||||||
| @@ -138,12 +164,14 @@ func (b *Bmattermost) Send(msg config.Message) error { | |||||||
| 		err := b.mh.Send(matterMessage) | 		err := b.mh.Send(matterMessage) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			flog.Info(err) | 			flog.Info(err) | ||||||
| 			return err | 			return "", err | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return "", nil | ||||||
| 	} | 	} | ||||||
| 	b.mc.PostMessage(b.mc.GetChannelId(channel, ""), message) | 	if msg.ID != "" { | ||||||
| 	return nil | 		return b.mc.EditMessage(msg.ID, message) | ||||||
|  | 	} | ||||||
|  | 	return b.mc.PostMessage(b.mc.GetChannelId(channel, ""), message) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmattermost) handleMatter() { | func (b *Bmattermost) handleMatter() { | ||||||
| @@ -151,18 +179,23 @@ func (b *Bmattermost) handleMatter() { | |||||||
| 	if b.Config.WebhookBindAddress != "" { | 	if b.Config.WebhookBindAddress != "" { | ||||||
| 		flog.Debugf("Choosing webhooks based receiving") | 		flog.Debugf("Choosing webhooks based receiving") | ||||||
| 		go b.handleMatterHook(mchan) | 		go b.handleMatterHook(mchan) | ||||||
|  | 	} else { | ||||||
|  | 		if b.Config.Token != "" { | ||||||
|  | 			flog.Debugf("Choosing token based receiving") | ||||||
| 		} else { | 		} else { | ||||||
| 			flog.Debugf("Choosing login/password based receiving") | 			flog.Debugf("Choosing login/password based receiving") | ||||||
|  | 		} | ||||||
| 		go b.handleMatterClient(mchan) | 		go b.handleMatterClient(mchan) | ||||||
| 	} | 	} | ||||||
| 	for message := range mchan { | 	for message := range mchan { | ||||||
| 		rmsg := config.Message{Username: message.Username, Channel: message.Channel, Account: b.Account, UserID: message.UserID} | 		rmsg := config.Message{Username: message.Username, Channel: message.Channel, Account: b.Account, UserID: message.UserID, ID: message.ID} | ||||||
| 		text, ok := b.replaceAction(message.Text) | 		text, ok := b.replaceAction(message.Text) | ||||||
| 		if ok { | 		if ok { | ||||||
| 			rmsg.Event = config.EVENT_USER_ACTION | 			rmsg.Event = config.EVENT_USER_ACTION | ||||||
| 		} | 		} | ||||||
| 		rmsg.Text = text | 		rmsg.Text = text | ||||||
| 		flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account) | 		flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account) | ||||||
|  | 		flog.Debugf("Message is %#v", rmsg) | ||||||
| 		b.Remote <- rmsg | 		b.Remote <- rmsg | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -194,6 +227,7 @@ func (b *Bmattermost) handleMatterClient(mchan chan *MMMessage) { | |||||||
| 			m.Username = message.Username | 			m.Username = message.Username | ||||||
| 			m.Channel = message.Channel | 			m.Channel = message.Channel | ||||||
| 			m.Text = message.Text | 			m.Text = message.Text | ||||||
|  | 			m.ID = message.Post.Id | ||||||
| 			if message.Raw.Event == "post_edited" && !b.Config.EditDisable { | 			if message.Raw.Event == "post_edited" && !b.Config.EditDisable { | ||||||
| 				m.Text = message.Text + b.Config.EditSuffix | 				m.Text = message.Text + b.Config.EditSuffix | ||||||
| 			} | 			} | ||||||
| @@ -221,7 +255,12 @@ func (b *Bmattermost) handleMatterHook(mchan chan *MMMessage) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bmattermost) apiLogin() error { | func (b *Bmattermost) apiLogin() error { | ||||||
| 	b.mc = matterclient.New(b.Config.Login, b.Config.Password, | 	password := b.Config.Password | ||||||
|  | 	if b.Config.Token != "" { | ||||||
|  | 		password = "MMAUTHTOKEN=" + b.Config.Token | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	b.mc = matterclient.New(b.Config.Login, password, | ||||||
| 		b.Config.Team, b.Config.Server) | 		b.Config.Team, b.Config.Server) | ||||||
| 	b.mc.SkipTLSVerify = b.Config.SkipTLSVerify | 	b.mc.SkipTLSVerify = b.Config.SkipTLSVerify | ||||||
| 	b.mc.NoTLS = b.Config.NoTLS | 	b.mc.NoTLS = b.Config.NoTLS | ||||||
|   | |||||||
| @@ -53,11 +53,11 @@ func (b *Brocketchat) Disconnect() error { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Brocketchat) JoinChannel(channel string) error { | func (b *Brocketchat) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Brocketchat) Send(msg config.Message) error { | func (b *Brocketchat) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL} | 	matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL} | ||||||
| 	matterMessage.Channel = msg.Channel | 	matterMessage.Channel = msg.Channel | ||||||
| @@ -67,9 +67,9 @@ func (b *Brocketchat) Send(msg config.Message) error { | |||||||
| 	err := b.mh.Send(matterMessage) | 	err := b.mh.Send(matterMessage) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		flog.Info(err) | 		flog.Info(err) | ||||||
| 		return err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Brocketchat) handleRocketHook() { | func (b *Brocketchat) handleRocketHook() { | ||||||
|   | |||||||
| @@ -108,14 +108,14 @@ func (b *Bslack) Disconnect() error { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bslack) JoinChannel(channel string) error { | func (b *Bslack) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	// we can only join channels using the API | 	// we can only join channels using the API | ||||||
| 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | 	if b.Config.WebhookURL == "" && b.Config.WebhookBindAddress == "" { | ||||||
| 		if strings.HasPrefix(b.Config.Token, "xoxb") { | 		if strings.HasPrefix(b.Config.Token, "xoxb") { | ||||||
| 			// TODO check if bot has already joined channel | 			// TODO check if bot has already joined channel | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 		_, err := b.sc.JoinChannel(channel) | 		_, err := b.sc.JoinChannel(channel.Name) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if err.Error() != "name_taken" { | 			if err.Error() != "name_taken" { | ||||||
| 				return err | 				return err | ||||||
| @@ -125,7 +125,7 @@ func (b *Bslack) JoinChannel(channel string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bslack) Send(msg config.Message) error { | func (b *Bslack) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	if msg.Event == config.EVENT_USER_ACTION { | 	if msg.Event == config.EVENT_USER_ACTION { | ||||||
| 		msg.Text = "_" + msg.Text + "_" | 		msg.Text = "_" + msg.Text + "_" | ||||||
| @@ -145,13 +145,13 @@ func (b *Bslack) Send(msg config.Message) error { | |||||||
| 		err := b.mh.Send(matterMessage) | 		err := b.mh.Send(matterMessage) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			flog.Info(err) | 			flog.Info(err) | ||||||
| 			return err | 			return "", err | ||||||
| 		} | 		} | ||||||
| 		return nil | 		return "", nil | ||||||
| 	} | 	} | ||||||
| 	schannel, err := b.getChannelByName(channel) | 	schannel, err := b.getChannelByName(channel) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	np := slack.NewPostMessageParameters() | 	np := slack.NewPostMessageParameters() | ||||||
| 	if b.Config.PrefixMessagesWithNick { | 	if b.Config.PrefixMessagesWithNick { | ||||||
| @@ -163,14 +163,20 @@ func (b *Bslack) Send(msg config.Message) error { | |||||||
| 		np.IconURL = msg.Avatar | 		np.IconURL = msg.Avatar | ||||||
| 	} | 	} | ||||||
| 	np.Attachments = append(np.Attachments, slack.Attachment{CallbackID: "matterbridge"}) | 	np.Attachments = append(np.Attachments, slack.Attachment{CallbackID: "matterbridge"}) | ||||||
| 	b.sc.PostMessage(schannel.ID, message, np) | 	// replace mentions | ||||||
|  | 	np.LinkNames = 1 | ||||||
|  |  | ||||||
| 	/* | 	// if we have no ID it means we're creating a new message, not updating an existing one | ||||||
| 	   newmsg := b.rtm.NewOutgoingMessage(message, schannel.ID) | 	if msg.ID != "" { | ||||||
| 	   b.rtm.SendMessage(newmsg) | 		ts := strings.Fields(msg.ID) | ||||||
| 	*/ | 		b.sc.UpdateMessage(schannel.ID, ts[1], message) | ||||||
|  | 		return "", nil | ||||||
| 	return nil | 	} | ||||||
|  | 	_, id, err := b.sc.PostMessage(schannel.ID, message, np) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return "slack " + id, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bslack) getAvatar(user string) string { | func (b *Bslack) getAvatar(user string) string { | ||||||
| @@ -233,22 +239,27 @@ func (b *Bslack) handleSlack() { | |||||||
| 			text = b.replaceURL(text) | 			text = b.replaceURL(text) | ||||||
| 			text = html.UnescapeString(text) | 			text = html.UnescapeString(text) | ||||||
| 			flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account) | 			flog.Debugf("Sending message from %s on %s to gateway", message.Username, b.Account) | ||||||
| 			msg := config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username), UserID: message.UserID} | 			msg := config.Message{Text: text, Username: message.Username, Channel: message.Channel, Account: b.Account, Avatar: b.getAvatar(message.Username), UserID: message.UserID, ID: "slack " + message.Raw.Timestamp} | ||||||
| 			if message.Raw.SubType == "me_message" { | 			if message.Raw.SubType == "me_message" { | ||||||
| 				msg.Event = config.EVENT_USER_ACTION | 				msg.Event = config.EVENT_USER_ACTION | ||||||
| 			} | 			} | ||||||
|  | 			if message.Raw.SubType == "channel_leave" || message.Raw.SubType == "channel_join" { | ||||||
|  | 				msg.Username = "system" | ||||||
|  | 				msg.Event = config.EVENT_JOIN_LEAVE | ||||||
|  | 			} | ||||||
|  | 			// edited messages have a submessage, use this timestamp | ||||||
|  | 			if message.Raw.SubMessage != nil { | ||||||
|  | 				msg.ID = "slack " + message.Raw.SubMessage.Timestamp | ||||||
|  | 			} | ||||||
| 			b.Remote <- msg | 			b.Remote <- msg | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bslack) handleSlackClient(mchan chan *MMMessage) { | func (b *Bslack) handleSlackClient(mchan chan *MMMessage) { | ||||||
| 	count := 0 |  | ||||||
| 	for msg := range b.rtm.IncomingEvents { | 	for msg := range b.rtm.IncomingEvents { | ||||||
| 		switch ev := msg.Data.(type) { | 		switch ev := msg.Data.(type) { | ||||||
| 		case *slack.MessageEvent: | 		case *slack.MessageEvent: | ||||||
| 			// ignore first message |  | ||||||
| 			if count > 0 { |  | ||||||
| 			flog.Debugf("Receiving from slackclient %#v", ev) | 			flog.Debugf("Receiving from slackclient %#v", ev) | ||||||
| 			if len(ev.Attachments) > 0 { | 			if len(ev.Attachments) > 0 { | ||||||
| 				// skip messages we made ourselves | 				// skip messages we made ourselves | ||||||
| @@ -300,8 +311,6 @@ func (b *Bslack) handleSlackClient(mchan chan *MMMessage) { | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			mchan <- m | 			mchan <- m | ||||||
| 			} |  | ||||||
| 			count++ |  | ||||||
| 		case *slack.OutgoingErrorEvent: | 		case *slack.OutgoingErrorEvent: | ||||||
| 			flog.Debugf("%#v", ev.Error()) | 			flog.Debugf("%#v", ev.Error()) | ||||||
| 		case *slack.ChannelJoinedEvent: | 		case *slack.ChannelJoinedEvent: | ||||||
|   | |||||||
| @@ -60,8 +60,8 @@ func (b *Bsteam) Disconnect() error { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bsteam) JoinChannel(channel string) error { | func (b *Bsteam) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	id, err := steamid.NewId(channel) | 	id, err := steamid.NewId(channel.Name) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| @@ -69,13 +69,13 @@ func (b *Bsteam) JoinChannel(channel string) error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bsteam) Send(msg config.Message) error { | func (b *Bsteam) Send(msg config.Message) (string, error) { | ||||||
| 	id, err := steamid.NewId(msg.Channel) | 	id, err := steamid.NewId(msg.Channel) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return "", err | ||||||
| 	} | 	} | ||||||
| 	b.c.Social.SendMessage(id, steamlang.EChatEntryType_ChatMsg, msg.Username+msg.Text) | 	b.c.Social.SendMessage(id, steamlang.EChatEntryType_ChatMsg, msg.Username+msg.Text) | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bsteam) getNick(id steamid.SteamId) string { | func (b *Bsteam) getNick(id steamid.SteamId) string { | ||||||
|   | |||||||
| @@ -53,26 +53,45 @@ func (b *Btelegram) Disconnect() error { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Btelegram) JoinChannel(channel string) error { | func (b *Btelegram) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Btelegram) Send(msg config.Message) error { | func (b *Btelegram) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	chatid, err := strconv.ParseInt(msg.Channel, 10, 64) | 	chatid, err := strconv.ParseInt(msg.Channel, 10, 64) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return "", err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if b.Config.MessageFormat == "HTML" { | 	if b.Config.MessageFormat == "HTML" { | ||||||
| 		msg.Text = makeHTML(msg.Text) | 		msg.Text = makeHTML(msg.Text) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// edit the message if we have a msg ID | ||||||
|  | 	if msg.ID != "" { | ||||||
|  | 		msgid, err := strconv.Atoi(msg.ID) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", err | ||||||
|  | 		} | ||||||
|  | 		m := tgbotapi.NewEditMessageText(chatid, msgid, msg.Username+msg.Text) | ||||||
|  | 		_, err = b.c.Send(m) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", err | ||||||
|  | 		} | ||||||
|  | 		return "", nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	m := tgbotapi.NewMessage(chatid, msg.Username+msg.Text) | 	m := tgbotapi.NewMessage(chatid, msg.Username+msg.Text) | ||||||
| 	if b.Config.MessageFormat == "HTML" { | 	if b.Config.MessageFormat == "HTML" { | ||||||
| 		m.ParseMode = tgbotapi.ModeHTML | 		m.ParseMode = tgbotapi.ModeHTML | ||||||
| 	} | 	} | ||||||
| 	_, err = b.c.Send(m) | 	res, err := b.c.Send(m) | ||||||
| 	return err | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return strconv.Itoa(res.MessageID), nil | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | ||||||
| @@ -131,7 +150,7 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) { | |||||||
| 		} | 		} | ||||||
| 		if text != "" { | 		if text != "" { | ||||||
| 			flog.Debugf("Sending message from %s on %s to gateway", username, b.Account) | 			flog.Debugf("Sending message from %s on %s to gateway", username, b.Account) | ||||||
| 			b.Remote <- config.Message{Username: username, Text: text, Channel: channel, Account: b.Account, UserID: strconv.Itoa(message.From.ID)} | 			b.Remote <- config.Message{Username: username, Text: text, Channel: channel, Account: b.Account, UserID: strconv.Itoa(message.From.ID), ID: strconv.Itoa(message.MessageID)} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -74,15 +74,15 @@ func (b *Bxmpp) Disconnect() error { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bxmpp) JoinChannel(channel string) error { | func (b *Bxmpp) JoinChannel(channel config.ChannelInfo) error { | ||||||
| 	b.xc.JoinMUCNoHistory(channel+"@"+b.Config.Muc, b.Config.Nick) | 	b.xc.JoinMUCNoHistory(channel.Name+"@"+b.Config.Muc, b.Config.Nick) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bxmpp) Send(msg config.Message) error { | func (b *Bxmpp) Send(msg config.Message) (string, error) { | ||||||
| 	flog.Debugf("Receiving %#v", msg) | 	flog.Debugf("Receiving %#v", msg) | ||||||
| 	b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text}) | 	b.xc.Send(xmpp.Chat{Type: "groupchat", Remote: msg.Channel + "@" + b.Config.Muc, Text: msg.Username + msg.Text}) | ||||||
| 	return nil | 	return "", nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (b *Bxmpp) createXMPP() (*xmpp.Client, error) { | func (b *Bxmpp) createXMPP() (*xmpp.Client, error) { | ||||||
|   | |||||||
							
								
								
									
										36
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								changelog.md
									
									
									
									
									
								
							| @@ -1,3 +1,39 @@ | |||||||
|  | # v1.1.2 | ||||||
|  | * general: also build darwin binaries | ||||||
|  | * mattermost: add support for mattermost 4.2.x | ||||||
|  | * mattermost: Send images when text is empty regression. (mattermost). Closes #254 | ||||||
|  | * slack: also send the first messsage after connect. #252 | ||||||
|  |  | ||||||
|  | # v1.1.1 | ||||||
|  | ## Bugfix | ||||||
|  | * mattermost: fix public links | ||||||
|  |  | ||||||
|  | # v1.1.0 | ||||||
|  | ## New features | ||||||
|  | * general: Add better editing support. (actually edit the messages on bridges that support it) | ||||||
|  | 	(mattermost,discord,gitter,slack,telegram) | ||||||
|  | * mattermost: use API v4 (removes support for mattermost < 3.8) | ||||||
|  | * mattermost: add support for personal access tokens (since mattermost 4.1) | ||||||
|  | 	Use ```Token="yourtoken"``` in mattermost config | ||||||
|  | 	See https://docs.mattermost.com/developer/personal-access-tokens.html for more info | ||||||
|  | * matrix: Relay notices (matrix). Closes #243 | ||||||
|  | * irc: Add a charset option. Closes #247 | ||||||
|  |  | ||||||
|  | ## Bugfix | ||||||
|  | * slack: Handle leave/join events (slack). Closes #246 | ||||||
|  | * slack: Replace mentions from other bridges. (slack). Closes #233 | ||||||
|  | * gitter: remove ZWSP after messages | ||||||
|  |  | ||||||
|  | # v1.0.1 | ||||||
|  | ## New features | ||||||
|  | * mattermost: add support for mattermost 4.1.x | ||||||
|  | * discord: allow a webhookURL per channel #239 | ||||||
|  |  | ||||||
|  | # v1.0.0 | ||||||
|  | ## New features | ||||||
|  | * general: Add action support for slack,mattermost,irc,gitter,matrix,xmpp,discord. #199 | ||||||
|  | * discord: Shows the username instead of the server nickname #234 | ||||||
|  |  | ||||||
| # v1.0.0-rc1 | # v1.0.0-rc1 | ||||||
| ## New features | ## New features | ||||||
| * general: Add action support for slack,mattermost,irc,gitter,matrix,xmpp,discord. #199 | * general: Add action support for slack,mattermost,irc,gitter,matrix,xmpp,discord. #199 | ||||||
|   | |||||||
| @@ -1,10 +1,11 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| go version |grep go1.8 || exit | go version |grep go1.9 || exit | ||||||
| VERSION=$(git describe --tags) | VERSION=$(git describe --tags) | ||||||
| mkdir ci/binaries | mkdir ci/binaries | ||||||
| GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-win64.exe | GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-windows-amd64.exe | ||||||
| GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux64 | GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-amd64 | ||||||
| GOOS=linux GOARCH=arm go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-arm | GOOS=linux GOARCH=arm go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-linux-arm | ||||||
|  | GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X main.githash=$(git log --pretty=format:'%h' -n 1)" -o ci/binaries/matterbridge-$VERSION-darwin-amd64 | ||||||
| cd ci | cd ci | ||||||
| cat > deploy.json <<EOF | cat > deploy.json <<EOF | ||||||
| { | { | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import ( | |||||||
| 	"github.com/42wim/matterbridge/bridge/config" | 	"github.com/42wim/matterbridge/bridge/config" | ||||||
| 	log "github.com/Sirupsen/logrus" | 	log "github.com/Sirupsen/logrus" | ||||||
| 	//	"github.com/davecgh/go-spew/spew" | 	//	"github.com/davecgh/go-spew/spew" | ||||||
|  | 	"github.com/hashicorp/golang-lru" | ||||||
| 	"github.com/peterhellberg/emojilib" | 	"github.com/peterhellberg/emojilib" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| @@ -21,11 +22,19 @@ type Gateway struct { | |||||||
| 	ChannelOptions map[string]config.ChannelOptions | 	ChannelOptions map[string]config.ChannelOptions | ||||||
| 	Message        chan config.Message | 	Message        chan config.Message | ||||||
| 	Name           string | 	Name           string | ||||||
|  | 	Messages       *lru.Cache | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type BrMsgID struct { | ||||||
|  | 	br *bridge.Bridge | ||||||
|  | 	ID string | ||||||
| } | } | ||||||
|  |  | ||||||
| func New(cfg config.Gateway, r *Router) *Gateway { | func New(cfg config.Gateway, r *Router) *Gateway { | ||||||
| 	gw := &Gateway{Channels: make(map[string]*config.ChannelInfo), Message: r.Message, | 	gw := &Gateway{Channels: make(map[string]*config.ChannelInfo), Message: r.Message, | ||||||
| 		Router: r, Bridges: make(map[string]*bridge.Bridge), Config: r.Config} | 		Router: r, Bridges: make(map[string]*bridge.Bridge), Config: r.Config} | ||||||
|  | 	cache, _ := lru.New(5000) | ||||||
|  | 	gw.Messages = cache | ||||||
| 	gw.AddConfig(&cfg) | 	gw.AddConfig(&cfg) | ||||||
| 	return gw | 	return gw | ||||||
| } | } | ||||||
| @@ -136,15 +145,16 @@ func (gw *Gateway) getDestChannel(msg *config.Message, dest bridge.Bridge) []con | |||||||
| 	return channels | 	return channels | ||||||
| } | } | ||||||
|  |  | ||||||
| func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) []*BrMsgID { | ||||||
|  | 	var brMsgIDs []*BrMsgID | ||||||
| 	// only relay join/part when configged | 	// only relay join/part when configged | ||||||
| 	if msg.Event == config.EVENT_JOIN_LEAVE && !gw.Bridges[dest.Account].Config.ShowJoinPart { | 	if msg.Event == config.EVENT_JOIN_LEAVE && !gw.Bridges[dest.Account].Config.ShowJoinPart { | ||||||
| 		return | 		return brMsgIDs | ||||||
| 	} | 	} | ||||||
| 	// broadcast to every out channel (irc QUIT) | 	// broadcast to every out channel (irc QUIT) | ||||||
| 	if msg.Channel == "" && msg.Event != config.EVENT_JOIN_LEAVE { | 	if msg.Channel == "" && msg.Event != config.EVENT_JOIN_LEAVE { | ||||||
| 		log.Debug("empty channel") | 		log.Debug("empty channel") | ||||||
| 		return | 		return brMsgIDs | ||||||
| 	} | 	} | ||||||
| 	originchannel := msg.Channel | 	originchannel := msg.Channel | ||||||
| 	origmsg := msg | 	origmsg := msg | ||||||
| @@ -158,15 +168,29 @@ func (gw *Gateway) handleMessage(msg config.Message, dest *bridge.Bridge) { | |||||||
| 		msg.Channel = channel.Name | 		msg.Channel = channel.Name | ||||||
| 		msg.Avatar = gw.modifyAvatar(origmsg, dest) | 		msg.Avatar = gw.modifyAvatar(origmsg, dest) | ||||||
| 		msg.Username = gw.modifyUsername(origmsg, dest) | 		msg.Username = gw.modifyUsername(origmsg, dest) | ||||||
|  | 		msg.ID = "" | ||||||
|  | 		if res, ok := gw.Messages.Get(origmsg.ID); ok { | ||||||
|  | 			IDs := res.([]*BrMsgID) | ||||||
|  | 			for _, id := range IDs { | ||||||
|  | 				if dest.Protocol == id.br.Protocol { | ||||||
|  | 					msg.ID = id.ID | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		// for api we need originchannel as channel | 		// for api we need originchannel as channel | ||||||
| 		if dest.Protocol == "api" { | 		if dest.Protocol == "api" { | ||||||
| 			msg.Channel = originchannel | 			msg.Channel = originchannel | ||||||
| 		} | 		} | ||||||
| 		err := dest.Send(msg) | 		mID, err := dest.Send(msg) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			fmt.Println(err) | 			fmt.Println(err) | ||||||
| 		} | 		} | ||||||
|  | 		// append the message ID (mID) from this bridge (dest) to our brMsgIDs slice | ||||||
|  | 		if mID != "" { | ||||||
|  | 			brMsgIDs = append(brMsgIDs, &BrMsgID{dest, mID}) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  | 	return brMsgIDs | ||||||
| } | } | ||||||
|  |  | ||||||
| func (gw *Gateway) ignoreMessage(msg *config.Message) bool { | func (gw *Gateway) ignoreMessage(msg *config.Message) bool { | ||||||
|   | |||||||
| @@ -94,11 +94,17 @@ func (r *Router) handleReceive() { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		for _, gw := range r.Gateways { | 		for _, gw := range r.Gateways { | ||||||
|  | 			// record all the message ID's of the different bridges | ||||||
|  | 			var msgIDs []*BrMsgID | ||||||
| 			if !gw.ignoreMessage(&msg) { | 			if !gw.ignoreMessage(&msg) { | ||||||
| 				msg.Timestamp = time.Now() | 				msg.Timestamp = time.Now() | ||||||
| 				gw.modifyMessage(&msg) | 				gw.modifyMessage(&msg) | ||||||
| 				for _, br := range gw.Bridges { | 				for _, br := range gw.Bridges { | ||||||
| 					gw.handleMessage(msg, br) | 					msgIDs = append(msgIDs, gw.handleMessage(msg, br)...) | ||||||
|  | 				} | ||||||
|  | 				// only add the message ID if it doesn't already exists | ||||||
|  | 				if _, ok := gw.Messages.Get(msg.ID); !ok && msg.ID != "" { | ||||||
|  | 					gw.Messages.Add(msg.ID, msgIDs) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -5,14 +5,13 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/42wim/matterbridge/bridge/config" | 	"github.com/42wim/matterbridge/bridge/config" | ||||||
| 	"github.com/42wim/matterbridge/gateway" | 	"github.com/42wim/matterbridge/gateway" | ||||||
| 	//"github.com/42wim/matterbridge/gateway/samechannel" |  | ||||||
| 	log "github.com/Sirupsen/logrus" | 	log "github.com/Sirupsen/logrus" | ||||||
| 	"github.com/google/gops/agent" | 	"github.com/google/gops/agent" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	version = "1.0.0-rc1" | 	version = "1.1.2" | ||||||
| 	githash string | 	githash string | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -32,6 +32,23 @@ UseSASL=false | |||||||
| #OPTIONAL (default false) | #OPTIONAL (default false) | ||||||
| SkipTLSVerify=true | SkipTLSVerify=true | ||||||
|  |  | ||||||
|  | #If you know your charset, you can specify it manually.  | ||||||
|  | #Otherwise it tries to detect this automatically. Select one below | ||||||
|  | # "iso-8859-2:1987", "iso-8859-9:1989", "866", "latin9", "iso-8859-10:1992", "iso-ir-109", "hebrew",  | ||||||
|  | # "cp932", "iso-8859-15", "cp437", "utf-16be", "iso-8859-3:1988", "windows-1251", "utf16", "latin6",  | ||||||
|  | # "latin3", "iso-8859-1:1987", "iso-8859-9", "utf-16le", "big5", "cp819", "asmo-708", "utf-8",  | ||||||
|  | # "ibm437", "iso-ir-157", "iso-ir-144", "latin4", "850", "iso-8859-5", "iso-8859-5:1988", "l3",  | ||||||
|  | # "windows-31j", "utf8", "iso-8859-3", "437", "greek", "iso-8859-8", "l6", "l9-iso-8859-15",  | ||||||
|  | # "iso-8859-2", "latin2", "iso-ir-100", "iso-8859-6", "arabic", "iso-ir-148", "us-ascii", "x-sjis",  | ||||||
|  | # "utf16be", "iso-8859-8:1988", "utf16le", "l4", "utf-16", "iso-ir-138", "iso-8859-7", "iso-8859-7:1987",  | ||||||
|  | # "windows-1252", "l2", "koi8-r", "iso8859-1", "latin1", "ecma-114", "iso-ir-110", "elot-928",  | ||||||
|  | # "iso-ir-126", "iso-8859-1", "iso-ir-127", "cp850", "cyrillic", "greek8", "windows-1250", "iso-latin-1",  | ||||||
|  | # "l5", "ibm866", "cp866", "ms-kanji", "ibm850", "ecma-118", "iso-ir-101", "ibm819", "l1", "iso-8859-6:1987",  | ||||||
|  | # "latin5", "ascii", "sjis", "iso-8859-10", "iso-8859-4", "iso-8859-4:1988", "shift-jis | ||||||
|  | # The select charset will be converted to utf-8 when sent to other bridges. | ||||||
|  | #OPTIONAL (default "") | ||||||
|  | Charset="" | ||||||
|  |  | ||||||
| #Your nick on irc.  | #Your nick on irc.  | ||||||
| #REQUIRED | #REQUIRED | ||||||
| Nick="matterbot" | Nick="matterbot" | ||||||
| @@ -213,6 +230,11 @@ Team="yourteam" | |||||||
| Login="yourlogin" | Login="yourlogin" | ||||||
| Password="yourpass" | Password="yourpass" | ||||||
|  |  | ||||||
|  | #personal access token of the bot. | ||||||
|  | #new feature since mattermost 4.1. See https://docs.mattermost.com/developer/personal-access-tokens.html | ||||||
|  | #OPTIONAL (you can use token instead of login/password) | ||||||
|  | #Token="abcdefghijklm" | ||||||
|  |  | ||||||
| #Enable this to make a http connection (instead of https) to your mattermost.  | #Enable this to make a http connection (instead of https) to your mattermost.  | ||||||
| #OPTIONAL (default false) | #OPTIONAL (default false) | ||||||
| NoTLS=false | NoTLS=false | ||||||
| @@ -361,7 +383,6 @@ WebhookURL="https://hooks.slack.com/services/yourhook" | |||||||
| #AND DEDICATED BOT USER WHEN POSSIBLE! | #AND DEDICATED BOT USER WHEN POSSIBLE! | ||||||
| #Address to listen on for outgoing webhook requests from slack | #Address to listen on for outgoing webhook requests from slack | ||||||
| #See account settings - integrations - outgoing webhooks on slack | #See account settings - integrations - outgoing webhooks on slack | ||||||
| #This setting will not be used when useAPI is eanbled |  | ||||||
| #webhooks | #webhooks | ||||||
| #OPTIONAL | #OPTIONAL | ||||||
| WebhookBindAddress="0.0.0.0:9999" | WebhookBindAddress="0.0.0.0:9999" | ||||||
| @@ -443,7 +464,12 @@ Server="yourservername" | |||||||
| #OPTIONAL (default false) | #OPTIONAL (default false) | ||||||
| ShowEmbeds=false | ShowEmbeds=false | ||||||
|  |  | ||||||
|  | #Shows the username (minus the discriminator) instead of the server nickname | ||||||
|  | #OPTIONAL (default false) | ||||||
|  | UseUserName=false | ||||||
|  |  | ||||||
| #Specify WebhookURL. If given, will relay messages using the Webhook, which gives a better look to messages. | #Specify WebhookURL. If given, will relay messages using the Webhook, which gives a better look to messages. | ||||||
|  | #This only works if you have one discord channel, if you have multiple discord channels you'll have to specify it in the gateway config | ||||||
| #OPTIONAL (default empty) | #OPTIONAL (default empty) | ||||||
| WebhookURL="Yourwebhooktokenhere" | WebhookURL="Yourwebhooktokenhere" | ||||||
|  |  | ||||||
| @@ -829,6 +855,14 @@ enable=true | |||||||
|         #OPTIONAL - your irc channel key |         #OPTIONAL - your irc channel key | ||||||
|         key="yourkey" |         key="yourkey" | ||||||
|  |  | ||||||
|  |     [[gateway.inout]] | ||||||
|  |     account="discord.game" | ||||||
|  |     channel="mygreatgame" | ||||||
|  |  | ||||||
|  |         #OPTIONAL - webhookurl only works for discord (it needs a different URL for each cahnnel) | ||||||
|  |         [gateway.inout.options] | ||||||
|  |         webhookurl=""https://discordapp.com/api/webhooks/123456789123456789/C9WPqExYWONPDZabcdef-def1434FGFjstasJX9pYht73y" | ||||||
|  |  | ||||||
|     #API example |     #API example | ||||||
|     #[[gateway.inout]] |     #[[gateway.inout]] | ||||||
|     #account="api.local" |     #account="api.local" | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ | |||||||
|  |  | ||||||
| [mattermost] | [mattermost] | ||||||
|     [mattermost.work] |     [mattermost.work] | ||||||
|     useAPI=true |  | ||||||
|     #do not prefix it wit http:// or https:// |     #do not prefix it wit http:// or https:// | ||||||
|     Server="yourmattermostserver.domain"  |     Server="yourmattermostserver.domain"  | ||||||
|     Team="yourteam" |     Team="yourteam" | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/cookiejar" | 	"net/http/cookiejar" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strconv" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -45,8 +44,8 @@ type Message struct { | |||||||
| type Team struct { | type Team struct { | ||||||
| 	Team         *model.Team | 	Team         *model.Team | ||||||
| 	Id           string | 	Id           string | ||||||
| 	Channels     *model.ChannelList | 	Channels     []*model.Channel | ||||||
| 	MoreChannels *model.ChannelList | 	MoreChannels []*model.Channel | ||||||
| 	Users        map[string]*model.User | 	Users        map[string]*model.User | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -55,7 +54,7 @@ type MMClient struct { | |||||||
| 	*Credentials | 	*Credentials | ||||||
| 	Team          *Team | 	Team          *Team | ||||||
| 	OtherTeams    []*Team | 	OtherTeams    []*Team | ||||||
| 	Client        *model.Client | 	Client        *model.Client4 | ||||||
| 	User          *model.User | 	User          *model.User | ||||||
| 	Users         map[string]*model.User | 	Users         map[string]*model.User | ||||||
| 	MessageChan   chan *Message | 	MessageChan   chan *Message | ||||||
| @@ -109,21 +108,21 @@ func (m *MMClient) Login() error { | |||||||
| 		uriScheme = "http://" | 		uriScheme = "http://" | ||||||
| 	} | 	} | ||||||
| 	// login to mattermost | 	// login to mattermost | ||||||
| 	m.Client = model.NewClient(uriScheme + m.Credentials.Server) | 	m.Client = model.NewAPIv4Client(uriScheme + m.Credentials.Server) | ||||||
| 	m.Client.HttpClient.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}, Proxy: http.ProxyFromEnvironment} | 	m.Client.HttpClient.Transport = &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: m.SkipTLSVerify}, Proxy: http.ProxyFromEnvironment} | ||||||
| 	m.Client.HttpClient.Timeout = time.Second * 10 | 	m.Client.HttpClient.Timeout = time.Second * 10 | ||||||
|  |  | ||||||
| 	for { | 	for { | ||||||
| 		d := b.Duration() | 		d := b.Duration() | ||||||
| 		// bogus call to get the serverversion | 		// bogus call to get the serverversion | ||||||
| 		_, err := m.Client.GetClientProperties() | 		_, resp := m.Client.Logout() | ||||||
| 		if err != nil { | 		if resp.Error != nil { | ||||||
| 			return fmt.Errorf("%#v", err.Error()) | 			return fmt.Errorf("%#v", resp.Error.Error()) | ||||||
| 		} | 		} | ||||||
| 		if firstConnection && !supportedVersion(m.Client.ServerVersion) { | 		if firstConnection && !supportedVersion(resp.ServerVersion) { | ||||||
| 			return fmt.Errorf("unsupported mattermost version: %s", m.Client.ServerVersion) | 			return fmt.Errorf("unsupported mattermost version: %s", resp.ServerVersion) | ||||||
| 		} | 		} | ||||||
| 		m.ServerVersion = m.Client.ServerVersion | 		m.ServerVersion = resp.ServerVersion | ||||||
| 		if m.ServerVersion == "" { | 		if m.ServerVersion == "" { | ||||||
| 			m.log.Debugf("Server not up yet, reconnecting in %s", d) | 			m.log.Debugf("Server not up yet, reconnecting in %s", d) | ||||||
| 			time.Sleep(d) | 			time.Sleep(d) | ||||||
| @@ -134,30 +133,33 @@ func (m *MMClient) Login() error { | |||||||
| 	} | 	} | ||||||
| 	b.Reset() | 	b.Reset() | ||||||
|  |  | ||||||
| 	var myinfo *model.Result | 	var resp *model.Response | ||||||
|  | 	//var myinfo *model.Result | ||||||
| 	var appErr *model.AppError | 	var appErr *model.AppError | ||||||
| 	var logmsg = "trying login" | 	var logmsg = "trying login" | ||||||
| 	for { | 	for { | ||||||
| 		m.log.Debugf("%s %s %s %s", logmsg, m.Credentials.Team, m.Credentials.Login, m.Credentials.Server) | 		m.log.Debugf("%s %s %s %s", logmsg, m.Credentials.Team, m.Credentials.Login, m.Credentials.Server) | ||||||
| 		if strings.Contains(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN) { | 		if strings.Contains(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN) { | ||||||
| 			m.log.Debugf(logmsg+" with %s", model.SESSION_COOKIE_TOKEN) | 			m.log.Debugf(logmsg + " with token") | ||||||
| 			token := strings.Split(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN+"=") | 			token := strings.Split(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN+"=") | ||||||
| 			if len(token) != 2 { | 			if len(token) != 2 { | ||||||
| 				return errors.New("incorrect MMAUTHTOKEN. valid input is MMAUTHTOKEN=yourtoken") | 				return errors.New("incorrect MMAUTHTOKEN. valid input is MMAUTHTOKEN=yourtoken") | ||||||
| 			} | 			} | ||||||
| 			m.Client.HttpClient.Jar = m.createCookieJar(token[1]) | 			m.Client.HttpClient.Jar = m.createCookieJar(token[1]) | ||||||
| 			m.Client.MockSession(token[1]) | 			m.Client.AuthToken = token[1] | ||||||
| 			myinfo, appErr = m.Client.GetMe("") | 			m.Client.AuthType = model.HEADER_BEARER | ||||||
| 			if appErr != nil { | 			m.User, resp = m.Client.GetMe("") | ||||||
| 				return errors.New(appErr.DetailedError) | 			if resp.Error != nil { | ||||||
|  | 				return resp.Error | ||||||
| 			} | 			} | ||||||
| 			if myinfo.Data.(*model.User) == nil { | 			if m.User == nil { | ||||||
| 				m.log.Errorf("LOGIN TOKEN: %s is invalid", m.Credentials.Pass) | 				m.log.Errorf("LOGIN TOKEN: %s is invalid", m.Credentials.Pass) | ||||||
| 				return errors.New("invalid " + model.SESSION_COOKIE_TOKEN) | 				return errors.New("invalid " + model.SESSION_COOKIE_TOKEN) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			_, appErr = m.Client.Login(m.Credentials.Login, m.Credentials.Pass) | 			m.User, resp = m.Client.Login(m.Credentials.Login, m.Credentials.Pass) | ||||||
| 		} | 		} | ||||||
|  | 		appErr = resp.Error | ||||||
| 		if appErr != nil { | 		if appErr != nil { | ||||||
| 			d := b.Duration() | 			d := b.Duration() | ||||||
| 			m.log.Debug(appErr.DetailedError) | 			m.log.Debug(appErr.DetailedError) | ||||||
| @@ -185,8 +187,6 @@ func (m *MMClient) Login() error { | |||||||
| 	if m.Team == nil { | 	if m.Team == nil { | ||||||
| 		return errors.New("team not found") | 		return errors.New("team not found") | ||||||
| 	} | 	} | ||||||
| 	// set our team id as default route |  | ||||||
| 	m.Client.SetTeamId(m.Team.Id) |  | ||||||
|  |  | ||||||
| 	m.wsConnect() | 	m.wsConnect() | ||||||
|  |  | ||||||
| @@ -207,7 +207,7 @@ func (m *MMClient) wsConnect() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// setup websocket connection | 	// setup websocket connection | ||||||
| 	wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX_V3 + "/users/websocket" | 	wsurl := wsScheme + m.Credentials.Server + model.API_URL_SUFFIX_V4 + "/websocket" | ||||||
| 	header := http.Header{} | 	header := http.Header{} | ||||||
| 	header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken) | 	header.Set(model.HEADER_AUTH, "BEARER "+m.Client.AuthToken) | ||||||
|  |  | ||||||
| @@ -241,9 +241,9 @@ func (m *MMClient) Logout() error { | |||||||
| 		m.log.Debug("Not invalidating session in logout, credential is a token") | 		m.log.Debug("Not invalidating session in logout, credential is a token") | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	_, err := m.Client.Logout() | 	_, resp := m.Client.Logout() | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return err | 		return resp.Error | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -277,6 +277,13 @@ func (m *MMClient) WsReceiver() { | |||||||
| 			// check if we didn't empty the message | 			// check if we didn't empty the message | ||||||
| 			if msg.Text != "" { | 			if msg.Text != "" { | ||||||
| 				m.MessageChan <- msg | 				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 { | ||||||
|  | 					m.MessageChan <- msg | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| @@ -349,33 +356,34 @@ func (m *MMClient) parseActionPost(rmsg *Message) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) UpdateUsers() error { | func (m *MMClient) UpdateUsers() error { | ||||||
| 	mmusers, err := m.Client.GetProfiles(0, 50000, "") | 	mmusers, resp := m.Client.GetUsers(0, 50000, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return errors.New(err.DetailedError) | 		return errors.New(resp.Error.DetailedError) | ||||||
| 	} | 	} | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	m.Users = mmusers.Data.(map[string]*model.User) | 	for _, user := range mmusers { | ||||||
|  | 		m.Users[user.Id] = user | ||||||
|  | 	} | ||||||
| 	m.Unlock() | 	m.Unlock() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) UpdateChannels() error { | func (m *MMClient) UpdateChannels() error { | ||||||
| 	mmchannels, err := m.Client.GetChannels("") | 	mmchannels, resp := m.Client.GetChannelsForTeamForUser(m.Team.Id, m.User.Id, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return errors.New(err.DetailedError) | 		return errors.New(resp.Error.DetailedError) | ||||||
| 	} |  | ||||||
| 	var mmchannels2 *model.Result |  | ||||||
| 	if m.mmVersion() >= 3.08 { |  | ||||||
| 		mmchannels2, err = m.Client.GetMoreChannelsPage(0, 5000) |  | ||||||
| 	} else { |  | ||||||
| 		mmchannels2, err = m.Client.GetMoreChannels("") |  | ||||||
| 	} |  | ||||||
| 	if err != nil { |  | ||||||
| 		return errors.New(err.DetailedError) |  | ||||||
| 	} | 	} | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	m.Team.Channels = mmchannels.Data.(*model.ChannelList) | 	m.Team.Channels = mmchannels | ||||||
| 	m.Team.MoreChannels = mmchannels2.Data.(*model.ChannelList) | 	m.Unlock() | ||||||
|  |  | ||||||
|  | 	mmchannels, resp = m.Client.GetPublicChannelsForTeam(m.Team.Id, 0, 5000, "") | ||||||
|  | 	if resp.Error != nil { | ||||||
|  | 		return errors.New(resp.Error.DetailedError) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	m.Lock() | ||||||
|  | 	m.Team.MoreChannels = mmchannels | ||||||
| 	m.Unlock() | 	m.Unlock() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @@ -388,14 +396,14 @@ func (m *MMClient) GetChannelName(channelId string) string { | |||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		if t.Channels != nil { | 		if t.Channels != nil { | ||||||
| 			for _, channel := range *t.Channels { | 			for _, channel := range t.Channels { | ||||||
| 				if channel.Id == channelId { | 				if channel.Id == channelId { | ||||||
| 					return channel.Name | 					return channel.Name | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if t.MoreChannels != nil { | 		if t.MoreChannels != nil { | ||||||
| 			for _, channel := range *t.MoreChannels { | 			for _, channel := range t.MoreChannels { | ||||||
| 				if channel.Id == channelId { | 				if channel.Id == channelId { | ||||||
| 					return channel.Name | 					return channel.Name | ||||||
| 				} | 				} | ||||||
| @@ -413,7 +421,7 @@ func (m *MMClient) GetChannelId(name string, teamId string) string { | |||||||
| 	} | 	} | ||||||
| 	for _, t := range m.OtherTeams { | 	for _, t := range m.OtherTeams { | ||||||
| 		if t.Id == teamId { | 		if t.Id == teamId { | ||||||
| 			for _, channel := range append(*t.Channels, *t.MoreChannels...) { | 			for _, channel := range append(t.Channels, t.MoreChannels...) { | ||||||
| 				if channel.Name == name { | 				if channel.Name == name { | ||||||
| 					return channel.Id | 					return channel.Id | ||||||
| 				} | 				} | ||||||
| @@ -427,7 +435,7 @@ func (m *MMClient) GetChannelTeamId(id string) string { | |||||||
| 	m.RLock() | 	m.RLock() | ||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	for _, t := range append(m.OtherTeams, m.Team) { | 	for _, t := range append(m.OtherTeams, m.Team) { | ||||||
| 		for _, channel := range append(*t.Channels, *t.MoreChannels...) { | 		for _, channel := range append(t.Channels, t.MoreChannels...) { | ||||||
| 			if channel.Id == id { | 			if channel.Id == id { | ||||||
| 				return channel.TeamId | 				return channel.TeamId | ||||||
| 			} | 			} | ||||||
| @@ -440,7 +448,7 @@ func (m *MMClient) GetChannelHeader(channelId string) string { | |||||||
| 	m.RLock() | 	m.RLock() | ||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	for _, t := range m.OtherTeams { | 	for _, t := range m.OtherTeams { | ||||||
| 		for _, channel := range append(*t.Channels, *t.MoreChannels...) { | 		for _, channel := range append(t.Channels, t.MoreChannels...) { | ||||||
| 			if channel.Id == channelId { | 			if channel.Id == channelId { | ||||||
| 				return channel.Header | 				return channel.Header | ||||||
| 			} | 			} | ||||||
| @@ -450,55 +458,68 @@ func (m *MMClient) GetChannelHeader(channelId string) string { | |||||||
| 	return "" | 	return "" | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) PostMessage(channelId string, text string) { | func (m *MMClient) PostMessage(channelId string, text string) (string, error) { | ||||||
| 	post := &model.Post{ChannelId: channelId, Message: text} | 	post := &model.Post{ChannelId: channelId, Message: text} | ||||||
| 	m.Client.CreatePost(post) | 	res, resp := m.Client.CreatePost(post) | ||||||
|  | 	if resp.Error != nil { | ||||||
|  | 		return "", resp.Error | ||||||
|  | 	} | ||||||
|  | 	return res.Id, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (m *MMClient) EditMessage(postId string, text string) (string, error) { | ||||||
|  | 	post := &model.Post{Message: text} | ||||||
|  | 	res, resp := m.Client.UpdatePost(postId, post) | ||||||
|  | 	if resp.Error != nil { | ||||||
|  | 		return "", resp.Error | ||||||
|  | 	} | ||||||
|  | 	return res.Id, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) JoinChannel(channelId string) error { | func (m *MMClient) JoinChannel(channelId string) error { | ||||||
| 	m.RLock() | 	m.RLock() | ||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	for _, c := range *m.Team.Channels { | 	for _, c := range m.Team.Channels { | ||||||
| 		if c.Id == channelId { | 		if c.Id == channelId { | ||||||
| 			m.log.Debug("Not joining ", channelId, " already joined.") | 			m.log.Debug("Not joining ", channelId, " already joined.") | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	m.log.Debug("Joining ", channelId) | 	m.log.Debug("Joining ", channelId) | ||||||
| 	_, err := m.Client.JoinChannel(channelId) | 	_, resp := m.Client.AddChannelMember(channelId, m.User.Id) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return errors.New("failed to join") | 		return resp.Error | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetPostsSince(channelId string, time int64) *model.PostList { | func (m *MMClient) GetPostsSince(channelId string, time int64) *model.PostList { | ||||||
| 	res, err := m.Client.GetPostsSince(channelId, time) | 	res, resp := m.Client.GetPostsSince(channelId, time) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	return res.Data.(*model.PostList) | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) SearchPosts(query string) *model.PostList { | func (m *MMClient) SearchPosts(query string) *model.PostList { | ||||||
| 	res, err := m.Client.SearchPosts(query, false) | 	res, resp := m.Client.SearchPosts(m.Team.Id, query, false) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	return res.Data.(*model.PostList) | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetPosts(channelId string, limit int) *model.PostList { | func (m *MMClient) GetPosts(channelId string, limit int) *model.PostList { | ||||||
| 	res, err := m.Client.GetPosts(channelId, 0, limit, "") | 	res, resp := m.Client.GetPostsForChannel(channelId, 0, limit, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	return res.Data.(*model.PostList) | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetPublicLink(filename string) string { | func (m *MMClient) GetPublicLink(filename string) string { | ||||||
| 	res, err := m.Client.GetPublicLink(filename) | 	res, resp := m.Client.GetFileLink(filename) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return "" | 		return "" | ||||||
| 	} | 	} | ||||||
| 	return res | 	return res | ||||||
| @@ -507,8 +528,8 @@ func (m *MMClient) GetPublicLink(filename string) string { | |||||||
| func (m *MMClient) GetPublicLinks(filenames []string) []string { | func (m *MMClient) GetPublicLinks(filenames []string) []string { | ||||||
| 	var output []string | 	var output []string | ||||||
| 	for _, f := range filenames { | 	for _, f := range filenames { | ||||||
| 		res, err := m.Client.GetPublicLink(f) | 		res, resp := m.Client.GetFileLink(f) | ||||||
| 		if err != nil { | 		if resp.Error != nil { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		output = append(output, res) | 		output = append(output, res) | ||||||
| @@ -524,8 +545,8 @@ func (m *MMClient) GetFileLinks(filenames []string) []string { | |||||||
|  |  | ||||||
| 	var output []string | 	var output []string | ||||||
| 	for _, f := range filenames { | 	for _, f := range filenames { | ||||||
| 		res, err := m.Client.GetPublicLink(f) | 		res, resp := m.Client.GetFileLink(f) | ||||||
| 		if err != nil { | 		if resp.Error != nil { | ||||||
| 			// public links is probably disabled, create the link ourselves | 			// public links is probably disabled, create the link ourselves | ||||||
| 			output = append(output, uriScheme+m.Credentials.Server+model.API_URL_SUFFIX_V3+"/files/"+f+"/get") | 			output = append(output, uriScheme+m.Credentials.Server+model.API_URL_SUFFIX_V3+"/files/"+f+"/get") | ||||||
| 			continue | 			continue | ||||||
| @@ -536,42 +557,33 @@ func (m *MMClient) GetFileLinks(filenames []string) []string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) UpdateChannelHeader(channelId string, header string) { | func (m *MMClient) UpdateChannelHeader(channelId string, header string) { | ||||||
| 	data := make(map[string]string) | 	channel := &model.Channel{Id: channelId, Header: header} | ||||||
| 	data["channel_id"] = channelId |  | ||||||
| 	data["channel_header"] = header |  | ||||||
| 	m.log.Debugf("updating channelheader %#v, %#v", channelId, header) | 	m.log.Debugf("updating channelheader %#v, %#v", channelId, header) | ||||||
| 	_, err := m.Client.UpdateChannelHeader(data) | 	_, resp := m.Client.UpdateChannel(channel) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		log.Error(err) | 		log.Error(resp.Error) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) UpdateLastViewed(channelId string) { | func (m *MMClient) UpdateLastViewed(channelId string) { | ||||||
| 	m.log.Debugf("posting lastview %#v", channelId) | 	m.log.Debugf("posting lastview %#v", channelId) | ||||||
| 	if m.mmVersion() >= 3.08 { | 	view := &model.ChannelView{ChannelId: channelId} | ||||||
| 		view := model.ChannelView{ChannelId: channelId} | 	res, _ := m.Client.ViewChannel(m.User.Id, view) | ||||||
| 		res, _ := m.Client.ViewChannel(view) |  | ||||||
| 	if !res { | 	if !res { | ||||||
| 		m.log.Errorf("ChannelView update for %s failed", channelId) | 		m.log.Errorf("ChannelView update for %s failed", channelId) | ||||||
| 	} | 	} | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	_, err := m.Client.UpdateLastViewedAt(channelId, true) |  | ||||||
| 	if err != nil { |  | ||||||
| 		m.log.Error(err) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) UsernamesInChannel(channelId string) []string { | func (m *MMClient) UsernamesInChannel(channelId string) []string { | ||||||
| 	res, err := m.Client.GetProfilesInChannel(channelId, 0, 50000, "") | 	res, resp := m.Client.GetChannelMembers(channelId, 0, 50000, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		m.log.Errorf("UsernamesInChannel(%s) failed: %s", channelId, err) | 		m.log.Errorf("UsernamesInChannel(%s) failed: %s", channelId, resp.Error) | ||||||
| 		return []string{} | 		return []string{} | ||||||
| 	} | 	} | ||||||
| 	members := res.Data.(map[string]*model.User) | 	allusers := m.GetUsers() | ||||||
| 	result := []string{} | 	result := []string{} | ||||||
| 	for _, member := range members { | 	for _, member := range *res { | ||||||
| 		result = append(result, member.Nickname) | 		result = append(result, allusers[member.UserId].Nickname) | ||||||
| 	} | 	} | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
| @@ -595,22 +607,15 @@ func (m *MMClient) createCookieJar(token string) *cookiejar.Jar { | |||||||
| func (m *MMClient) SendDirectMessage(toUserId string, msg string) { | func (m *MMClient) SendDirectMessage(toUserId string, msg string) { | ||||||
| 	m.log.Debugf("SendDirectMessage to %s, msg %s", toUserId, msg) | 	m.log.Debugf("SendDirectMessage to %s, msg %s", toUserId, msg) | ||||||
| 	// create DM channel (only happens on first message) | 	// create DM channel (only happens on first message) | ||||||
| 	_, err := m.Client.CreateDirectChannel(toUserId) | 	_, resp := m.Client.CreateDirectChannel(m.User.Id, toUserId) | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		m.log.Debugf("SendDirectMessage to %#v failed: %s", toUserId, err) | 		m.log.Debugf("SendDirectMessage to %#v failed: %s", toUserId, resp.Error) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	channelName := model.GetDMNameFromIds(toUserId, m.User.Id) | 	channelName := model.GetDMNameFromIds(toUserId, m.User.Id) | ||||||
|  |  | ||||||
| 	// update our channels | 	// update our channels | ||||||
| 	mmchannels, err := m.Client.GetChannels("") | 	m.UpdateChannels() | ||||||
| 	if err != nil { |  | ||||||
| 		m.log.Debug("SendDirectMessage: Couldn't update channels") |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	m.Lock() |  | ||||||
| 	m.Team.Channels = mmchannels.Data.(*model.ChannelList) |  | ||||||
| 	m.Unlock() |  | ||||||
|  |  | ||||||
| 	// build & send the message | 	// build & send the message | ||||||
| 	msg = strings.Replace(msg, "\r", "", -1) | 	msg = strings.Replace(msg, "\r", "", -1) | ||||||
| @@ -636,10 +641,10 @@ func (m *MMClient) GetChannels() []*model.Channel { | |||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	var channels []*model.Channel | 	var channels []*model.Channel | ||||||
| 	// our primary team channels first | 	// our primary team channels first | ||||||
| 	channels = append(channels, *m.Team.Channels...) | 	channels = append(channels, m.Team.Channels...) | ||||||
| 	for _, t := range m.OtherTeams { | 	for _, t := range m.OtherTeams { | ||||||
| 		if t.Id != m.Team.Id { | 		if t.Id != m.Team.Id { | ||||||
| 			channels = append(channels, *t.Channels...) | 			channels = append(channels, t.Channels...) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return channels | 	return channels | ||||||
| @@ -651,7 +656,7 @@ func (m *MMClient) GetMoreChannels() []*model.Channel { | |||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	var channels []*model.Channel | 	var channels []*model.Channel | ||||||
| 	for _, t := range m.OtherTeams { | 	for _, t := range m.OtherTeams { | ||||||
| 		channels = append(channels, *t.MoreChannels...) | 		channels = append(channels, t.MoreChannels...) | ||||||
| 	} | 	} | ||||||
| 	return channels | 	return channels | ||||||
| } | } | ||||||
| @@ -662,9 +667,9 @@ func (m *MMClient) GetTeamFromChannel(channelId string) string { | |||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	var channels []*model.Channel | 	var channels []*model.Channel | ||||||
| 	for _, t := range m.OtherTeams { | 	for _, t := range m.OtherTeams { | ||||||
| 		channels = append(channels, *t.Channels...) | 		channels = append(channels, t.Channels...) | ||||||
| 		if t.MoreChannels != nil { | 		if t.MoreChannels != nil { | ||||||
| 			channels = append(channels, *t.MoreChannels...) | 			channels = append(channels, t.MoreChannels...) | ||||||
| 		} | 		} | ||||||
| 		for _, c := range channels { | 		for _, c := range channels { | ||||||
| 			if c.Id == channelId { | 			if c.Id == channelId { | ||||||
| @@ -678,12 +683,11 @@ func (m *MMClient) GetTeamFromChannel(channelId string) string { | |||||||
| func (m *MMClient) GetLastViewedAt(channelId string) int64 { | func (m *MMClient) GetLastViewedAt(channelId string) int64 { | ||||||
| 	m.RLock() | 	m.RLock() | ||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
| 	res, err := m.Client.GetChannel(channelId, "") | 	res, resp := m.Client.GetChannelMember(channelId, m.User.Id, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return model.GetMillis() | 		return model.GetMillis() | ||||||
| 	} | 	} | ||||||
| 	data := res.Data.(*model.ChannelData) | 	return res.LastViewedAt | ||||||
| 	return data.Member.LastViewedAt |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetUsers() map[string]*model.User { | func (m *MMClient) GetUsers() map[string]*model.User { | ||||||
| @@ -701,12 +705,11 @@ func (m *MMClient) GetUser(userId string) *model.User { | |||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
| 	_, ok := m.Users[userId] | 	_, ok := m.Users[userId] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		res, err := m.Client.GetProfilesByIds([]string{userId}) | 		res, resp := m.Client.GetUser(userId, "") | ||||||
| 		if err != nil { | 		if resp.Error != nil { | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 		u := res.Data.(map[string]*model.User)[userId] | 		m.Users[userId] = res | ||||||
| 		m.Users[userId] = u |  | ||||||
| 	} | 	} | ||||||
| 	return m.Users[userId] | 	return m.Users[userId] | ||||||
| } | } | ||||||
| @@ -720,36 +723,36 @@ func (m *MMClient) GetUserName(userId string) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetStatus(userId string) string { | func (m *MMClient) GetStatus(userId string) string { | ||||||
| 	res, err := m.Client.GetStatusesByIds([]string{userId}) | 	res, resp := m.Client.GetUserStatus(userId, "") | ||||||
| 	if err != nil { | 	if resp.Error != nil { | ||||||
| 		return "" | 		return "" | ||||||
| 	} | 	} | ||||||
| 	status := res.Data.(map[string]string) | 	if res.Status == model.STATUS_AWAY { | ||||||
| 	if status[userId] == model.STATUS_AWAY { |  | ||||||
| 		return "away" | 		return "away" | ||||||
| 	} | 	} | ||||||
| 	if status[userId] == model.STATUS_ONLINE { | 	if res.Status == model.STATUS_ONLINE { | ||||||
| 		return "online" | 		return "online" | ||||||
| 	} | 	} | ||||||
| 	return "offline" | 	return "offline" | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) GetStatuses() map[string]string { | func (m *MMClient) GetStatuses() map[string]string { | ||||||
| 	var ok bool | 	var ids []string | ||||||
| 	statuses := make(map[string]string) | 	statuses := make(map[string]string) | ||||||
| 	res, err := m.Client.GetStatuses() | 	for id := range m.Users { | ||||||
| 	if err != nil { | 		ids = append(ids, id) | ||||||
|  | 	} | ||||||
|  | 	res, resp := m.Client.GetUsersStatusesByIds(ids) | ||||||
|  | 	if resp.Error != nil { | ||||||
| 		return statuses | 		return statuses | ||||||
| 	} | 	} | ||||||
| 	if statuses, ok = res.Data.(map[string]string); ok { | 	for _, status := range res { | ||||||
| 		for userId, status := range statuses { | 		statuses[status.UserId] = "offline" | ||||||
| 			statuses[userId] = "offline" | 		if status.Status == model.STATUS_AWAY { | ||||||
| 			if status == model.STATUS_AWAY { | 			statuses[status.UserId] = "away" | ||||||
| 				statuses[userId] = "away" |  | ||||||
| 			} |  | ||||||
| 			if status == model.STATUS_ONLINE { |  | ||||||
| 				statuses[userId] = "online" |  | ||||||
| 		} | 		} | ||||||
|  | 		if status.Status == model.STATUS_ONLINE { | ||||||
|  | 			statuses[status.UserId] = "online" | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return statuses | 	return statuses | ||||||
| @@ -800,40 +803,39 @@ func (m *MMClient) StatusLoop() { | |||||||
| func (m *MMClient) initUser() error { | func (m *MMClient) initUser() error { | ||||||
| 	m.Lock() | 	m.Lock() | ||||||
| 	defer m.Unlock() | 	defer m.Unlock() | ||||||
| 	initLoad, err := m.Client.GetInitialLoad() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	initData := initLoad.Data.(*model.InitialLoad) |  | ||||||
| 	m.User = initData.User |  | ||||||
| 	// we only load all team data on initial login. | 	// we only load all team data on initial login. | ||||||
| 	// all other updates are for channels from our (primary) team only. | 	// all other updates are for channels from our (primary) team only. | ||||||
| 	//m.log.Debug("initUser(): loading all team data") | 	//m.log.Debug("initUser(): loading all team data") | ||||||
| 	for _, v := range initData.Teams { | 	teams, resp := m.Client.GetTeamsForUser(m.User.Id, "") | ||||||
| 		m.Client.SetTeamId(v.Id) | 	if resp.Error != nil { | ||||||
| 		mmusers, err := m.Client.GetProfiles(0, 50000, "") | 		return resp.Error | ||||||
| 		if err != nil { |  | ||||||
| 			return errors.New(err.DetailedError) |  | ||||||
| 	} | 	} | ||||||
| 		t := &Team{Team: v, Users: mmusers.Data.(map[string]*model.User), Id: v.Id} | 	for _, team := range teams { | ||||||
| 		mmchannels, err := m.Client.GetChannels("") | 		mmusers, resp := m.Client.GetUsersInTeam(team.Id, 0, 50000, "") | ||||||
| 		if err != nil { | 		if resp.Error != nil { | ||||||
| 			return errors.New(err.DetailedError) | 			return errors.New(resp.Error.DetailedError) | ||||||
| 		} | 		} | ||||||
| 		t.Channels = mmchannels.Data.(*model.ChannelList) | 		usermap := make(map[string]*model.User) | ||||||
| 		if m.mmVersion() >= 3.08 { | 		for _, user := range mmusers { | ||||||
| 			mmchannels, err = m.Client.GetMoreChannelsPage(0, 5000) | 			usermap[user.Id] = user | ||||||
| 		} else { |  | ||||||
| 			mmchannels, err = m.Client.GetMoreChannels("") |  | ||||||
| 		} | 		} | ||||||
| 		if err != nil { |  | ||||||
| 			return errors.New(err.DetailedError) | 		t := &Team{Team: team, Users: usermap, Id: team.Id} | ||||||
|  |  | ||||||
|  | 		mmchannels, resp := m.Client.GetChannelsForTeamForUser(team.Id, m.User.Id, "") | ||||||
|  | 		if resp.Error != nil { | ||||||
|  | 			return resp.Error | ||||||
| 		} | 		} | ||||||
| 		t.MoreChannels = mmchannels.Data.(*model.ChannelList) | 		t.Channels = mmchannels | ||||||
|  | 		mmchannels, resp = m.Client.GetPublicChannelsForTeam(team.Id, 0, 5000, "") | ||||||
|  | 		if resp.Error != nil { | ||||||
|  | 			return resp.Error | ||||||
|  | 		} | ||||||
|  | 		t.MoreChannels = mmchannels | ||||||
| 		m.OtherTeams = append(m.OtherTeams, t) | 		m.OtherTeams = append(m.OtherTeams, t) | ||||||
| 		if v.Name == m.Credentials.Team { | 		if team.Name == m.Credentials.Team { | ||||||
| 			m.Team = t | 			m.Team = t | ||||||
| 			m.log.Debugf("initUser(): found our team %s (id: %s)", v.Name, v.Id) | 			m.log.Debugf("initUser(): found our team %s (id: %s)", team.Name, team.Id) | ||||||
| 		} | 		} | ||||||
| 		// add all users | 		// add all users | ||||||
| 		for k, v := range t.Users { | 		for k, v := range t.Users { | ||||||
| @@ -854,22 +856,13 @@ func (m *MMClient) sendWSRequest(action string, data map[string]interface{}) err | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MMClient) mmVersion() float64 { |  | ||||||
| 	v, _ := strconv.ParseFloat(string(m.ServerVersion[0:2])+"0"+string(m.ServerVersion[2]), 64) |  | ||||||
| 	if string(m.ServerVersion[4]) == "." { |  | ||||||
| 		v, _ = strconv.ParseFloat(m.ServerVersion[0:4], 64) |  | ||||||
| 	} |  | ||||||
| 	return v |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func supportedVersion(version string) bool { | func supportedVersion(version string) bool { | ||||||
| 	if strings.HasPrefix(version, "3.5.0") || | 	if strings.HasPrefix(version, "3.8.0") || | ||||||
| 		strings.HasPrefix(version, "3.6.0") || |  | ||||||
| 		strings.HasPrefix(version, "3.7.0") || |  | ||||||
| 		strings.HasPrefix(version, "3.8.0") || |  | ||||||
| 		strings.HasPrefix(version, "3.9.0") || | 		strings.HasPrefix(version, "3.9.0") || | ||||||
| 		strings.HasPrefix(version, "3.10.0") || | 		strings.HasPrefix(version, "3.10.0") || | ||||||
| 		strings.HasPrefix(version, "4.0") { | 		strings.HasPrefix(version, "4.0") || | ||||||
|  | 		strings.HasPrefix(version, "4.1") || | ||||||
|  | 		strings.HasPrefix(version, "4.2") { | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
| 	return false | 	return false | ||||||
|   | |||||||
| @@ -43,6 +43,7 @@ type IMessage struct { | |||||||
| 	ServiceId   string `schema:"service_id"` | 	ServiceId   string `schema:"service_id"` | ||||||
| 	Text        string `schema:"text"` | 	Text        string `schema:"text"` | ||||||
| 	TriggerWord string `schema:"trigger_word"` | 	TriggerWord string `schema:"trigger_word"` | ||||||
|  | 	FileIDs     string `schema:"file_ids"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // Client for Mattermost. | // Client for Mattermost. | ||||||
|   | |||||||
| @@ -205,17 +205,43 @@ func (gitter *Gitter) GetMessage(roomID, messageID string) (*Message, error) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendMessage sends a message to a room | // SendMessage sends a message to a room | ||||||
| func (gitter *Gitter) SendMessage(roomID, text string) error { | func (gitter *Gitter) SendMessage(roomID, text string) (*Message, error) { | ||||||
| 
 | 
 | ||||||
| 	message := Message{Text: text} | 	message := Message{Text: text} | ||||||
| 	body, _ := json.Marshal(message) | 	body, _ := json.Marshal(message) | ||||||
| 	_, err := gitter.post(gitter.config.apiBaseURL+"rooms/"+roomID+"/chatMessages", body) | 	response, err := gitter.post(gitter.config.apiBaseURL+"rooms/"+roomID+"/chatMessages", body) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		gitter.log(err) | 		gitter.log(err) | ||||||
| 		return err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	err = json.Unmarshal(response, &message) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &message, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UpdateMessage updates a message in a room | ||||||
|  | func (gitter *Gitter) UpdateMessage(roomID, msgID, text string) (*Message, error) { | ||||||
|  | 
 | ||||||
|  | 	message := Message{Text: text} | ||||||
|  | 	body, _ := json.Marshal(message) | ||||||
|  | 	response, err := gitter.put(gitter.config.apiBaseURL+"rooms/"+roomID+"/chatMessages/"+msgID, body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err = json.Unmarshal(response, &message) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &message, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // JoinRoom joins a room | // JoinRoom joins a room | ||||||
| @@ -265,7 +291,7 @@ func (gitter *Gitter) SearchRooms(room string) ([]Room, error) { | |||||||
| 		Results []Room `json:"results"` | 		Results []Room `json:"results"` | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	response, err := gitter.get(gitter.config.apiBaseURL + "rooms?q=" + room ) | 	response, err := gitter.get(gitter.config.apiBaseURL + "rooms?q=" + room) | ||||||
| 
 | 
 | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		gitter.log(err) | 		gitter.log(err) | ||||||
| @@ -414,6 +440,39 @@ func (gitter *Gitter) post(url string, body []byte) ([]byte, error) { | |||||||
| 	return result, nil | 	return result, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (gitter *Gitter) put(url string, body []byte) ([]byte, error) { | ||||||
|  | 	r, err := http.NewRequest("PUT", url, bytes.NewBuffer(body)) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	r.Header.Set("Content-Type", "application/json") | ||||||
|  | 	r.Header.Set("Accept", "application/json") | ||||||
|  | 	r.Header.Set("Authorization", "Bearer "+gitter.config.token) | ||||||
|  | 
 | ||||||
|  | 	resp, err := gitter.config.client.Do(r) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	defer resp.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	if resp.StatusCode != http.StatusOK { | ||||||
|  | 		err = APIError{What: fmt.Sprintf("Status code: %v", resp.StatusCode)} | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	result, err := ioutil.ReadAll(resp.Body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		gitter.log(err) | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (gitter *Gitter) delete(url string) ([]byte, error) { | func (gitter *Gitter) delete(url string) ([]byte, error) { | ||||||
| 	r, err := http.NewRequest("delete", url, nil) | 	r, err := http.NewRequest("delete", url, nil) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattermost/platform/einterfaces/account_migration.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattermost/platform/einterfaces/account_migration.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
| @@ -6,7 +6,7 @@ package einterfaces | |||||||
| import "github.com/mattermost/platform/model" | import "github.com/mattermost/platform/model" | ||||||
|  |  | ||||||
| type AccountMigrationInterface interface { | type AccountMigrationInterface interface { | ||||||
| 	MigrateToLdap(fromAuthService string, forignUserFieldNameToMatch string) *model.AppError | 	MigrateToLdap(fromAuthService string, forignUserFieldNameToMatch string, force bool) *model.AppError | ||||||
| } | } | ||||||
|  |  | ||||||
| var theAccountMigrationInterface AccountMigrationInterface | var theAccountMigrationInterface AccountMigrationInterface | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/brand.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/brand.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								vendor/github.com/mattermost/platform/einterfaces/cluster.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/mattermost/platform/einterfaces/cluster.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
| @@ -7,26 +7,19 @@ import ( | |||||||
| 	"github.com/mattermost/platform/model" | 	"github.com/mattermost/platform/model" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | type ClusterMessageHandler func(msg *model.ClusterMessage) | ||||||
|  |  | ||||||
| type ClusterInterface interface { | type ClusterInterface interface { | ||||||
| 	StartInterNodeCommunication() | 	StartInterNodeCommunication() | ||||||
| 	StopInterNodeCommunication() | 	StopInterNodeCommunication() | ||||||
| 	GetClusterInfos() []*model.ClusterInfo | 	RegisterClusterMessageHandler(event string, crm ClusterMessageHandler) | ||||||
| 	GetClusterStats() ([]*model.ClusterStats, *model.AppError) |  | ||||||
| 	ClearSessionCacheForUser(userId string) |  | ||||||
| 	InvalidateCacheForUser(userId string) |  | ||||||
| 	InvalidateCacheForChannel(channelId string) |  | ||||||
| 	InvalidateCacheForChannelByName(teamId, name string) |  | ||||||
| 	InvalidateCacheForChannelMembers(channelId string) |  | ||||||
| 	InvalidateCacheForChannelMembersNotifyProps(channelId string) |  | ||||||
| 	InvalidateCacheForChannelPosts(channelId string) |  | ||||||
| 	InvalidateCacheForWebhook(webhookId string) |  | ||||||
| 	InvalidateCacheForReactions(postId string) |  | ||||||
| 	Publish(event *model.WebSocketEvent) |  | ||||||
| 	UpdateStatus(status *model.Status) |  | ||||||
| 	GetLogs() ([]string, *model.AppError) |  | ||||||
| 	GetClusterId() string | 	GetClusterId() string | ||||||
|  | 	GetClusterInfos() []*model.ClusterInfo | ||||||
|  | 	SendClusterMessage(cluster *model.ClusterMessage) | ||||||
|  | 	NotifyMsg(buf []byte) | ||||||
|  | 	GetClusterStats() ([]*model.ClusterStats, *model.AppError) | ||||||
|  | 	GetLogs(page, perPage int) ([]string, *model.AppError) | ||||||
| 	ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError | 	ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError | ||||||
| 	InvalidateAllCaches() *model.AppError |  | ||||||
| } | } | ||||||
|  |  | ||||||
| var theClusterInterface ClusterInterface | var theClusterInterface ClusterInterface | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/compliance.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/compliance.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										25
									
								
								vendor/github.com/mattermost/platform/einterfaces/elasticsearch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/mattermost/platform/einterfaces/elasticsearch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package einterfaces | ||||||
|  |  | ||||||
|  | import "github.com/mattermost/platform/model" | ||||||
|  |  | ||||||
|  | type ElasticsearchInterface interface { | ||||||
|  | 	Start() *model.AppError | ||||||
|  | 	IndexPost(post *model.Post, teamId string) *model.AppError | ||||||
|  | 	SearchPosts(channels *model.ChannelList, searchParams []*model.SearchParams) ([]string, *model.AppError) | ||||||
|  | 	DeletePost(post *model.Post) *model.AppError | ||||||
|  | 	TestConfig(cfg *model.Config) *model.AppError | ||||||
|  | 	PurgeIndexes() *model.AppError | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var theElasticsearchInterface ElasticsearchInterface | ||||||
|  |  | ||||||
|  | func RegisterElasticsearchInterface(newInterface ElasticsearchInterface) { | ||||||
|  | 	theElasticsearchInterface = newInterface | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetElasticsearchInterface() ElasticsearchInterface { | ||||||
|  | 	return theElasticsearchInterface | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/emoji.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/emoji.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								vendor/github.com/mattermost/platform/einterfaces/jobs/data_retention.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/mattermost/platform/einterfaces/jobs/data_retention.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package jobs | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/mattermost/platform/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type DataRetentionInterface interface { | ||||||
|  | 	MakeWorker() model.Worker | ||||||
|  | 	MakeScheduler() model.Scheduler | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var theDataRetentionInterface DataRetentionInterface | ||||||
|  |  | ||||||
|  | func RegisterDataRetentionInterface(newInterface DataRetentionInterface) { | ||||||
|  | 	theDataRetentionInterface = newInterface | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetDataRetentionInterface() DataRetentionInterface { | ||||||
|  | 	return theDataRetentionInterface | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								vendor/github.com/mattermost/platform/einterfaces/jobs/elasticsearch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/mattermost/platform/einterfaces/jobs/elasticsearch.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package jobs | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/mattermost/platform/model" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type ElasticsearchIndexerInterface interface { | ||||||
|  | 	MakeWorker() model.Worker | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var theElasticsearchIndexerInterface ElasticsearchIndexerInterface | ||||||
|  |  | ||||||
|  | func RegisterElasticsearchIndexerInterface(newInterface ElasticsearchIndexerInterface) { | ||||||
|  | 	theElasticsearchIndexerInterface = newInterface | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetElasticsearchIndexerInterface() ElasticsearchIndexerInterface { | ||||||
|  | 	return theElasticsearchIndexerInterface | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								vendor/github.com/mattermost/platform/einterfaces/metrics.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/mattermost/platform/einterfaces/metrics.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
| @@ -33,6 +33,7 @@ type MetricsInterface interface { | |||||||
| 	IncrementMemCacheHitCounterSession() | 	IncrementMemCacheHitCounterSession() | ||||||
|  |  | ||||||
| 	IncrementWebsocketEvent(eventType string) | 	IncrementWebsocketEvent(eventType string) | ||||||
|  | 	IncrementWebSocketBroadcast(eventType string) | ||||||
|  |  | ||||||
| 	AddMemCacheHitCounter(cacheName string, amount float64) | 	AddMemCacheHitCounter(cacheName string, amount float64) | ||||||
| 	AddMemCacheMissCounter(cacheName string, amount float64) | 	AddMemCacheMissCounter(cacheName string, amount float64) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/mfa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/mfa.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/oauthproviders.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/einterfaces/oauthproviders.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattermost/platform/einterfaces/saml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattermost/platform/einterfaces/saml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package einterfaces | package einterfaces | ||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| type SamlInterface interface { | type SamlInterface interface { | ||||||
| 	ConfigureSP() *model.AppError | 	ConfigureSP() *model.AppError | ||||||
| 	BuildRequest(relayState string) (*model.SamlAuthRequest, *model.AppError) | 	BuildRequest(relayState string) (*model.SamlAuthRequest, *model.AppError) | ||||||
| 	DoLogin(encodedXML string, relayState map[string]string, siteURL string) (*model.User, *model.AppError) | 	DoLogin(encodedXML string, relayState map[string]string) (*model.User, *model.AppError) | ||||||
| 	GetMetadata() (string, *model.AppError) | 	GetMetadata() (string, *model.AppError) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								vendor/github.com/mattermost/platform/model/access.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/mattermost/platform/model/access.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -21,6 +21,7 @@ type AccessData struct { | |||||||
| 	RefreshToken string `json:"refresh_token"` | 	RefreshToken string `json:"refresh_token"` | ||||||
| 	RedirectUri  string `json:"redirect_uri"` | 	RedirectUri  string `json:"redirect_uri"` | ||||||
| 	ExpiresAt    int64  `json:"expires_at"` | 	ExpiresAt    int64  `json:"expires_at"` | ||||||
|  | 	Scope        string `json:"scope"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type AccessResponse struct { | type AccessResponse struct { | ||||||
| @@ -51,7 +52,7 @@ func (ad *AccessData) IsValid() *AppError { | |||||||
| 		return NewLocAppError("AccessData.IsValid", "model.access.is_valid.refresh_token.app_error", nil, "") | 		return NewLocAppError("AccessData.IsValid", "model.access.is_valid.refresh_token.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(ad.RedirectUri) > 256 { | 	if len(ad.RedirectUri) == 0 || len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) { | ||||||
| 		return NewLocAppError("AccessData.IsValid", "model.access.is_valid.redirect_uri.app_error", nil, "") | 		return NewLocAppError("AccessData.IsValid", "model.access.is_valid.redirect_uri.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/analytics_row.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/analytics_row.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/audit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/audit.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/audits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/audits.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										116
									
								
								vendor/github.com/mattermost/platform/model/authorization.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										116
									
								
								vendor/github.com/mattermost/platform/model/authorization.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -39,6 +39,7 @@ var PERMISSION_DELETE_PUBLIC_CHANNEL *Permission | |||||||
| var PERMISSION_DELETE_PRIVATE_CHANNEL *Permission | var PERMISSION_DELETE_PRIVATE_CHANNEL *Permission | ||||||
| var PERMISSION_EDIT_OTHER_USERS *Permission | var PERMISSION_EDIT_OTHER_USERS *Permission | ||||||
| var PERMISSION_READ_CHANNEL *Permission | var PERMISSION_READ_CHANNEL *Permission | ||||||
|  | var PERMISSION_READ_PUBLIC_CHANNEL *Permission | ||||||
| var PERMISSION_PERMANENT_DELETE_USER *Permission | var PERMISSION_PERMANENT_DELETE_USER *Permission | ||||||
| var PERMISSION_UPLOAD_FILE *Permission | var PERMISSION_UPLOAD_FILE *Permission | ||||||
| var PERMISSION_GET_PUBLIC_LINK *Permission | var PERMISSION_GET_PUBLIC_LINK *Permission | ||||||
| @@ -47,6 +48,7 @@ var PERMISSION_MANAGE_OTHERS_WEBHOOKS *Permission | |||||||
| var PERMISSION_MANAGE_OAUTH *Permission | var PERMISSION_MANAGE_OAUTH *Permission | ||||||
| var PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH *Permission | var PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH *Permission | ||||||
| var PERMISSION_CREATE_POST *Permission | var PERMISSION_CREATE_POST *Permission | ||||||
|  | var PERMISSION_CREATE_POST_PUBLIC *Permission | ||||||
| var PERMISSION_EDIT_POST *Permission | var PERMISSION_EDIT_POST *Permission | ||||||
| var PERMISSION_EDIT_OTHERS_POSTS *Permission | var PERMISSION_EDIT_OTHERS_POSTS *Permission | ||||||
| var PERMISSION_DELETE_POST *Permission | var PERMISSION_DELETE_POST *Permission | ||||||
| @@ -56,6 +58,11 @@ var PERMISSION_CREATE_TEAM *Permission | |||||||
| var PERMISSION_MANAGE_TEAM *Permission | var PERMISSION_MANAGE_TEAM *Permission | ||||||
| var PERMISSION_IMPORT_TEAM *Permission | var PERMISSION_IMPORT_TEAM *Permission | ||||||
| var PERMISSION_VIEW_TEAM *Permission | var PERMISSION_VIEW_TEAM *Permission | ||||||
|  | var PERMISSION_LIST_USERS_WITHOUT_TEAM *Permission | ||||||
|  | var PERMISSION_MANAGE_JOBS *Permission | ||||||
|  | var PERMISSION_CREATE_USER_ACCESS_TOKEN *Permission | ||||||
|  | var PERMISSION_READ_USER_ACCESS_TOKEN *Permission | ||||||
|  | var PERMISSION_REVOKE_USER_ACCESS_TOKEN *Permission | ||||||
|  |  | ||||||
| // General permission that encompases all system admin functions | // General permission that encompases all system admin functions | ||||||
| // in the future this could be broken up to allow access to some | // in the future this could be broken up to allow access to some | ||||||
| @@ -64,9 +71,14 @@ var PERMISSION_MANAGE_SYSTEM *Permission | |||||||
|  |  | ||||||
| var ROLE_SYSTEM_USER *Role | var ROLE_SYSTEM_USER *Role | ||||||
| var ROLE_SYSTEM_ADMIN *Role | var ROLE_SYSTEM_ADMIN *Role | ||||||
|  | var ROLE_SYSTEM_POST_ALL *Role | ||||||
|  | var ROLE_SYSTEM_POST_ALL_PUBLIC *Role | ||||||
|  | var ROLE_SYSTEM_USER_ACCESS_TOKEN *Role | ||||||
|  |  | ||||||
| var ROLE_TEAM_USER *Role | var ROLE_TEAM_USER *Role | ||||||
| var ROLE_TEAM_ADMIN *Role | var ROLE_TEAM_ADMIN *Role | ||||||
|  | var ROLE_TEAM_POST_ALL *Role | ||||||
|  | var ROLE_TEAM_POST_ALL_PUBLIC *Role | ||||||
|  |  | ||||||
| var ROLE_CHANNEL_USER *Role | var ROLE_CHANNEL_USER *Role | ||||||
| var ROLE_CHANNEL_ADMIN *Role | var ROLE_CHANNEL_ADMIN *Role | ||||||
| @@ -195,6 +207,11 @@ func InitalizePermissions() { | |||||||
| 		"authentication.permissions.read_channel.name", | 		"authentication.permissions.read_channel.name", | ||||||
| 		"authentication.permissions.read_channel.description", | 		"authentication.permissions.read_channel.description", | ||||||
| 	} | 	} | ||||||
|  | 	PERMISSION_READ_PUBLIC_CHANNEL = &Permission{ | ||||||
|  | 		"read_public_channel", | ||||||
|  | 		"authentication.permissions.read_public_channel.name", | ||||||
|  | 		"authentication.permissions.read_public_channel.description", | ||||||
|  | 	} | ||||||
| 	PERMISSION_PERMANENT_DELETE_USER = &Permission{ | 	PERMISSION_PERMANENT_DELETE_USER = &Permission{ | ||||||
| 		"permanent_delete_user", | 		"permanent_delete_user", | ||||||
| 		"authentication.permissions.permanent_delete_user.name", | 		"authentication.permissions.permanent_delete_user.name", | ||||||
| @@ -235,6 +252,11 @@ func InitalizePermissions() { | |||||||
| 		"authentication.permissions.create_post.name", | 		"authentication.permissions.create_post.name", | ||||||
| 		"authentication.permissions.create_post.description", | 		"authentication.permissions.create_post.description", | ||||||
| 	} | 	} | ||||||
|  | 	PERMISSION_CREATE_POST_PUBLIC = &Permission{ | ||||||
|  | 		"create_post_public", | ||||||
|  | 		"authentication.permissions.create_post_public.name", | ||||||
|  | 		"authentication.permissions.create_post_public.description", | ||||||
|  | 	} | ||||||
| 	PERMISSION_EDIT_POST = &Permission{ | 	PERMISSION_EDIT_POST = &Permission{ | ||||||
| 		"edit_post", | 		"edit_post", | ||||||
| 		"authentication.permissions.edit_post.name", | 		"authentication.permissions.edit_post.name", | ||||||
| @@ -280,6 +302,31 @@ func InitalizePermissions() { | |||||||
| 		"authentication.permissions.view_team.name", | 		"authentication.permissions.view_team.name", | ||||||
| 		"authentication.permissions.view_team.description", | 		"authentication.permissions.view_team.description", | ||||||
| 	} | 	} | ||||||
|  | 	PERMISSION_LIST_USERS_WITHOUT_TEAM = &Permission{ | ||||||
|  | 		"list_users_without_team", | ||||||
|  | 		"authentication.permissions.list_users_without_team.name", | ||||||
|  | 		"authentication.permissions.list_users_without_team.description", | ||||||
|  | 	} | ||||||
|  | 	PERMISSION_CREATE_USER_ACCESS_TOKEN = &Permission{ | ||||||
|  | 		"create_user_access_token", | ||||||
|  | 		"authentication.permissions.create_user_access_token.name", | ||||||
|  | 		"authentication.permissions.create_user_access_token.description", | ||||||
|  | 	} | ||||||
|  | 	PERMISSION_READ_USER_ACCESS_TOKEN = &Permission{ | ||||||
|  | 		"read_user_access_token", | ||||||
|  | 		"authentication.permissions.read_user_access_token.name", | ||||||
|  | 		"authentication.permissions.read_user_access_token.description", | ||||||
|  | 	} | ||||||
|  | 	PERMISSION_REVOKE_USER_ACCESS_TOKEN = &Permission{ | ||||||
|  | 		"revoke_user_access_token", | ||||||
|  | 		"authentication.permissions.revoke_user_access_token.name", | ||||||
|  | 		"authentication.permissions.revoke_user_access_token.description", | ||||||
|  | 	} | ||||||
|  | 	PERMISSION_MANAGE_JOBS = &Permission{ | ||||||
|  | 		"manage_jobs", | ||||||
|  | 		"authentication.permisssions.manage_jobs.name", | ||||||
|  | 		"authentication.permisssions.manage_jobs.description", | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func InitalizeRoles() { | func InitalizeRoles() { | ||||||
| @@ -293,7 +340,6 @@ func InitalizeRoles() { | |||||||
| 		[]string{ | 		[]string{ | ||||||
| 			PERMISSION_READ_CHANNEL.Id, | 			PERMISSION_READ_CHANNEL.Id, | ||||||
| 			PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, | 			PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, | ||||||
| 			PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, |  | ||||||
| 			PERMISSION_UPLOAD_FILE.Id, | 			PERMISSION_UPLOAD_FILE.Id, | ||||||
| 			PERMISSION_GET_PUBLIC_LINK.Id, | 			PERMISSION_GET_PUBLIC_LINK.Id, | ||||||
| 			PERMISSION_CREATE_POST.Id, | 			PERMISSION_CREATE_POST.Id, | ||||||
| @@ -326,17 +372,38 @@ func InitalizeRoles() { | |||||||
| 		[]string{ | 		[]string{ | ||||||
| 			PERMISSION_LIST_TEAM_CHANNELS.Id, | 			PERMISSION_LIST_TEAM_CHANNELS.Id, | ||||||
| 			PERMISSION_JOIN_PUBLIC_CHANNELS.Id, | 			PERMISSION_JOIN_PUBLIC_CHANNELS.Id, | ||||||
|  | 			PERMISSION_READ_PUBLIC_CHANNEL.Id, | ||||||
| 			PERMISSION_VIEW_TEAM.Id, | 			PERMISSION_VIEW_TEAM.Id, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	BuiltInRoles[ROLE_TEAM_USER.Id] = ROLE_TEAM_USER | 	BuiltInRoles[ROLE_TEAM_USER.Id] = ROLE_TEAM_USER | ||||||
|  |  | ||||||
|  | 	ROLE_TEAM_POST_ALL = &Role{ | ||||||
|  | 		"team_post_all", | ||||||
|  | 		"authentication.roles.team_post_all.name", | ||||||
|  | 		"authentication.roles.team_post_all.description", | ||||||
|  | 		[]string{ | ||||||
|  | 			PERMISSION_CREATE_POST.Id, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	BuiltInRoles[ROLE_TEAM_POST_ALL.Id] = ROLE_TEAM_POST_ALL | ||||||
|  |  | ||||||
|  | 	ROLE_TEAM_POST_ALL_PUBLIC = &Role{ | ||||||
|  | 		"team_post_all_public", | ||||||
|  | 		"authentication.roles.team_post_all_public.name", | ||||||
|  | 		"authentication.roles.team_post_all_public.description", | ||||||
|  | 		[]string{ | ||||||
|  | 			PERMISSION_CREATE_POST_PUBLIC.Id, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	BuiltInRoles[ROLE_TEAM_POST_ALL_PUBLIC.Id] = ROLE_TEAM_POST_ALL_PUBLIC | ||||||
|  |  | ||||||
| 	ROLE_TEAM_ADMIN = &Role{ | 	ROLE_TEAM_ADMIN = &Role{ | ||||||
| 		"team_admin", | 		"team_admin", | ||||||
| 		"authentication.roles.team_admin.name", | 		"authentication.roles.team_admin.name", | ||||||
| 		"authentication.roles.team_admin.description", | 		"authentication.roles.team_admin.description", | ||||||
| 		[]string{ | 		[]string{ | ||||||
| 			PERMISSION_EDIT_OTHERS_POSTS.Id, | 			PERMISSION_EDIT_OTHERS_POSTS.Id, | ||||||
| 			PERMISSION_ADD_USER_TO_TEAM.Id, |  | ||||||
| 			PERMISSION_REMOVE_USER_FROM_TEAM.Id, | 			PERMISSION_REMOVE_USER_FROM_TEAM.Id, | ||||||
| 			PERMISSION_MANAGE_TEAM.Id, | 			PERMISSION_MANAGE_TEAM.Id, | ||||||
| 			PERMISSION_IMPORT_TEAM.Id, | 			PERMISSION_IMPORT_TEAM.Id, | ||||||
| @@ -358,10 +425,42 @@ func InitalizeRoles() { | |||||||
| 			PERMISSION_CREATE_DIRECT_CHANNEL.Id, | 			PERMISSION_CREATE_DIRECT_CHANNEL.Id, | ||||||
| 			PERMISSION_CREATE_GROUP_CHANNEL.Id, | 			PERMISSION_CREATE_GROUP_CHANNEL.Id, | ||||||
| 			PERMISSION_PERMANENT_DELETE_USER.Id, | 			PERMISSION_PERMANENT_DELETE_USER.Id, | ||||||
| 			PERMISSION_MANAGE_OAUTH.Id, |  | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	BuiltInRoles[ROLE_SYSTEM_USER.Id] = ROLE_SYSTEM_USER | 	BuiltInRoles[ROLE_SYSTEM_USER.Id] = ROLE_SYSTEM_USER | ||||||
|  |  | ||||||
|  | 	ROLE_SYSTEM_POST_ALL = &Role{ | ||||||
|  | 		"system_post_all", | ||||||
|  | 		"authentication.roles.system_post_all.name", | ||||||
|  | 		"authentication.roles.system_post_all.description", | ||||||
|  | 		[]string{ | ||||||
|  | 			PERMISSION_CREATE_POST.Id, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	BuiltInRoles[ROLE_SYSTEM_POST_ALL.Id] = ROLE_SYSTEM_POST_ALL | ||||||
|  |  | ||||||
|  | 	ROLE_SYSTEM_POST_ALL_PUBLIC = &Role{ | ||||||
|  | 		"system_post_all_public", | ||||||
|  | 		"authentication.roles.system_post_all_public.name", | ||||||
|  | 		"authentication.roles.system_post_all_public.description", | ||||||
|  | 		[]string{ | ||||||
|  | 			PERMISSION_CREATE_POST_PUBLIC.Id, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	BuiltInRoles[ROLE_SYSTEM_POST_ALL_PUBLIC.Id] = ROLE_SYSTEM_POST_ALL_PUBLIC | ||||||
|  |  | ||||||
|  | 	ROLE_SYSTEM_USER_ACCESS_TOKEN = &Role{ | ||||||
|  | 		"system_user_access_token", | ||||||
|  | 		"authentication.roles.system_user_access_token.name", | ||||||
|  | 		"authentication.roles.system_user_access_token.description", | ||||||
|  | 		[]string{ | ||||||
|  | 			PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, | ||||||
|  | 			PERMISSION_READ_USER_ACCESS_TOKEN.Id, | ||||||
|  | 			PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	BuiltInRoles[ROLE_SYSTEM_USER_ACCESS_TOKEN.Id] = ROLE_SYSTEM_USER_ACCESS_TOKEN | ||||||
|  |  | ||||||
| 	ROLE_SYSTEM_ADMIN = &Role{ | 	ROLE_SYSTEM_ADMIN = &Role{ | ||||||
| 		"system_admin", | 		"system_admin", | ||||||
| 		"authentication.roles.global_admin.name", | 		"authentication.roles.global_admin.name", | ||||||
| @@ -378,6 +477,8 @@ func InitalizeRoles() { | |||||||
| 							PERMISSION_MANAGE_SYSTEM.Id, | 							PERMISSION_MANAGE_SYSTEM.Id, | ||||||
| 							PERMISSION_MANAGE_ROLES.Id, | 							PERMISSION_MANAGE_ROLES.Id, | ||||||
| 							PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, | 							PERMISSION_MANAGE_PUBLIC_CHANNEL_PROPERTIES.Id, | ||||||
|  | 							PERMISSION_MANAGE_PUBLIC_CHANNEL_MEMBERS.Id, | ||||||
|  | 							PERMISSION_MANAGE_PRIVATE_CHANNEL_MEMBERS.Id, | ||||||
| 							PERMISSION_DELETE_PUBLIC_CHANNEL.Id, | 							PERMISSION_DELETE_PUBLIC_CHANNEL.Id, | ||||||
| 							PERMISSION_CREATE_PUBLIC_CHANNEL.Id, | 							PERMISSION_CREATE_PUBLIC_CHANNEL.Id, | ||||||
| 							PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, | 							PERMISSION_MANAGE_PRIVATE_CHANNEL_PROPERTIES.Id, | ||||||
| @@ -391,6 +492,13 @@ func InitalizeRoles() { | |||||||
| 							PERMISSION_DELETE_POST.Id, | 							PERMISSION_DELETE_POST.Id, | ||||||
| 							PERMISSION_DELETE_OTHERS_POSTS.Id, | 							PERMISSION_DELETE_OTHERS_POSTS.Id, | ||||||
| 							PERMISSION_CREATE_TEAM.Id, | 							PERMISSION_CREATE_TEAM.Id, | ||||||
|  | 							PERMISSION_ADD_USER_TO_TEAM.Id, | ||||||
|  | 							PERMISSION_LIST_USERS_WITHOUT_TEAM.Id, | ||||||
|  | 							PERMISSION_MANAGE_JOBS.Id, | ||||||
|  | 							PERMISSION_CREATE_POST_PUBLIC.Id, | ||||||
|  | 							PERMISSION_CREATE_USER_ACCESS_TOKEN.Id, | ||||||
|  | 							PERMISSION_READ_USER_ACCESS_TOKEN.Id, | ||||||
|  | 							PERMISSION_REVOKE_USER_ACCESS_TOKEN.Id, | ||||||
| 						}, | 						}, | ||||||
| 						ROLE_TEAM_USER.Permissions..., | 						ROLE_TEAM_USER.Permissions..., | ||||||
| 					), | 					), | ||||||
|   | |||||||
							
								
								
									
										60
									
								
								vendor/github.com/mattermost/platform/model/authorize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/mattermost/platform/model/authorize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,6 +6,7 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -25,6 +26,14 @@ type AuthData struct { | |||||||
| 	Scope       string `json:"scope"` | 	Scope       string `json:"scope"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type AuthorizeRequest struct { | ||||||
|  | 	ResponseType string `json:"response_type"` | ||||||
|  | 	ClientId     string `json:"client_id"` | ||||||
|  | 	RedirectUri  string `json:"redirect_uri"` | ||||||
|  | 	Scope        string `json:"scope"` | ||||||
|  | 	State        string `json:"state"` | ||||||
|  | } | ||||||
|  |  | ||||||
| // IsValid validates the AuthData and returns an error if it isn't configured | // IsValid validates the AuthData and returns an error if it isn't configured | ||||||
| // correctly. | // correctly. | ||||||
| func (ad *AuthData) IsValid() *AppError { | func (ad *AuthData) IsValid() *AppError { | ||||||
| @@ -49,7 +58,7 @@ func (ad *AuthData) IsValid() *AppError { | |||||||
| 		return NewLocAppError("AuthData.IsValid", "model.authorize.is_valid.create_at.app_error", nil, "client_id="+ad.ClientId) | 		return NewLocAppError("AuthData.IsValid", "model.authorize.is_valid.create_at.app_error", nil, "client_id="+ad.ClientId) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(ad.RedirectUri) > 256 { | 	if len(ad.RedirectUri) == 0 || len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) { | ||||||
| 		return NewLocAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ad.ClientId) | 		return NewLocAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ad.ClientId) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -64,6 +73,33 @@ func (ad *AuthData) IsValid() *AppError { | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // IsValid validates the AuthorizeRequest and returns an error if it isn't configured | ||||||
|  | // correctly. | ||||||
|  | func (ar *AuthorizeRequest) IsValid() *AppError { | ||||||
|  |  | ||||||
|  | 	if len(ar.ClientId) != 26 { | ||||||
|  | 		return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(ar.ResponseType) == 0 { | ||||||
|  | 		return NewAppError("AuthData.IsValid", "model.authorize.is_valid.response_type.app_error", nil, "", http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(ar.RedirectUri) == 0 || len(ar.RedirectUri) > 256 || !IsValidHttpUrl(ar.RedirectUri) { | ||||||
|  | 		return NewAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(ar.State) > 128 { | ||||||
|  | 		return NewAppError("AuthData.IsValid", "model.authorize.is_valid.state.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(ar.Scope) > 128 { | ||||||
|  | 		return NewAppError("AuthData.IsValid", "model.authorize.is_valid.scope.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ad *AuthData) PreSave() { | func (ad *AuthData) PreSave() { | ||||||
| 	if ad.ExpiresIn == 0 { | 	if ad.ExpiresIn == 0 { | ||||||
| 		ad.ExpiresIn = AUTHCODE_EXPIRE_TIME | 		ad.ExpiresIn = AUTHCODE_EXPIRE_TIME | ||||||
| @@ -98,6 +134,26 @@ func AuthDataFromJson(data io.Reader) *AuthData { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (ar *AuthorizeRequest) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(ar) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func AuthorizeRequestFromJson(data io.Reader) *AuthorizeRequest { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var ar AuthorizeRequest | ||||||
|  | 	err := decoder.Decode(&ar) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &ar | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (ad *AuthData) IsExpired() bool { | func (ad *AuthData) IsExpired() bool { | ||||||
|  |  | ||||||
| 	if GetMillis() > ad.CreateAt+int64(ad.ExpiresIn*1000) { | 	if GetMillis() > ad.CreateAt+int64(ad.ExpiresIn*1000) { | ||||||
|   | |||||||
							
								
								
									
										47
									
								
								vendor/github.com/mattermost/platform/model/channel.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								vendor/github.com/mattermost/platform/model/channel.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -46,6 +46,13 @@ type Channel struct { | |||||||
| 	CreatorId     string `json:"creator_id"` | 	CreatorId     string `json:"creator_id"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type ChannelPatch struct { | ||||||
|  | 	DisplayName *string `json:"display_name"` | ||||||
|  | 	Name        *string `json:"name"` | ||||||
|  | 	Header      *string `json:"header"` | ||||||
|  | 	Purpose     *string `json:"purpose"` | ||||||
|  | } | ||||||
|  |  | ||||||
| func (o *Channel) ToJson() string { | func (o *Channel) ToJson() string { | ||||||
| 	b, err := json.Marshal(o) | 	b, err := json.Marshal(o) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -55,6 +62,15 @@ func (o *Channel) ToJson() string { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (o *ChannelPatch) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func ChannelFromJson(data io.Reader) *Channel { | func ChannelFromJson(data io.Reader) *Channel { | ||||||
| 	decoder := json.NewDecoder(data) | 	decoder := json.NewDecoder(data) | ||||||
| 	var o Channel | 	var o Channel | ||||||
| @@ -66,6 +82,17 @@ func ChannelFromJson(data io.Reader) *Channel { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ChannelPatchFromJson(data io.Reader) *ChannelPatch { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var o ChannelPatch | ||||||
|  | 	err := decoder.Decode(&o) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &o | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (o *Channel) Etag() string { | func (o *Channel) Etag() string { | ||||||
| 	return Etag(o.Id, o.UpdateAt) | 	return Etag(o.Id, o.UpdateAt) | ||||||
| } | } | ||||||
| @@ -137,6 +164,24 @@ func (o *Channel) IsGroupOrDirect() bool { | |||||||
| 	return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP | 	return o.Type == CHANNEL_DIRECT || o.Type == CHANNEL_GROUP | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (o *Channel) Patch(patch *ChannelPatch) { | ||||||
|  | 	if patch.DisplayName != nil { | ||||||
|  | 		o.DisplayName = *patch.DisplayName | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.Name != nil { | ||||||
|  | 		o.Name = *patch.Name | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.Header != nil { | ||||||
|  | 		o.Header = *patch.Header | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.Purpose != nil { | ||||||
|  | 		o.Purpose = *patch.Purpose | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func GetDMNameFromIds(userId1, userId2 string) string { | func GetDMNameFromIds(userId1, userId2 string) string { | ||||||
| 	if userId1 > userId2 { | 	if userId1 > userId2 { | ||||||
| 		return userId2 + "__" + userId1 | 		return userId2 + "__" + userId1 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_count.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_count.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_data.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_data.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								vendor/github.com/mattermost/platform/model/channel_list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/mattermost/platform/model/channel_list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -50,3 +50,14 @@ func ChannelListFromJson(data io.Reader) *ChannelList { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ChannelSliceFromJson(data io.Reader) []*Channel { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var o []*Channel | ||||||
|  | 	err := decoder.Decode(&o) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return o | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								vendor/github.com/mattermost/platform/model/channel_member.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/mattermost/platform/model/channel_member.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -19,11 +19,11 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type ChannelUnread struct { | type ChannelUnread struct { | ||||||
| 	TeamId        string | 	TeamId       string    `json:"team_id"` | ||||||
| 	TotalMsgCount int64 | 	ChannelId    string    `json:"channel_id"` | ||||||
| 	MsgCount      int64 | 	MsgCount     int64     `json:"msg_count"` | ||||||
| 	MentionCount  int64 | 	MentionCount int64     `json:"mention_count"` | ||||||
| 	NotifyProps   StringMap | 	NotifyProps  StringMap `json:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| type ChannelMember struct { | type ChannelMember struct { | ||||||
| @@ -47,6 +47,15 @@ func (o *ChannelMembers) ToJson() string { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (o *ChannelUnread) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func ChannelMembersFromJson(data io.Reader) *ChannelMembers { | func ChannelMembersFromJson(data io.Reader) *ChannelMembers { | ||||||
| 	decoder := json.NewDecoder(data) | 	decoder := json.NewDecoder(data) | ||||||
| 	var o ChannelMembers | 	var o ChannelMembers | ||||||
| @@ -58,6 +67,17 @@ func ChannelMembersFromJson(data io.Reader) *ChannelMembers { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func ChannelUnreadFromJson(data io.Reader) *ChannelUnread { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var o ChannelUnread | ||||||
|  | 	err := decoder.Decode(&o) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &o | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (o *ChannelMember) ToJson() string { | func (o *ChannelMember) ToJson() string { | ||||||
| 	b, err := json.Marshal(o) | 	b, err := json.Marshal(o) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_search.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_view.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/channel_view.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										80
									
								
								vendor/github.com/mattermost/platform/model/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/github.com/mattermost/platform/model/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -1191,17 +1191,6 @@ func (c *Client) GetChannel(id, etag string) (*Result, *AppError) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // SCHEDULED FOR DEPRECATION IN 3.7 - use GetMoreChannelsPage instead |  | ||||||
| func (c *Client) GetMoreChannels(etag string) (*Result, *AppError) { |  | ||||||
| 	if r, err := c.DoApiGet(c.GetTeamRoute()+"/channels/more", "", etag); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} else { |  | ||||||
| 		defer closeBody(r) |  | ||||||
| 		return &Result{r.Header.Get(HEADER_REQUEST_ID), |  | ||||||
| 			r.Header.Get(HEADER_ETAG_SERVER), ChannelListFromJson(r.Body)}, nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetMoreChannelsPage will return a page of open channels the user is not in based on | // GetMoreChannelsPage will return a page of open channels the user is not in based on | ||||||
| // the provided offset and limit. Must be authenticated. | // the provided offset and limit. Must be authenticated. | ||||||
| func (c *Client) GetMoreChannelsPage(offset int, limit int) (*Result, *AppError) { | func (c *Client) GetMoreChannelsPage(offset int, limit int) (*Result, *AppError) { | ||||||
| @@ -1333,22 +1322,6 @@ func (c *Client) RemoveChannelMember(id, user_id string) (*Result, *AppError) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // UpdateLastViewedAt will mark a channel as read. |  | ||||||
| // The channelId indicates the channel to mark as read. If active is true, push notifications |  | ||||||
| // will be cleared if there are unread messages. The default for active is true. |  | ||||||
| // SCHEDULED FOR DEPRECATION IN 3.8 - use ViewChannel instead |  | ||||||
| func (c *Client) UpdateLastViewedAt(channelId string, active bool) (*Result, *AppError) { |  | ||||||
| 	data := make(map[string]interface{}) |  | ||||||
| 	data["active"] = active |  | ||||||
| 	if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/update_last_viewed_at", StringInterfaceToJson(data)); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} else { |  | ||||||
| 		defer closeBody(r) |  | ||||||
| 		return &Result{r.Header.Get(HEADER_REQUEST_ID), |  | ||||||
| 			r.Header.Get(HEADER_ETAG_SERVER), nil}, nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ViewChannel performs all the actions related to viewing a channel. This includes marking | // ViewChannel performs all the actions related to viewing a channel. This includes marking | ||||||
| // the channel and the previous one as read, and marking the channel as being actively viewed. | // the channel and the previous one as read, and marking the channel as being actively viewed. | ||||||
| // ChannelId is required but may be blank to indicate no channel is being viewed. | // ChannelId is required but may be blank to indicate no channel is being viewed. | ||||||
| @@ -1533,6 +1506,16 @@ func (c *Client) GetFlaggedPosts(offset int, limit int) (*Result, *AppError) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (c *Client) GetPinnedPosts(channelId string) (*Result, *AppError) { | ||||||
|  | 	if r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/pinned", "", ""); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} else { | ||||||
|  | 		defer closeBody(r) | ||||||
|  | 		return &Result{r.Header.Get(HEADER_REQUEST_ID), | ||||||
|  | 			r.Header.Get(HEADER_ETAG_SERVER), PostListFromJson(r.Body)}, nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *AppError) { | func (c *Client) UploadProfileFile(data []byte, contentType string) (*Result, *AppError) { | ||||||
| 	return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType) | 	return c.uploadFile(c.ApiUrl+"/users/newimage", data, contentType) | ||||||
| } | } | ||||||
| @@ -1782,22 +1765,6 @@ func (c *Client) GetStatusesByIds(userIds []string) (*Result, *AppError) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // SetActiveChannel sets the the channel id the user is currently viewing. |  | ||||||
| // The channelId key is required but the value can be blank. Returns standard |  | ||||||
| // response. |  | ||||||
| // SCHEDULED FOR DEPRECATION IN 3.8 - use ViewChannel instead |  | ||||||
| func (c *Client) SetActiveChannel(channelId string) (*Result, *AppError) { |  | ||||||
| 	data := map[string]string{} |  | ||||||
| 	data["channel_id"] = channelId |  | ||||||
| 	if r, err := c.DoApiPost("/users/status/set_active_channel", MapToJson(data)); err != nil { |  | ||||||
| 		return nil, err |  | ||||||
| 	} else { |  | ||||||
| 		defer closeBody(r) |  | ||||||
| 		return &Result{r.Header.Get(HEADER_REQUEST_ID), |  | ||||||
| 			r.Header.Get(HEADER_ETAG_SERVER), MapFromJson(r.Body)}, nil |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (c *Client) GetMyTeam(etag string) (*Result, *AppError) { | func (c *Client) GetMyTeam(etag string) (*Result, *AppError) { | ||||||
| 	if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil { | 	if r, err := c.DoApiGet(c.GetTeamRoute()+"/me", "", etag); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| @@ -1874,15 +1841,14 @@ func (c *Client) GetTeamStats(teamId string) (*Result, *AppError) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetTeamStats will return a team stats object containing the number of users on the team | // GetTeamByName will return a team object based on the team name provided. Must be authenticated. | ||||||
| // based on the team id provided. Must be authenticated. |  | ||||||
| func (c *Client) GetTeamByName(teamName string) (*Result, *AppError) { | func (c *Client) GetTeamByName(teamName string) (*Result, *AppError) { | ||||||
| 	if r, err := c.DoApiGet(fmt.Sprintf("/teams/name/%v", teamName), "", ""); err != nil { | 	if r, err := c.DoApiGet(fmt.Sprintf("/teams/name/%v", teamName), "", ""); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} else { | 	} else { | ||||||
| 		defer closeBody(r) | 		defer closeBody(r) | ||||||
| 		return &Result{r.Header.Get(HEADER_REQUEST_ID), | 		return &Result{r.Header.Get(HEADER_REQUEST_ID), | ||||||
| 			r.Header.Get(HEADER_ETAG_SERVER), TeamStatsFromJson(r.Body)}, nil | 			r.Header.Get(HEADER_ETAG_SERVER), TeamFromJson(r.Body)}, nil | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -2389,3 +2355,23 @@ func (c *Client) UpdateChannelRoles(channelId string, userId string, roles strin | |||||||
| 			} | 			} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (c *Client) PinPost(channelId string, postId string) (*Result, *AppError) { | ||||||
|  | 	if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/posts/"+postId+"/pin", ""); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} else { | ||||||
|  | 		defer closeBody(r) | ||||||
|  | 		return &Result{r.Header.Get(HEADER_REQUEST_ID), | ||||||
|  | 			r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *Client) UnpinPost(channelId string, postId string) (*Result, *AppError) { | ||||||
|  | 	if r, err := c.DoApiPost(c.GetChannelRoute(channelId)+"/posts/"+postId+"/unpin", ""); err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} else { | ||||||
|  | 		defer closeBody(r) | ||||||
|  | 		return &Result{r.Header.Get(HEADER_REQUEST_ID), | ||||||
|  | 			r.Header.Get(HEADER_ETAG_SERVER), PostFromJson(r.Body)}, nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										2215
									
								
								vendor/github.com/mattermost/platform/model/client4.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2215
									
								
								vendor/github.com/mattermost/platform/model/client4.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										132
									
								
								vendor/github.com/mattermost/platform/model/cluster_discovery.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/mattermost/platform/model/cluster_discovery.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	CDS_OFFLINE_AFTER_MILLIS = 1000 * 60 * 30 // 30 minutes | ||||||
|  | 	CDS_TYPE_APP             = "mattermost_app" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type ClusterDiscovery struct { | ||||||
|  | 	Id          string `json:"id"` | ||||||
|  | 	Type        string `json:"type"` | ||||||
|  | 	ClusterName string `json:"cluster_name"` | ||||||
|  | 	Hostname    string `json:"hostname"` | ||||||
|  | 	GossipPort  int32  `json:"gossip_port"` | ||||||
|  | 	Port        int32  `json:"port"` | ||||||
|  | 	CreateAt    int64  `json:"create_at"` | ||||||
|  | 	LastPingAt  int64  `json:"last_ping_at"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) PreSave() { | ||||||
|  | 	if o.Id == "" { | ||||||
|  | 		o.Id = NewId() | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.CreateAt == 0 { | ||||||
|  | 		o.CreateAt = GetMillis() | ||||||
|  | 		o.LastPingAt = o.CreateAt | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) AutoFillHostname() { | ||||||
|  | 	// attempt to set the hostname from the OS | ||||||
|  | 	if len(o.Hostname) == 0 { | ||||||
|  | 		if hn, err := os.Hostname(); err == nil { | ||||||
|  | 			o.Hostname = hn | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) AutoFillIpAddress() { | ||||||
|  | 	// attempt to set the hostname to the first non-local IP address | ||||||
|  | 	if len(o.Hostname) == 0 { | ||||||
|  | 		o.Hostname = GetServerIpAddress() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) IsEqual(in *ClusterDiscovery) bool { | ||||||
|  | 	if in == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.Type != in.Type { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterName != in.ClusterName { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.Hostname != in.Hostname { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func FilterClusterDiscovery(vs []*ClusterDiscovery, f func(*ClusterDiscovery) bool) []*ClusterDiscovery { | ||||||
|  | 	copy := make([]*ClusterDiscovery, 0) | ||||||
|  | 	for _, v := range vs { | ||||||
|  | 		if f(v) { | ||||||
|  | 			copy = append(copy, v) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return copy | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) IsValid() *AppError { | ||||||
|  | 	if len(o.Id) != 26 { | ||||||
|  | 		return NewLocAppError("Channel.IsValid", "model.channel.is_valid.id.app_error", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(o.ClusterName) == 0 { | ||||||
|  | 		return NewLocAppError("ClusterDiscovery.IsValid", "ClusterName must be set", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(o.Type) == 0 { | ||||||
|  | 		return NewLocAppError("ClusterDiscovery.IsValid", "Type must be set", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(o.Hostname) == 0 { | ||||||
|  | 		return NewLocAppError("ClusterDiscovery.IsValid", "Hostname must be set", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.CreateAt == 0 { | ||||||
|  | 		return NewLocAppError("ClusterDiscovery.IsValid", "CreateAt must be set", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.LastPingAt == 0 { | ||||||
|  | 		return NewLocAppError("ClusterDiscovery.IsValid", "LastPingAt must be set", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterDiscovery) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return string(b) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ClusterDiscoveryFromJson(data io.Reader) *ClusterDiscovery { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var me ClusterDiscovery | ||||||
|  | 	err := decoder.Decode(&me) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &me | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								vendor/github.com/mattermost/platform/model/cluster_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/mattermost/platform/model/cluster_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,16 +6,14 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"strings" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ClusterInfo struct { | type ClusterInfo struct { | ||||||
| 	Id                 string `json:"id"` |  | ||||||
| 	Version    string `json:"version"` | 	Version    string `json:"version"` | ||||||
| 	ConfigHash string `json:"config_hash"` | 	ConfigHash string `json:"config_hash"` | ||||||
| 	InterNodeUrl       string `json:"internode_url"` | 	IpAddress  string `json:"ipaddress"` | ||||||
| 	Hostname   string `json:"hostname"` | 	Hostname   string `json:"hostname"` | ||||||
| 	LastSuccessfulPing int64  `json:"last_ping"` |  | ||||||
| 	IsAlive            bool   `json:"is_alive"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (me *ClusterInfo) ToJson() string { | func (me *ClusterInfo) ToJson() string { | ||||||
| @@ -27,6 +25,11 @@ func (me *ClusterInfo) ToJson() string { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (me *ClusterInfo) Copy() *ClusterInfo { | ||||||
|  | 	json := me.ToJson() | ||||||
|  | 	return ClusterInfoFromJson(strings.NewReader(json)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func ClusterInfoFromJson(data io.Reader) *ClusterInfo { | func ClusterInfoFromJson(data io.Reader) *ClusterInfo { | ||||||
| 	decoder := json.NewDecoder(data) | 	decoder := json.NewDecoder(data) | ||||||
| 	var me ClusterInfo | 	var me ClusterInfo | ||||||
| @@ -38,14 +41,6 @@ func ClusterInfoFromJson(data io.Reader) *ClusterInfo { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (me *ClusterInfo) HaveEstablishedInitialContact() bool { |  | ||||||
| 	if me.Id != "" { |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func ClusterInfosToJson(objmap []*ClusterInfo) string { | func ClusterInfosToJson(objmap []*ClusterInfo) string { | ||||||
| 	if b, err := json.Marshal(objmap); err != nil { | 	if b, err := json.Marshal(objmap); err != nil { | ||||||
| 		return "" | 		return "" | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								vendor/github.com/mattermost/platform/model/cluster_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/github.com/mattermost/platform/model/cluster_message.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	CLUSTER_EVENT_PUBLISH                                           = "publish" | ||||||
|  | 	CLUSTER_EVENT_UPDATE_STATUS                                     = "update_status" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_ALL_CACHES                             = "inv_all_caches" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_REACTIONS                    = "inv_reactions" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_WEBHOOK                      = "inv_webhook" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_POSTS                = "inv_channel_posts" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS_NOTIFY_PROPS = "inv_channel_members_notify_props" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_MEMBERS              = "inv_channel_members" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL_BY_NAME              = "inv_channel_name" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_CHANNEL                      = "inv_channel" | ||||||
|  | 	CLUSTER_EVENT_INVALIDATE_CACHE_FOR_USER                         = "inv_user" | ||||||
|  | 	CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_USER                      = "clear_session_user" | ||||||
|  |  | ||||||
|  | 	CLUSTER_SEND_BEST_EFFORT = "best_effort" | ||||||
|  | 	CLUSTER_SEND_RELIABLE    = "reliable" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type ClusterMessage struct { | ||||||
|  | 	Event            string            `json:"event"` | ||||||
|  | 	SendType         string            `json:"-"` | ||||||
|  | 	WaitForAllToSend bool              `json:"-"` | ||||||
|  | 	Data             string            `json:"data,omitempty"` | ||||||
|  | 	Props            map[string]string `json:"props,omitempty"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *ClusterMessage) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func ClusterMessageFromJson(data io.Reader) *ClusterMessage { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var o ClusterMessage | ||||||
|  | 	err := decoder.Decode(&o) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &o | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/cluster_stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/cluster_stats.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								vendor/github.com/mattermost/platform/model/command_args.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/mattermost/platform/model/command_args.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,13 +6,20 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"io" | 	"io" | ||||||
|  |  | ||||||
|  | 	goi18n "github.com/nicksnyder/go-i18n/i18n" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type CommandArgs struct { | type CommandArgs struct { | ||||||
|  | 	UserId    string               `json:"user_id"` | ||||||
| 	ChannelId string               `json:"channel_id"` | 	ChannelId string               `json:"channel_id"` | ||||||
|  | 	TeamId    string               `json:"team_id"` | ||||||
| 	RootId    string               `json:"root_id"` | 	RootId    string               `json:"root_id"` | ||||||
| 	ParentId  string               `json:"parent_id"` | 	ParentId  string               `json:"parent_id"` | ||||||
| 	Command   string               `json:"command"` | 	Command   string               `json:"command"` | ||||||
|  | 	SiteURL   string               `json:"-"` | ||||||
|  | 	T         goi18n.TranslateFunc `json:"-"` | ||||||
|  | 	Session   Session              `json:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *CommandArgs) ToJson() string { | func (o *CommandArgs) ToJson() string { | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								vendor/github.com/mattermost/platform/model/command_response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/mattermost/platform/model/command_response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,11 +1,10 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -40,14 +39,8 @@ func CommandResponseFromJson(data io.Reader) *CommandResponse { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Ensure attachment fields are stored as strings | 	o.Text = ExpandAnnouncement(o.Text) | ||||||
| 	for _, attachment := range o.Attachments { | 	o.Attachments = ProcessSlackAttachments(o.Attachments) | ||||||
| 		for _, field := range attachment.Fields { |  | ||||||
| 			if field.Value != nil { |  | ||||||
| 				field.Value = fmt.Sprintf("%v", field.Value) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return &o | 	return &o | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/compliance.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/compliance.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								vendor/github.com/mattermost/platform/model/compliance_post.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/mattermost/platform/model/compliance_post.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,10 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"regexp" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -64,6 +65,15 @@ func CompliancePostHeader() []string { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func cleanComplianceStrings(in string) string { | ||||||
|  | 	if matched, _ := regexp.MatchString("^\\s*(=|\\+|\\-)", in); matched { | ||||||
|  | 		return "'" + in | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  | 		return in | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (me *CompliancePost) Row() []string { | func (me *CompliancePost) Row() []string { | ||||||
|  |  | ||||||
| 	postDeleteAt := "" | 	postDeleteAt := "" | ||||||
| @@ -77,15 +87,15 @@ func (me *CompliancePost) Row() []string { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return []string{ | 	return []string{ | ||||||
| 		me.TeamName, | 		cleanComplianceStrings(me.TeamName), | ||||||
| 		me.TeamDisplayName, | 		cleanComplianceStrings(me.TeamDisplayName), | ||||||
|  |  | ||||||
| 		me.ChannelName, | 		cleanComplianceStrings(me.ChannelName), | ||||||
| 		me.ChannelDisplayName, | 		cleanComplianceStrings(me.ChannelDisplayName), | ||||||
|  |  | ||||||
| 		me.UserUsername, | 		cleanComplianceStrings(me.UserUsername), | ||||||
| 		me.UserEmail, | 		cleanComplianceStrings(me.UserEmail), | ||||||
| 		me.UserNickname, | 		cleanComplianceStrings(me.UserNickname), | ||||||
|  |  | ||||||
| 		me.PostId, | 		me.PostId, | ||||||
| 		time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339), | 		time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339), | ||||||
| @@ -95,7 +105,7 @@ func (me *CompliancePost) Row() []string { | |||||||
| 		me.PostRootId, | 		me.PostRootId, | ||||||
| 		me.PostParentId, | 		me.PostParentId, | ||||||
| 		me.PostOriginalId, | 		me.PostOriginalId, | ||||||
| 		me.PostMessage, | 		cleanComplianceStrings(me.PostMessage), | ||||||
| 		me.PostType, | 		me.PostType, | ||||||
| 		me.PostProps, | 		me.PostProps, | ||||||
| 		me.PostHashtags, | 		me.PostHashtags, | ||||||
|   | |||||||
							
								
								
									
										452
									
								
								vendor/github.com/mattermost/platform/model/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										452
									
								
								vendor/github.com/mattermost/platform/model/config.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,6 +6,7 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -32,12 +33,17 @@ const ( | |||||||
| 	WEBSERVER_MODE_GZIP     = "gzip" | 	WEBSERVER_MODE_GZIP     = "gzip" | ||||||
| 	WEBSERVER_MODE_DISABLED = "disabled" | 	WEBSERVER_MODE_DISABLED = "disabled" | ||||||
|  |  | ||||||
|  | 	GENERIC_NO_CHANNEL_NOTIFICATION = "generic_no_channel" | ||||||
| 	GENERIC_NOTIFICATION            = "generic" | 	GENERIC_NOTIFICATION            = "generic" | ||||||
| 	FULL_NOTIFICATION               = "full" | 	FULL_NOTIFICATION               = "full" | ||||||
|  |  | ||||||
| 	DIRECT_MESSAGE_ANY  = "any" | 	DIRECT_MESSAGE_ANY  = "any" | ||||||
| 	DIRECT_MESSAGE_TEAM = "team" | 	DIRECT_MESSAGE_TEAM = "team" | ||||||
|  |  | ||||||
|  | 	SHOW_USERNAME          = "username" | ||||||
|  | 	SHOW_NICKNAME_FULLNAME = "nickname_full_name" | ||||||
|  | 	SHOW_FULLNAME          = "full_name" | ||||||
|  |  | ||||||
| 	PERMISSIONS_ALL           = "all" | 	PERMISSIONS_ALL           = "all" | ||||||
| 	PERMISSIONS_CHANNEL_ADMIN = "channel_admin" | 	PERMISSIONS_CHANNEL_ADMIN = "channel_admin" | ||||||
| 	PERMISSIONS_TEAM_ADMIN    = "team_admin" | 	PERMISSIONS_TEAM_ADMIN    = "team_admin" | ||||||
| @@ -60,6 +66,9 @@ const ( | |||||||
| 	EMAIL_BATCHING_BUFFER_SIZE = 256 | 	EMAIL_BATCHING_BUFFER_SIZE = 256 | ||||||
| 	EMAIL_BATCHING_INTERVAL    = 30 | 	EMAIL_BATCHING_INTERVAL    = 30 | ||||||
|  |  | ||||||
|  | 	EMAIL_NOTIFICATION_CONTENTS_FULL    = "full" | ||||||
|  | 	EMAIL_NOTIFICATION_CONTENTS_GENERIC = "generic" | ||||||
|  |  | ||||||
| 	SITENAME_MAX_LENGTH = 30 | 	SITENAME_MAX_LENGTH = 30 | ||||||
|  |  | ||||||
| 	SERVICE_SETTINGS_DEFAULT_SITE_URL        = "" | 	SERVICE_SETTINGS_DEFAULT_SITE_URL        = "" | ||||||
| @@ -80,6 +89,9 @@ const ( | |||||||
| 	SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK                 = "https://about.mattermost.com/default-about/" | 	SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK                 = "https://about.mattermost.com/default-about/" | ||||||
| 	SUPPORT_SETTINGS_DEFAULT_HELP_LINK                  = "https://about.mattermost.com/default-help/" | 	SUPPORT_SETTINGS_DEFAULT_HELP_LINK                  = "https://about.mattermost.com/default-help/" | ||||||
| 	SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK      = "https://about.mattermost.com/default-report-a-problem/" | 	SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK      = "https://about.mattermost.com/default-report-a-problem/" | ||||||
|  | 	SUPPORT_SETTINGS_DEFAULT_ADMINISTRATORS_GUIDE_LINK  = "https://about.mattermost.com/administrators-guide/" | ||||||
|  | 	SUPPORT_SETTINGS_DEFAULT_TROUBLESHOOTING_FORUM_LINK = "https://about.mattermost.com/troubleshooting-forum/" | ||||||
|  | 	SUPPORT_SETTINGS_DEFAULT_COMMERCIAL_SUPPORT_LINK    = "https://about.mattermost.com/commercial-support/" | ||||||
| 	SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL              = "feedback@mattermost.com" | 	SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL              = "feedback@mattermost.com" | ||||||
|  |  | ||||||
| 	LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = "" | 	LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = "" | ||||||
| @@ -107,10 +119,20 @@ const ( | |||||||
| 	WEBRTC_SETTINGS_DEFAULT_TURN_URI = "" | 	WEBRTC_SETTINGS_DEFAULT_TURN_URI = "" | ||||||
|  |  | ||||||
| 	ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS = 2500 | 	ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS = 2500 | ||||||
|  |  | ||||||
|  | 	ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR      = "#f2a93b" | ||||||
|  | 	ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR = "#333333" | ||||||
|  |  | ||||||
|  | 	ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL      = "" | ||||||
|  | 	ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME            = "" | ||||||
|  | 	ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD            = "" | ||||||
|  | 	ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_REPLICAS = 1 | ||||||
|  | 	ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_SHARDS   = 1 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type ServiceSettings struct { | type ServiceSettings struct { | ||||||
| 	SiteURL                                  *string | 	SiteURL                                  *string | ||||||
|  | 	LicenseFileLocation                      *string | ||||||
| 	ListenAddress                            string | 	ListenAddress                            string | ||||||
| 	ConnectionSecurity                       *string | 	ConnectionSecurity                       *string | ||||||
| 	TLSCertFile                              *string | 	TLSCertFile                              *string | ||||||
| @@ -121,6 +143,7 @@ type ServiceSettings struct { | |||||||
| 	ReadTimeout                              *int | 	ReadTimeout                              *int | ||||||
| 	WriteTimeout                             *int | 	WriteTimeout                             *int | ||||||
| 	MaximumLoginAttempts                     int | 	MaximumLoginAttempts                     int | ||||||
|  | 	GoroutineHealthThreshold                 *int | ||||||
| 	GoogleDeveloperKey                       string | 	GoogleDeveloperKey                       string | ||||||
| 	EnableOAuthServiceProvider               bool | 	EnableOAuthServiceProvider               bool | ||||||
| 	EnableIncomingWebhooks                   bool | 	EnableIncomingWebhooks                   bool | ||||||
| @@ -129,6 +152,7 @@ type ServiceSettings struct { | |||||||
| 	EnableOnlyAdminIntegrations              *bool | 	EnableOnlyAdminIntegrations              *bool | ||||||
| 	EnablePostUsernameOverride               bool | 	EnablePostUsernameOverride               bool | ||||||
| 	EnablePostIconOverride                   bool | 	EnablePostIconOverride                   bool | ||||||
|  | 	EnableAPIv3                              *bool | ||||||
| 	EnableLinkPreviews                       *bool | 	EnableLinkPreviews                       *bool | ||||||
| 	EnableTesting                            bool | 	EnableTesting                            bool | ||||||
| 	EnableDeveloper                          *bool | 	EnableDeveloper                          *bool | ||||||
| @@ -136,6 +160,7 @@ type ServiceSettings struct { | |||||||
| 	EnableInsecureOutgoingConnections        *bool | 	EnableInsecureOutgoingConnections        *bool | ||||||
| 	EnableMultifactorAuthentication          *bool | 	EnableMultifactorAuthentication          *bool | ||||||
| 	EnforceMultifactorAuthentication         *bool | 	EnforceMultifactorAuthentication         *bool | ||||||
|  | 	EnableUserAccessTokens                   *bool | ||||||
| 	AllowCorsFrom                            *string | 	AllowCorsFrom                            *string | ||||||
| 	SessionLengthWebInDays                   *int | 	SessionLengthWebInDays                   *int | ||||||
| 	SessionLengthMobileInDays                *int | 	SessionLengthMobileInDays                *int | ||||||
| @@ -145,19 +170,28 @@ type ServiceSettings struct { | |||||||
| 	WebsocketPort                            *int | 	WebsocketPort                            *int | ||||||
| 	WebserverMode                            *string | 	WebserverMode                            *string | ||||||
| 	EnableCustomEmoji                        *bool | 	EnableCustomEmoji                        *bool | ||||||
|  | 	EnableEmojiPicker                        *bool | ||||||
| 	RestrictCustomEmojiCreation              *string | 	RestrictCustomEmojiCreation              *string | ||||||
| 	RestrictPostDelete                       *string | 	RestrictPostDelete                       *string | ||||||
| 	AllowEditPost                            *string | 	AllowEditPost                            *string | ||||||
| 	PostEditTimeLimit                        *int | 	PostEditTimeLimit                        *int | ||||||
| 	TimeBetweenUserTypingUpdatesMilliseconds *int64 | 	TimeBetweenUserTypingUpdatesMilliseconds *int64 | ||||||
|  | 	EnablePostSearch                         *bool | ||||||
| 	EnableUserTypingMessages                 *bool | 	EnableUserTypingMessages                 *bool | ||||||
|  | 	EnableChannelViewedMessages              *bool | ||||||
|  | 	EnableUserStatuses                       *bool | ||||||
| 	ClusterLogTimeoutMilliseconds            *int | 	ClusterLogTimeoutMilliseconds            *int | ||||||
| } | } | ||||||
|  |  | ||||||
| type ClusterSettings struct { | type ClusterSettings struct { | ||||||
| 	Enable                *bool | 	Enable                *bool | ||||||
| 	InterNodeListenAddress *string | 	ClusterName           *string | ||||||
| 	InterNodeUrls          []string | 	OverrideHostname      *string | ||||||
|  | 	UseIpAddress          *bool | ||||||
|  | 	UseExperimentalGossip *bool | ||||||
|  | 	ReadOnlyConfig        *bool | ||||||
|  | 	GossipPort            *int | ||||||
|  | 	StreamingPort         *int | ||||||
| } | } | ||||||
|  |  | ||||||
| type MetricsSettings struct { | type MetricsSettings struct { | ||||||
| @@ -184,10 +218,12 @@ type SqlSettings struct { | |||||||
| 	DriverName               string | 	DriverName               string | ||||||
| 	DataSource               string | 	DataSource               string | ||||||
| 	DataSourceReplicas       []string | 	DataSourceReplicas       []string | ||||||
|  | 	DataSourceSearchReplicas []string | ||||||
| 	MaxIdleConns             int | 	MaxIdleConns             int | ||||||
| 	MaxOpenConns             int | 	MaxOpenConns             int | ||||||
| 	Trace                    bool | 	Trace                    bool | ||||||
| 	AtRestEncryptKey         string | 	AtRestEncryptKey         string | ||||||
|  | 	QueryTimeout             *int | ||||||
| } | } | ||||||
|  |  | ||||||
| type LogSettings struct { | type LogSettings struct { | ||||||
| @@ -210,17 +246,14 @@ type PasswordSettings struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| type FileSettings struct { | type FileSettings struct { | ||||||
|  | 	EnableFileAttachments   *bool | ||||||
|  | 	EnableMobileUpload      *bool | ||||||
|  | 	EnableMobileDownload    *bool | ||||||
| 	MaxFileSize             *int64 | 	MaxFileSize             *int64 | ||||||
| 	DriverName              string | 	DriverName              string | ||||||
| 	Directory               string | 	Directory               string | ||||||
| 	EnablePublicLink        bool | 	EnablePublicLink        bool | ||||||
| 	PublicLinkSalt          *string | 	PublicLinkSalt          *string | ||||||
| 	ThumbnailWidth          int |  | ||||||
| 	ThumbnailHeight         int |  | ||||||
| 	PreviewWidth            int |  | ||||||
| 	PreviewHeight           int |  | ||||||
| 	ProfileWidth            int |  | ||||||
| 	ProfileHeight           int |  | ||||||
| 	InitialFont             string | 	InitialFont             string | ||||||
| 	AmazonS3AccessKeyId     string | 	AmazonS3AccessKeyId     string | ||||||
| 	AmazonS3SecretAccessKey string | 	AmazonS3SecretAccessKey string | ||||||
| @@ -228,6 +261,8 @@ type FileSettings struct { | |||||||
| 	AmazonS3Region          string | 	AmazonS3Region          string | ||||||
| 	AmazonS3Endpoint        string | 	AmazonS3Endpoint        string | ||||||
| 	AmazonS3SSL             *bool | 	AmazonS3SSL             *bool | ||||||
|  | 	AmazonS3SignV2          *bool | ||||||
|  | 	AmazonS3SSE             *bool | ||||||
| } | } | ||||||
|  |  | ||||||
| type EmailSettings struct { | type EmailSettings struct { | ||||||
| @@ -239,19 +274,21 @@ type EmailSettings struct { | |||||||
| 	FeedbackName                      string | 	FeedbackName                      string | ||||||
| 	FeedbackEmail                     string | 	FeedbackEmail                     string | ||||||
| 	FeedbackOrganization              *string | 	FeedbackOrganization              *string | ||||||
|  | 	EnableSMTPAuth                    *bool | ||||||
| 	SMTPUsername                      string | 	SMTPUsername                      string | ||||||
| 	SMTPPassword                      string | 	SMTPPassword                      string | ||||||
| 	SMTPServer                        string | 	SMTPServer                        string | ||||||
| 	SMTPPort                          string | 	SMTPPort                          string | ||||||
| 	ConnectionSecurity                string | 	ConnectionSecurity                string | ||||||
| 	InviteSalt                        string | 	InviteSalt                        string | ||||||
| 	PasswordResetSalt        string |  | ||||||
| 	SendPushNotifications             *bool | 	SendPushNotifications             *bool | ||||||
| 	PushNotificationServer            *string | 	PushNotificationServer            *string | ||||||
| 	PushNotificationContents          *string | 	PushNotificationContents          *string | ||||||
| 	EnableEmailBatching               *bool | 	EnableEmailBatching               *bool | ||||||
| 	EmailBatchingBufferSize           *int | 	EmailBatchingBufferSize           *int | ||||||
| 	EmailBatchingInterval             *int | 	EmailBatchingInterval             *int | ||||||
|  | 	SkipServerCertificateVerification *bool | ||||||
|  | 	EmailNotificationContentsType     *string | ||||||
| } | } | ||||||
|  |  | ||||||
| type RateLimitSettings struct { | type RateLimitSettings struct { | ||||||
| @@ -274,9 +311,20 @@ type SupportSettings struct { | |||||||
| 	AboutLink                *string | 	AboutLink                *string | ||||||
| 	HelpLink                 *string | 	HelpLink                 *string | ||||||
| 	ReportAProblemLink       *string | 	ReportAProblemLink       *string | ||||||
|  | 	AdministratorsGuideLink  *string | ||||||
|  | 	TroubleshootingForumLink *string | ||||||
|  | 	CommercialSupportLink    *string | ||||||
| 	SupportEmail             *string | 	SupportEmail             *string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type AnnouncementSettings struct { | ||||||
|  | 	EnableBanner         *bool | ||||||
|  | 	BannerText           *string | ||||||
|  | 	BannerColor          *string | ||||||
|  | 	BannerTextColor      *string | ||||||
|  | 	AllowBannerDismissal *bool | ||||||
|  | } | ||||||
|  |  | ||||||
| type TeamSettings struct { | type TeamSettings struct { | ||||||
| 	SiteName                            string | 	SiteName                            string | ||||||
| 	MaxUsersPerTeam                     int | 	MaxUsersPerTeam                     int | ||||||
| @@ -295,9 +343,11 @@ type TeamSettings struct { | |||||||
| 	RestrictPrivateChannelCreation      *string | 	RestrictPrivateChannelCreation      *string | ||||||
| 	RestrictPublicChannelDeletion       *string | 	RestrictPublicChannelDeletion       *string | ||||||
| 	RestrictPrivateChannelDeletion      *string | 	RestrictPrivateChannelDeletion      *string | ||||||
|  | 	RestrictPrivateChannelManageMembers *string | ||||||
| 	UserStatusAwayTimeout               *int64 | 	UserStatusAwayTimeout               *int64 | ||||||
| 	MaxChannelsPerTeam                  *int64 | 	MaxChannelsPerTeam                  *int64 | ||||||
| 	MaxNotificationsPerChannel          *int64 | 	MaxNotificationsPerChannel          *int64 | ||||||
|  | 	TeammateNameDisplay                 *string | ||||||
| } | } | ||||||
|  |  | ||||||
| type LdapSettings struct { | type LdapSettings struct { | ||||||
| @@ -389,6 +439,30 @@ type WebrtcSettings struct { | |||||||
| 	TurnSharedKey       *string | 	TurnSharedKey       *string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type ElasticsearchSettings struct { | ||||||
|  | 	ConnectionUrl     *string | ||||||
|  | 	Username          *string | ||||||
|  | 	Password          *string | ||||||
|  | 	EnableIndexing    *bool | ||||||
|  | 	EnableSearching   *bool | ||||||
|  | 	Sniff             *bool | ||||||
|  | 	PostIndexReplicas *int | ||||||
|  | 	PostIndexShards   *int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type DataRetentionSettings struct { | ||||||
|  | 	Enable *bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type JobSettings struct { | ||||||
|  | 	RunJobs      *bool | ||||||
|  | 	RunScheduler *bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type PluginSettings struct { | ||||||
|  | 	Plugins map[string]interface{} | ||||||
|  | } | ||||||
|  |  | ||||||
| type Config struct { | type Config struct { | ||||||
| 	ServiceSettings       ServiceSettings | 	ServiceSettings       ServiceSettings | ||||||
| 	TeamSettings          TeamSettings | 	TeamSettings          TeamSettings | ||||||
| @@ -400,6 +474,7 @@ type Config struct { | |||||||
| 	RateLimitSettings     RateLimitSettings | 	RateLimitSettings     RateLimitSettings | ||||||
| 	PrivacySettings       PrivacySettings | 	PrivacySettings       PrivacySettings | ||||||
| 	SupportSettings       SupportSettings | 	SupportSettings       SupportSettings | ||||||
|  | 	AnnouncementSettings  AnnouncementSettings | ||||||
| 	GitLabSettings        SSOSettings | 	GitLabSettings        SSOSettings | ||||||
| 	GoogleSettings        SSOSettings | 	GoogleSettings        SSOSettings | ||||||
| 	Office365Settings     SSOSettings | 	Office365Settings     SSOSettings | ||||||
| @@ -412,6 +487,10 @@ type Config struct { | |||||||
| 	MetricsSettings       MetricsSettings | 	MetricsSettings       MetricsSettings | ||||||
| 	AnalyticsSettings     AnalyticsSettings | 	AnalyticsSettings     AnalyticsSettings | ||||||
| 	WebrtcSettings        WebrtcSettings | 	WebrtcSettings        WebrtcSettings | ||||||
|  | 	ElasticsearchSettings ElasticsearchSettings | ||||||
|  | 	DataRetentionSettings DataRetentionSettings | ||||||
|  | 	JobSettings           JobSettings | ||||||
|  | 	PluginSettings        PluginSettings | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *Config) ToJson() string { | func (o *Config) ToJson() string { | ||||||
| @@ -453,27 +532,52 @@ func (o *Config) SetDefaults() { | |||||||
| 		o.SqlSettings.AtRestEncryptKey = NewRandomString(32) | 		o.SqlSettings.AtRestEncryptKey = NewRandomString(32) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.SqlSettings.QueryTimeout == nil { | ||||||
|  | 		o.SqlSettings.QueryTimeout = new(int) | ||||||
|  | 		*o.SqlSettings.QueryTimeout = 30 | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.FileSettings.AmazonS3Endpoint == "" { | 	if o.FileSettings.AmazonS3Endpoint == "" { | ||||||
| 		// Defaults to "s3.amazonaws.com" | 		// Defaults to "s3.amazonaws.com" | ||||||
| 		o.FileSettings.AmazonS3Endpoint = "s3.amazonaws.com" | 		o.FileSettings.AmazonS3Endpoint = "s3.amazonaws.com" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.FileSettings.AmazonS3Region == "" { |  | ||||||
| 		// Defaults to "us-east-1" region. |  | ||||||
| 		o.FileSettings.AmazonS3Region = "us-east-1" |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.AmazonS3SSL == nil { | 	if o.FileSettings.AmazonS3SSL == nil { | ||||||
| 		o.FileSettings.AmazonS3SSL = new(bool) | 		o.FileSettings.AmazonS3SSL = new(bool) | ||||||
| 		*o.FileSettings.AmazonS3SSL = true // Secure by default. | 		*o.FileSettings.AmazonS3SSL = true // Secure by default. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.FileSettings.AmazonS3SignV2 == nil { | ||||||
|  | 		o.FileSettings.AmazonS3SignV2 = new(bool) | ||||||
|  | 		// Signature v2 is not enabled by default. | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.FileSettings.AmazonS3SSE == nil { | ||||||
|  | 		o.FileSettings.AmazonS3SSE = new(bool) | ||||||
|  | 		*o.FileSettings.AmazonS3SSE = false // Not Encrypted by default. | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.FileSettings.EnableFileAttachments == nil { | ||||||
|  | 		o.FileSettings.EnableFileAttachments = new(bool) | ||||||
|  | 		*o.FileSettings.EnableFileAttachments = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.FileSettings.EnableMobileUpload == nil { | ||||||
|  | 		o.FileSettings.EnableMobileUpload = new(bool) | ||||||
|  | 		*o.FileSettings.EnableMobileUpload = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.FileSettings.EnableMobileDownload == nil { | ||||||
|  | 		o.FileSettings.EnableMobileDownload = new(bool) | ||||||
|  | 		*o.FileSettings.EnableMobileDownload = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.FileSettings.MaxFileSize == nil { | 	if o.FileSettings.MaxFileSize == nil { | ||||||
| 		o.FileSettings.MaxFileSize = new(int64) | 		o.FileSettings.MaxFileSize = new(int64) | ||||||
| 		*o.FileSettings.MaxFileSize = 52428800 // 50 MB | 		*o.FileSettings.MaxFileSize = 52428800 // 50 MB | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(*o.FileSettings.PublicLinkSalt) == 0 { | 	if o.FileSettings.PublicLinkSalt == nil || len(*o.FileSettings.PublicLinkSalt) == 0 { | ||||||
| 		o.FileSettings.PublicLinkSalt = new(string) | 		o.FileSettings.PublicLinkSalt = new(string) | ||||||
| 		*o.FileSettings.PublicLinkSalt = NewRandomString(32) | 		*o.FileSettings.PublicLinkSalt = NewRandomString(32) | ||||||
| 	} | 	} | ||||||
| @@ -483,12 +587,12 @@ func (o *Config) SetDefaults() { | |||||||
| 		o.FileSettings.InitialFont = "luximbi.ttf" | 		o.FileSettings.InitialFont = "luximbi.ttf" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.EmailSettings.InviteSalt) == 0 { | 	if o.FileSettings.Directory == "" { | ||||||
| 		o.EmailSettings.InviteSalt = NewRandomString(32) | 		o.FileSettings.Directory = "./data/" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.EmailSettings.PasswordResetSalt) == 0 { | 	if len(o.EmailSettings.InviteSalt) == 0 { | ||||||
| 		o.EmailSettings.PasswordResetSalt = NewRandomString(32) | 		o.EmailSettings.InviteSalt = NewRandomString(32) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.ServiceSettings.SiteURL == nil { | 	if o.ServiceSettings.SiteURL == nil { | ||||||
| @@ -496,6 +600,15 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.ServiceSettings.SiteURL = SERVICE_SETTINGS_DEFAULT_SITE_URL | 		*o.ServiceSettings.SiteURL = SERVICE_SETTINGS_DEFAULT_SITE_URL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.LicenseFileLocation == nil { | ||||||
|  | 		o.ServiceSettings.LicenseFileLocation = new(string) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnableAPIv3 == nil { | ||||||
|  | 		o.ServiceSettings.EnableAPIv3 = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnableAPIv3 = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.ServiceSettings.EnableLinkPreviews == nil { | 	if o.ServiceSettings.EnableLinkPreviews == nil { | ||||||
| 		o.ServiceSettings.EnableLinkPreviews = new(bool) | 		o.ServiceSettings.EnableLinkPreviews = new(bool) | ||||||
| 		*o.ServiceSettings.EnableLinkPreviews = false | 		*o.ServiceSettings.EnableLinkPreviews = false | ||||||
| @@ -526,6 +639,11 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.ServiceSettings.EnforceMultifactorAuthentication = false | 		*o.ServiceSettings.EnforceMultifactorAuthentication = false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnableUserAccessTokens == nil { | ||||||
|  | 		o.ServiceSettings.EnableUserAccessTokens = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnableUserAccessTokens = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.PasswordSettings.MinimumLength == nil { | 	if o.PasswordSettings.MinimumLength == nil { | ||||||
| 		o.PasswordSettings.MinimumLength = new(int) | 		o.PasswordSettings.MinimumLength = new(int) | ||||||
| 		*o.PasswordSettings.MinimumLength = PASSWORD_MINIMUM_LENGTH | 		*o.PasswordSettings.MinimumLength = PASSWORD_MINIMUM_LENGTH | ||||||
| @@ -594,14 +712,22 @@ func (o *Config) SetDefaults() { | |||||||
| 	if o.TeamSettings.RestrictPublicChannelCreation == nil { | 	if o.TeamSettings.RestrictPublicChannelCreation == nil { | ||||||
| 		o.TeamSettings.RestrictPublicChannelCreation = new(string) | 		o.TeamSettings.RestrictPublicChannelCreation = new(string) | ||||||
| 		// If this setting does not exist, assume migration from <3.6, so use management setting as default. | 		// If this setting does not exist, assume migration from <3.6, so use management setting as default. | ||||||
|  | 		if *o.TeamSettings.RestrictPublicChannelManagement == PERMISSIONS_CHANNEL_ADMIN { | ||||||
|  | 			*o.TeamSettings.RestrictPublicChannelCreation = PERMISSIONS_TEAM_ADMIN | ||||||
|  | 		} else { | ||||||
| 			*o.TeamSettings.RestrictPublicChannelCreation = *o.TeamSettings.RestrictPublicChannelManagement | 			*o.TeamSettings.RestrictPublicChannelCreation = *o.TeamSettings.RestrictPublicChannelManagement | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.TeamSettings.RestrictPrivateChannelCreation == nil { | 	if o.TeamSettings.RestrictPrivateChannelCreation == nil { | ||||||
| 		o.TeamSettings.RestrictPrivateChannelCreation = new(string) | 		o.TeamSettings.RestrictPrivateChannelCreation = new(string) | ||||||
| 		// If this setting does not exist, assume migration from <3.6, so use management setting as default. | 		// If this setting does not exist, assume migration from <3.6, so use management setting as default. | ||||||
|  | 		if *o.TeamSettings.RestrictPrivateChannelManagement == PERMISSIONS_CHANNEL_ADMIN { | ||||||
|  | 			*o.TeamSettings.RestrictPrivateChannelCreation = PERMISSIONS_TEAM_ADMIN | ||||||
|  | 		} else { | ||||||
| 			*o.TeamSettings.RestrictPrivateChannelCreation = *o.TeamSettings.RestrictPrivateChannelManagement | 			*o.TeamSettings.RestrictPrivateChannelCreation = *o.TeamSettings.RestrictPrivateChannelManagement | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.TeamSettings.RestrictPublicChannelDeletion == nil { | 	if o.TeamSettings.RestrictPublicChannelDeletion == nil { | ||||||
| 		o.TeamSettings.RestrictPublicChannelDeletion = new(string) | 		o.TeamSettings.RestrictPublicChannelDeletion = new(string) | ||||||
| @@ -615,6 +741,11 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.TeamSettings.RestrictPrivateChannelDeletion = *o.TeamSettings.RestrictPrivateChannelManagement | 		*o.TeamSettings.RestrictPrivateChannelDeletion = *o.TeamSettings.RestrictPrivateChannelManagement | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.TeamSettings.RestrictPrivateChannelManageMembers == nil { | ||||||
|  | 		o.TeamSettings.RestrictPrivateChannelManageMembers = new(string) | ||||||
|  | 		*o.TeamSettings.RestrictPrivateChannelManageMembers = PERMISSIONS_ALL | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.TeamSettings.UserStatusAwayTimeout == nil { | 	if o.TeamSettings.UserStatusAwayTimeout == nil { | ||||||
| 		o.TeamSettings.UserStatusAwayTimeout = new(int64) | 		o.TeamSettings.UserStatusAwayTimeout = new(int64) | ||||||
| 		*o.TeamSettings.UserStatusAwayTimeout = TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT | 		*o.TeamSettings.UserStatusAwayTimeout = TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT | ||||||
| @@ -680,8 +811,31 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.EmailSettings.EmailBatchingInterval = EMAIL_BATCHING_INTERVAL | 		*o.EmailSettings.EmailBatchingInterval = EMAIL_BATCHING_INTERVAL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.EmailSettings.EnableSMTPAuth == nil { | ||||||
|  | 		o.EmailSettings.EnableSMTPAuth = new(bool) | ||||||
|  | 		if o.EmailSettings.ConnectionSecurity == CONN_SECURITY_NONE { | ||||||
|  | 			*o.EmailSettings.EnableSMTPAuth = false | ||||||
|  | 		} else { | ||||||
|  | 			*o.EmailSettings.EnableSMTPAuth = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.EmailSettings.ConnectionSecurity == CONN_SECURITY_PLAIN { | ||||||
|  | 		o.EmailSettings.ConnectionSecurity = CONN_SECURITY_NONE | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.EmailSettings.SkipServerCertificateVerification == nil { | ||||||
|  | 		o.EmailSettings.SkipServerCertificateVerification = new(bool) | ||||||
|  | 		*o.EmailSettings.SkipServerCertificateVerification = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.EmailSettings.EmailNotificationContentsType == nil { | ||||||
|  | 		o.EmailSettings.EmailNotificationContentsType = new(string) | ||||||
|  | 		*o.EmailSettings.EmailNotificationContentsType = EMAIL_NOTIFICATION_CONTENTS_FULL | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if !IsSafeLink(o.SupportSettings.TermsOfServiceLink) { | 	if !IsSafeLink(o.SupportSettings.TermsOfServiceLink) { | ||||||
| 		o.SupportSettings.TermsOfServiceLink = nil | 		*o.SupportSettings.TermsOfServiceLink = SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.TermsOfServiceLink == nil { | 	if o.SupportSettings.TermsOfServiceLink == nil { | ||||||
| @@ -690,7 +844,7 @@ func (o *Config) SetDefaults() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !IsSafeLink(o.SupportSettings.PrivacyPolicyLink) { | 	if !IsSafeLink(o.SupportSettings.PrivacyPolicyLink) { | ||||||
| 		o.SupportSettings.PrivacyPolicyLink = nil | 		*o.SupportSettings.PrivacyPolicyLink = "" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.PrivacyPolicyLink == nil { | 	if o.SupportSettings.PrivacyPolicyLink == nil { | ||||||
| @@ -699,7 +853,7 @@ func (o *Config) SetDefaults() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !IsSafeLink(o.SupportSettings.AboutLink) { | 	if !IsSafeLink(o.SupportSettings.AboutLink) { | ||||||
| 		o.SupportSettings.AboutLink = nil | 		*o.SupportSettings.AboutLink = "" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.AboutLink == nil { | 	if o.SupportSettings.AboutLink == nil { | ||||||
| @@ -708,7 +862,7 @@ func (o *Config) SetDefaults() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !IsSafeLink(o.SupportSettings.HelpLink) { | 	if !IsSafeLink(o.SupportSettings.HelpLink) { | ||||||
| 		o.SupportSettings.HelpLink = nil | 		*o.SupportSettings.HelpLink = "" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.HelpLink == nil { | 	if o.SupportSettings.HelpLink == nil { | ||||||
| @@ -717,7 +871,7 @@ func (o *Config) SetDefaults() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !IsSafeLink(o.SupportSettings.ReportAProblemLink) { | 	if !IsSafeLink(o.SupportSettings.ReportAProblemLink) { | ||||||
| 		o.SupportSettings.ReportAProblemLink = nil | 		*o.SupportSettings.ReportAProblemLink = "" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.ReportAProblemLink == nil { | 	if o.SupportSettings.ReportAProblemLink == nil { | ||||||
| @@ -725,11 +879,63 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.SupportSettings.ReportAProblemLink = SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK | 		*o.SupportSettings.ReportAProblemLink = SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !IsSafeLink(o.SupportSettings.AdministratorsGuideLink) { | ||||||
|  | 		*o.SupportSettings.AdministratorsGuideLink = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.SupportSettings.AdministratorsGuideLink == nil { | ||||||
|  | 		o.SupportSettings.AdministratorsGuideLink = new(string) | ||||||
|  | 		*o.SupportSettings.AdministratorsGuideLink = SUPPORT_SETTINGS_DEFAULT_ADMINISTRATORS_GUIDE_LINK | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !IsSafeLink(o.SupportSettings.TroubleshootingForumLink) { | ||||||
|  | 		*o.SupportSettings.TroubleshootingForumLink = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.SupportSettings.TroubleshootingForumLink == nil { | ||||||
|  | 		o.SupportSettings.TroubleshootingForumLink = new(string) | ||||||
|  | 		*o.SupportSettings.TroubleshootingForumLink = SUPPORT_SETTINGS_DEFAULT_TROUBLESHOOTING_FORUM_LINK | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !IsSafeLink(o.SupportSettings.CommercialSupportLink) { | ||||||
|  | 		*o.SupportSettings.CommercialSupportLink = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.SupportSettings.CommercialSupportLink == nil { | ||||||
|  | 		o.SupportSettings.CommercialSupportLink = new(string) | ||||||
|  | 		*o.SupportSettings.CommercialSupportLink = SUPPORT_SETTINGS_DEFAULT_COMMERCIAL_SUPPORT_LINK | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.SupportSettings.SupportEmail == nil { | 	if o.SupportSettings.SupportEmail == nil { | ||||||
| 		o.SupportSettings.SupportEmail = new(string) | 		o.SupportSettings.SupportEmail = new(string) | ||||||
| 		*o.SupportSettings.SupportEmail = SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL | 		*o.SupportSettings.SupportEmail = SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.AnnouncementSettings.EnableBanner == nil { | ||||||
|  | 		o.AnnouncementSettings.EnableBanner = new(bool) | ||||||
|  | 		*o.AnnouncementSettings.EnableBanner = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.AnnouncementSettings.BannerText == nil { | ||||||
|  | 		o.AnnouncementSettings.BannerText = new(string) | ||||||
|  | 		*o.AnnouncementSettings.BannerText = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.AnnouncementSettings.BannerColor == nil { | ||||||
|  | 		o.AnnouncementSettings.BannerColor = new(string) | ||||||
|  | 		*o.AnnouncementSettings.BannerColor = ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.AnnouncementSettings.BannerTextColor == nil { | ||||||
|  | 		o.AnnouncementSettings.BannerTextColor = new(string) | ||||||
|  | 		*o.AnnouncementSettings.BannerTextColor = ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.AnnouncementSettings.AllowBannerDismissal == nil { | ||||||
|  | 		o.AnnouncementSettings.AllowBannerDismissal = new(bool) | ||||||
|  | 		*o.AnnouncementSettings.AllowBannerDismissal = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.LdapSettings.Enable == nil { | 	if o.LdapSettings.Enable == nil { | ||||||
| 		o.LdapSettings.Enable = new(bool) | 		o.LdapSettings.Enable = new(bool) | ||||||
| 		*o.LdapSettings.Enable = false | 		*o.LdapSettings.Enable = false | ||||||
| @@ -884,7 +1090,12 @@ func (o *Config) SetDefaults() { | |||||||
|  |  | ||||||
| 	if o.ServiceSettings.EnableCustomEmoji == nil { | 	if o.ServiceSettings.EnableCustomEmoji == nil { | ||||||
| 		o.ServiceSettings.EnableCustomEmoji = new(bool) | 		o.ServiceSettings.EnableCustomEmoji = new(bool) | ||||||
| 		*o.ServiceSettings.EnableCustomEmoji = true | 		*o.ServiceSettings.EnableCustomEmoji = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnableEmojiPicker == nil { | ||||||
|  | 		o.ServiceSettings.EnableEmojiPicker = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnableEmojiPicker = true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.ServiceSettings.RestrictCustomEmojiCreation == nil { | 	if o.ServiceSettings.RestrictCustomEmojiCreation == nil { | ||||||
| @@ -907,18 +1118,44 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.ServiceSettings.PostEditTimeLimit = 300 | 		*o.ServiceSettings.PostEditTimeLimit = 300 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.ClusterSettings.InterNodeListenAddress == nil { |  | ||||||
| 		o.ClusterSettings.InterNodeListenAddress = new(string) |  | ||||||
| 		*o.ClusterSettings.InterNodeListenAddress = ":8075" |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.ClusterSettings.Enable == nil { | 	if o.ClusterSettings.Enable == nil { | ||||||
| 		o.ClusterSettings.Enable = new(bool) | 		o.ClusterSettings.Enable = new(bool) | ||||||
| 		*o.ClusterSettings.Enable = false | 		*o.ClusterSettings.Enable = false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.ClusterSettings.InterNodeUrls == nil { | 	if o.ClusterSettings.ClusterName == nil { | ||||||
| 		o.ClusterSettings.InterNodeUrls = []string{} | 		o.ClusterSettings.ClusterName = new(string) | ||||||
|  | 		*o.ClusterSettings.ClusterName = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.OverrideHostname == nil { | ||||||
|  | 		o.ClusterSettings.OverrideHostname = new(string) | ||||||
|  | 		*o.ClusterSettings.OverrideHostname = "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.UseIpAddress == nil { | ||||||
|  | 		o.ClusterSettings.UseIpAddress = new(bool) | ||||||
|  | 		*o.ClusterSettings.UseIpAddress = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.UseExperimentalGossip == nil { | ||||||
|  | 		o.ClusterSettings.UseExperimentalGossip = new(bool) | ||||||
|  | 		*o.ClusterSettings.UseExperimentalGossip = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.ReadOnlyConfig == nil { | ||||||
|  | 		o.ClusterSettings.ReadOnlyConfig = new(bool) | ||||||
|  | 		*o.ClusterSettings.ReadOnlyConfig = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.GossipPort == nil { | ||||||
|  | 		o.ClusterSettings.GossipPort = new(int) | ||||||
|  | 		*o.ClusterSettings.GossipPort = 8074 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ClusterSettings.StreamingPort == nil { | ||||||
|  | 		o.ClusterSettings.StreamingPort = new(int) | ||||||
|  | 		*o.ClusterSettings.StreamingPort = 8075 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.MetricsSettings.ListenAddress == nil { | 	if o.MetricsSettings.ListenAddress == nil { | ||||||
| @@ -978,12 +1215,12 @@ func (o *Config) SetDefaults() { | |||||||
|  |  | ||||||
| 	if o.SamlSettings.Verify == nil { | 	if o.SamlSettings.Verify == nil { | ||||||
| 		o.SamlSettings.Verify = new(bool) | 		o.SamlSettings.Verify = new(bool) | ||||||
| 		*o.SamlSettings.Verify = false | 		*o.SamlSettings.Verify = true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SamlSettings.Encrypt == nil { | 	if o.SamlSettings.Encrypt == nil { | ||||||
| 		o.SamlSettings.Encrypt = new(bool) | 		o.SamlSettings.Encrypt = new(bool) | ||||||
| 		*o.SamlSettings.Encrypt = false | 		*o.SamlSettings.Encrypt = true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.SamlSettings.IdpUrl == nil { | 	if o.SamlSettings.IdpUrl == nil { | ||||||
| @@ -1056,6 +1293,15 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.SamlSettings.LocaleAttribute = SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE | 		*o.SamlSettings.LocaleAttribute = SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.TeamSettings.TeammateNameDisplay == nil { | ||||||
|  | 		o.TeamSettings.TeammateNameDisplay = new(string) | ||||||
|  | 		*o.TeamSettings.TeammateNameDisplay = SHOW_USERNAME | ||||||
|  |  | ||||||
|  | 		if *o.SamlSettings.Enable || *o.LdapSettings.Enable { | ||||||
|  | 			*o.TeamSettings.TeammateNameDisplay = SHOW_FULLNAME | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.NativeAppSettings.AppDownloadLink == nil { | 	if o.NativeAppSettings.AppDownloadLink == nil { | ||||||
| 		o.NativeAppSettings.AppDownloadLink = new(string) | 		o.NativeAppSettings.AppDownloadLink = new(string) | ||||||
| 		*o.NativeAppSettings.AppDownloadLink = NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK | 		*o.NativeAppSettings.AppDownloadLink = NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK | ||||||
| @@ -1076,6 +1322,11 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.RateLimitSettings.Enable = false | 		*o.RateLimitSettings.Enable = false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.GoroutineHealthThreshold == nil { | ||||||
|  | 		o.ServiceSettings.GoroutineHealthThreshold = new(int) | ||||||
|  | 		*o.ServiceSettings.GoroutineHealthThreshold = -1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.RateLimitSettings.MaxBurst == nil { | 	if o.RateLimitSettings.MaxBurst == nil { | ||||||
| 		o.RateLimitSettings.MaxBurst = new(int) | 		o.RateLimitSettings.MaxBurst = new(int) | ||||||
| 		*o.RateLimitSettings.MaxBurst = 100 | 		*o.RateLimitSettings.MaxBurst = 100 | ||||||
| @@ -1131,16 +1382,90 @@ func (o *Config) SetDefaults() { | |||||||
| 		*o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = 5000 | 		*o.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds = 5000 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnablePostSearch == nil { | ||||||
|  | 		o.ServiceSettings.EnablePostSearch = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnablePostSearch = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.ServiceSettings.EnableUserTypingMessages == nil { | 	if o.ServiceSettings.EnableUserTypingMessages == nil { | ||||||
| 		o.ServiceSettings.EnableUserTypingMessages = new(bool) | 		o.ServiceSettings.EnableUserTypingMessages = new(bool) | ||||||
| 		*o.ServiceSettings.EnableUserTypingMessages = true | 		*o.ServiceSettings.EnableUserTypingMessages = true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnableChannelViewedMessages == nil { | ||||||
|  | 		o.ServiceSettings.EnableChannelViewedMessages = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnableChannelViewedMessages = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ServiceSettings.EnableUserStatuses == nil { | ||||||
|  | 		o.ServiceSettings.EnableUserStatuses = new(bool) | ||||||
|  | 		*o.ServiceSettings.EnableUserStatuses = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.ServiceSettings.ClusterLogTimeoutMilliseconds == nil { | 	if o.ServiceSettings.ClusterLogTimeoutMilliseconds == nil { | ||||||
| 		o.ServiceSettings.ClusterLogTimeoutMilliseconds = new(int) | 		o.ServiceSettings.ClusterLogTimeoutMilliseconds = new(int) | ||||||
| 		*o.ServiceSettings.ClusterLogTimeoutMilliseconds = 2000 | 		*o.ServiceSettings.ClusterLogTimeoutMilliseconds = 2000 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.ConnectionUrl == nil { | ||||||
|  | 		o.ElasticsearchSettings.ConnectionUrl = new(string) | ||||||
|  | 		*o.ElasticsearchSettings.ConnectionUrl = ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.Username == nil { | ||||||
|  | 		o.ElasticsearchSettings.Username = new(string) | ||||||
|  | 		*o.ElasticsearchSettings.Username = ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.Password == nil { | ||||||
|  | 		o.ElasticsearchSettings.Password = new(string) | ||||||
|  | 		*o.ElasticsearchSettings.Password = ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.EnableIndexing == nil { | ||||||
|  | 		o.ElasticsearchSettings.EnableIndexing = new(bool) | ||||||
|  | 		*o.ElasticsearchSettings.EnableIndexing = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.EnableSearching == nil { | ||||||
|  | 		o.ElasticsearchSettings.EnableSearching = new(bool) | ||||||
|  | 		*o.ElasticsearchSettings.EnableSearching = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.Sniff == nil { | ||||||
|  | 		o.ElasticsearchSettings.Sniff = new(bool) | ||||||
|  | 		*o.ElasticsearchSettings.Sniff = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.PostIndexReplicas == nil { | ||||||
|  | 		o.ElasticsearchSettings.PostIndexReplicas = new(int) | ||||||
|  | 		*o.ElasticsearchSettings.PostIndexReplicas = ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_REPLICAS | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.ElasticsearchSettings.PostIndexShards == nil { | ||||||
|  | 		o.ElasticsearchSettings.PostIndexShards = new(int) | ||||||
|  | 		*o.ElasticsearchSettings.PostIndexShards = ELASTICSEARCH_SETTINGS_DEFAULT_POST_INDEX_SHARDS | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.DataRetentionSettings.Enable == nil { | ||||||
|  | 		o.DataRetentionSettings.Enable = new(bool) | ||||||
|  | 		*o.DataRetentionSettings.Enable = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.JobSettings.RunJobs == nil { | ||||||
|  | 		o.JobSettings.RunJobs = new(bool) | ||||||
|  | 		*o.JobSettings.RunJobs = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.JobSettings.RunScheduler == nil { | ||||||
|  | 		o.JobSettings.RunScheduler = new(bool) | ||||||
|  | 		*o.JobSettings.RunScheduler = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if o.PluginSettings.Plugins == nil { | ||||||
|  | 		o.PluginSettings.Plugins = make(map[string]interface{}) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	o.defaultWebrtcSettings() | 	o.defaultWebrtcSettings() | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1184,6 +1509,10 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.restrict_direct_message.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !(*o.TeamSettings.TeammateNameDisplay == SHOW_FULLNAME || *o.TeamSettings.TeammateNameDisplay == SHOW_NICKNAME_FULLNAME || *o.TeamSettings.TeammateNameDisplay == SHOW_USERNAME) { | ||||||
|  | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.teammate_name_display.app_error", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if len(o.SqlSettings.AtRestEncryptKey) < 32 { | 	if len(o.SqlSettings.AtRestEncryptKey) < 32 { | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.encrypt_sql.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
| @@ -1196,6 +1525,10 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.sql_idle.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.sql_idle.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if *o.SqlSettings.QueryTimeout <= 0 { | ||||||
|  | 		return NewAppError("Config.IsValid", "model.config.is_valid.sql_query_timeout.app_error", nil, "", http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if len(o.SqlSettings.DataSource) == 0 { | 	if len(o.SqlSettings.DataSource) == 0 { | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.sql_data_src.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.sql_data_src.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
| @@ -1212,30 +1545,6 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_driver.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_driver.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.FileSettings.PreviewHeight < 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_preview_height.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.PreviewWidth <= 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_preview_width.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.ProfileHeight <= 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_profile_height.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.ProfileWidth <= 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_profile_width.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.ThumbnailHeight <= 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_thumb_height.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if o.FileSettings.ThumbnailWidth <= 0 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_thumb_width.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(*o.FileSettings.PublicLinkSalt) < 32 { | 	if len(*o.FileSettings.PublicLinkSalt) < 32 { | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_salt.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.file_salt.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
| @@ -1248,10 +1557,6 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_salt.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_salt.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.EmailSettings.PasswordResetSalt) < 32 { |  | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_reset_salt.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if *o.EmailSettings.EmailBatchingBufferSize <= 0 { | 	if *o.EmailSettings.EmailBatchingBufferSize <= 0 { | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_buffer_size.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_buffer_size.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
| @@ -1260,6 +1565,10 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_interval.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_batching_interval.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if !(*o.EmailSettings.EmailNotificationContentsType == EMAIL_NOTIFICATION_CONTENTS_FULL || *o.EmailSettings.EmailNotificationContentsType == EMAIL_NOTIFICATION_CONTENTS_GENERIC) { | ||||||
|  | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.email_notification_contents_type.app_error", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if o.RateLimitSettings.MemoryStoreSize <= 0 { | 	if o.RateLimitSettings.MemoryStoreSize <= 0 { | ||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.rate_mem.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.rate_mem.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
| @@ -1376,6 +1685,16 @@ func (o *Config) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Config.IsValid", "model.config.is_valid.time_between_user_typing.app_error", nil, "") | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.time_between_user_typing.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if *o.ElasticsearchSettings.EnableIndexing { | ||||||
|  | 		if len(*o.ElasticsearchSettings.ConnectionUrl) == 0 { | ||||||
|  | 			return NewLocAppError("Config.IsValid", "model.config.is_valid.elastic_search.connection_url.app_error", nil, "") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if *o.ElasticsearchSettings.EnableSearching && !*o.ElasticsearchSettings.EnableIndexing { | ||||||
|  | 		return NewLocAppError("Config.IsValid", "model.config.is_valid.elastic_search.enable_searching.app_error", nil, "") | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1398,7 +1717,6 @@ func (o *Config) Sanitize() { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	o.EmailSettings.InviteSalt = FAKE_SETTING | 	o.EmailSettings.InviteSalt = FAKE_SETTING | ||||||
| 	o.EmailSettings.PasswordResetSalt = FAKE_SETTING |  | ||||||
| 	if len(o.EmailSettings.SMTPPassword) > 0 { | 	if len(o.EmailSettings.SMTPPassword) > 0 { | ||||||
| 		o.EmailSettings.SMTPPassword = FAKE_SETTING | 		o.EmailSettings.SMTPPassword = FAKE_SETTING | ||||||
| 	} | 	} | ||||||
| @@ -1413,6 +1731,12 @@ func (o *Config) Sanitize() { | |||||||
| 	for i := range o.SqlSettings.DataSourceReplicas { | 	for i := range o.SqlSettings.DataSourceReplicas { | ||||||
| 		o.SqlSettings.DataSourceReplicas[i] = FAKE_SETTING | 		o.SqlSettings.DataSourceReplicas[i] = FAKE_SETTING | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	for i := range o.SqlSettings.DataSourceSearchReplicas { | ||||||
|  | 		o.SqlSettings.DataSourceSearchReplicas[i] = FAKE_SETTING | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	*o.ElasticsearchSettings.Password = FAKE_SETTING | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *Config) defaultWebrtcSettings() { | func (o *Config) defaultWebrtcSettings() { | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								vendor/github.com/mattermost/platform/model/emoji.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/mattermost/platform/model/emoji.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -34,7 +34,7 @@ func (emoji *Emoji) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Emoji.IsValid", "model.emoji.user_id.app_error", nil, "") | 		return NewLocAppError("Emoji.IsValid", "model.emoji.user_id.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(emoji.Name) == 0 || len(emoji.Name) > 64 { | 	if len(emoji.Name) == 0 || len(emoji.Name) > 64 || !IsValidAlphaNumHyphenUnderscore(emoji.Name, false) { | ||||||
| 		return NewLocAppError("Emoji.IsValid", "model.emoji.name.app_error", nil, "") | 		return NewLocAppError("Emoji.IsValid", "model.emoji.name.app_error", nil, "") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/file.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/file_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/file_info.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/gitlab/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/gitlab/gitlab.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package oauthgitlab | package oauthgitlab | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								vendor/github.com/mattermost/platform/model/incoming_webhook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										58
									
								
								vendor/github.com/mattermost/platform/model/incoming_webhook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,10 +6,9 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" |  | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| @@ -81,35 +80,36 @@ func IncomingWebhookListFromJson(data io.Reader) []*IncomingWebhook { | |||||||
| func (o *IncomingWebhook) IsValid() *AppError { | func (o *IncomingWebhook) IsValid() *AppError { | ||||||
|  |  | ||||||
| 	if len(o.Id) != 26 { | 	if len(o.Id) != 26 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.id.app_error", nil, "", http.StatusBadRequest) | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.CreateAt == 0 { | 	if o.CreateAt == 0 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.create_at.app_error", nil, "id="+o.Id) | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.UpdateAt == 0 { | 	if o.UpdateAt == 0 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id) | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.UserId) != 26 { | 	if len(o.UserId) != 26 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.user_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.ChannelId) != 26 { | 	if len(o.ChannelId) != 26 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.channel_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.TeamId) != 26 { | 	if len(o.TeamId) != 26 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.team_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.DisplayName) > 64 { | 	if len(o.DisplayName) > 64 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.display_name.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.Description) > 128 { | 	if len(o.Description) > 128 { | ||||||
| 		return NewLocAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "") | 		return NewAppError("IncomingWebhook.IsValid", "model.incoming_hook.description.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| @@ -193,39 +193,6 @@ func decodeIncomingWebhookRequest(by []byte) (*IncomingWebhookRequest, error) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // To mention @channel via a webhook in Slack, the message should contain |  | ||||||
| // <!channel>, as explained at the bottom of this article: |  | ||||||
| // https://get.slack.help/hc/en-us/articles/202009646-Making-announcements |  | ||||||
| func expandAnnouncement(text string) string { |  | ||||||
| 	c1 := "<!channel>" |  | ||||||
| 	c2 := "@channel" |  | ||||||
| 	if strings.Contains(text, c1) { |  | ||||||
| 		return strings.Replace(text, c1, c2, -1) |  | ||||||
| 	} |  | ||||||
| 	return text |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Expand announcements in incoming webhooks from Slack. Those announcements |  | ||||||
| // can be found in the text attribute, or in the pretext, text, title and value |  | ||||||
| // attributes of the attachment structure. The Slack attachment structure is |  | ||||||
| // documented here: https://api.slack.com/docs/attachments |  | ||||||
| func expandAnnouncements(i *IncomingWebhookRequest) { |  | ||||||
| 	i.Text = expandAnnouncement(i.Text) |  | ||||||
|  |  | ||||||
| 	for _, attachment := range i.Attachments { |  | ||||||
| 		attachment.Pretext = expandAnnouncement(attachment.Pretext) |  | ||||||
| 		attachment.Text = expandAnnouncement(attachment.Text) |  | ||||||
| 		attachment.Title = expandAnnouncement(attachment.Title) |  | ||||||
|  |  | ||||||
| 		for _, field := range attachment.Fields { |  | ||||||
| 			if field.Value != nil { |  | ||||||
| 				// Ensure the value is set to a string if it is set |  | ||||||
| 				field.Value = expandAnnouncement(fmt.Sprintf("%v", field.Value)) |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func IncomingWebhookRequestFromJson(data io.Reader) *IncomingWebhookRequest { | func IncomingWebhookRequestFromJson(data io.Reader) *IncomingWebhookRequest { | ||||||
| 	buf := new(bytes.Buffer) | 	buf := new(bytes.Buffer) | ||||||
| 	buf.ReadFrom(data) | 	buf.ReadFrom(data) | ||||||
| @@ -241,7 +208,8 @@ func IncomingWebhookRequestFromJson(data io.Reader) *IncomingWebhookRequest { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	expandAnnouncements(o) | 	o.Text = ExpandAnnouncement(o.Text) | ||||||
|  | 	o.Attachments = ProcessSlackAttachments(o.Attachments) | ||||||
|  |  | ||||||
| 	return o | 	return o | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/initial_load.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/initial_load.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										159
									
								
								vendor/github.com/mattermost/platform/model/job.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										159
									
								
								vendor/github.com/mattermost/platform/model/job.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,100 +1,117 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"encoding/json" | ||||||
| 	"time" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type TaskFunc func() | const ( | ||||||
|  | 	JOB_TYPE_DATA_RETENTION              = "data_retention" | ||||||
|  | 	JOB_TYPE_ELASTICSEARCH_POST_INDEXING = "elasticsearch_post_indexing" | ||||||
|  |  | ||||||
| type ScheduledTask struct { | 	JOB_STATUS_PENDING          = "pending" | ||||||
| 	Name      string        `json:"name"` | 	JOB_STATUS_IN_PROGRESS      = "in_progress" | ||||||
| 	Interval  time.Duration `json:"interval"` | 	JOB_STATUS_SUCCESS          = "success" | ||||||
| 	Recurring bool          `json:"recurring"` | 	JOB_STATUS_ERROR            = "error" | ||||||
| 	function  TaskFunc | 	JOB_STATUS_CANCEL_REQUESTED = "cancel_requested" | ||||||
| 	timer     *time.Timer | 	JOB_STATUS_CANCELED         = "canceled" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type Job struct { | ||||||
|  | 	Id             string                 `json:"id"` | ||||||
|  | 	Type           string                 `json:"type"` | ||||||
|  | 	Priority       int64                  `json:"priority"` | ||||||
|  | 	CreateAt       int64                  `json:"create_at"` | ||||||
|  | 	StartAt        int64                  `json:"start_at"` | ||||||
|  | 	LastActivityAt int64                  `json:"last_activity_at"` | ||||||
|  | 	Status         string                 `json:"status"` | ||||||
|  | 	Progress       int64                  `json:"progress"` | ||||||
|  | 	Data           map[string]interface{} `json:"data"` | ||||||
| } | } | ||||||
|  |  | ||||||
| var tasks = make(map[string]*ScheduledTask) | func (j *Job) IsValid() *AppError { | ||||||
|  | 	if len(j.Id) != 26 { | ||||||
| func addTask(task *ScheduledTask) { | 		return NewAppError("Job.IsValid", "model.job.is_valid.id.app_error", nil, "id="+j.Id, http.StatusBadRequest) | ||||||
| 	tasks[task.Name] = task |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func removeTaskByName(name string) { |  | ||||||
| 	delete(tasks, name) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func GetTaskByName(name string) *ScheduledTask { |  | ||||||
| 	if task, ok := tasks[name]; ok { |  | ||||||
| 		return task |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if j.CreateAt == 0 { | ||||||
|  | 		return NewAppError("Job.IsValid", "model.job.is_valid.create_at.app_error", nil, "id="+j.Id, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch j.Type { | ||||||
|  | 	case JOB_TYPE_DATA_RETENTION: | ||||||
|  | 	case JOB_TYPE_ELASTICSEARCH_POST_INDEXING: | ||||||
|  | 	default: | ||||||
|  | 		return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	switch j.Status { | ||||||
|  | 	case JOB_STATUS_PENDING: | ||||||
|  | 	case JOB_STATUS_IN_PROGRESS: | ||||||
|  | 	case JOB_STATUS_SUCCESS: | ||||||
|  | 	case JOB_STATUS_ERROR: | ||||||
|  | 	case JOB_STATUS_CANCEL_REQUESTED: | ||||||
|  | 	case JOB_STATUS_CANCELED: | ||||||
|  | 	default: | ||||||
|  | 		return NewAppError("Job.IsValid", "model.job.is_valid.status.app_error", nil, "id="+j.Id, http.StatusBadRequest) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func GetAllTasks() *map[string]*ScheduledTask { | func (js *Job) ToJson() string { | ||||||
| 	return &tasks | 	if b, err := json.Marshal(js); err != nil { | ||||||
| } | 		return "" | ||||||
|  | 	} else { | ||||||
| func CreateTask(name string, function TaskFunc, timeToExecution time.Duration) *ScheduledTask { | 		return string(b) | ||||||
| 	task := &ScheduledTask{ |  | ||||||
| 		Name:      name, |  | ||||||
| 		Interval:  timeToExecution, |  | ||||||
| 		Recurring: false, |  | ||||||
| 		function:  function, |  | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| 	taskRunner := func() { | func JobFromJson(data io.Reader) *Job { | ||||||
| 		go task.function() | 	var job Job | ||||||
| 		removeTaskByName(task.Name) | 	if err := json.NewDecoder(data).Decode(&job); err == nil { | ||||||
|  | 		return &job | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	task.timer = time.AfterFunc(timeToExecution, taskRunner) |  | ||||||
|  |  | ||||||
| 	addTask(task) |  | ||||||
|  |  | ||||||
| 	return task |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func CreateRecurringTask(name string, function TaskFunc, interval time.Duration) *ScheduledTask { | func JobsToJson(jobs []*Job) string { | ||||||
| 	task := &ScheduledTask{ | 	if b, err := json.Marshal(jobs); err != nil { | ||||||
| 		Name:      name, | 		return "" | ||||||
| 		Interval:  interval, | 	} else { | ||||||
| 		Recurring: true, | 		return string(b) | ||||||
| 		function:  function, |  | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| 	taskRecurer := func() { | func JobsFromJson(data io.Reader) []*Job { | ||||||
| 		go task.function() | 	var jobs []*Job | ||||||
| 		task.timer.Reset(task.Interval) | 	if err := json.NewDecoder(data).Decode(&jobs); err == nil { | ||||||
|  | 		return jobs | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	task.timer = time.AfterFunc(interval, taskRecurer) |  | ||||||
|  |  | ||||||
| 	addTask(task) |  | ||||||
|  |  | ||||||
| 	return task |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (task *ScheduledTask) Cancel() { | func (js *Job) DataToJson() string { | ||||||
| 	task.timer.Stop() | 	if b, err := json.Marshal(js.Data); err != nil { | ||||||
| 	removeTaskByName(task.Name) | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // Executes the task immediatly. A recurring task will be run regularally after interval. | type Worker interface { | ||||||
| func (task *ScheduledTask) Execute() { | 	Run() | ||||||
| 	task.function() | 	Stop() | ||||||
| 	task.timer.Reset(task.Interval) | 	JobChannel() chan<- Job | ||||||
| } | } | ||||||
|  |  | ||||||
| func (task *ScheduledTask) String() string { | type Scheduler interface { | ||||||
| 	return fmt.Sprintf( | 	Run() | ||||||
| 		"%s\nInterval: %s\nRecurring: %t\n", | 	Stop() | ||||||
| 		task.Name, |  | ||||||
| 		task.Interval.String(), |  | ||||||
| 		task.Recurring, |  | ||||||
| 	) |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/ldap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								vendor/github.com/mattermost/platform/model/license.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/mattermost/platform/model/license.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -49,6 +49,10 @@ type Features struct { | |||||||
| 	MHPNS                     *bool `json:"mhpns"` | 	MHPNS                     *bool `json:"mhpns"` | ||||||
| 	SAML                      *bool `json:"saml"` | 	SAML                      *bool `json:"saml"` | ||||||
| 	PasswordRequirements      *bool `json:"password_requirements"` | 	PasswordRequirements      *bool `json:"password_requirements"` | ||||||
|  | 	Elasticsearch             *bool `json:"elastic_search"` | ||||||
|  | 	Announcement              *bool `json:"announcement"` | ||||||
|  | 	EmailNotificationContents *bool `json:"email_notification_contents"` | ||||||
|  |  | ||||||
| 	// after we enabled more features for webrtc we'll need to control them with this | 	// after we enabled more features for webrtc we'll need to control them with this | ||||||
| 	FutureFeatures *bool `json:"future_features"` | 	FutureFeatures *bool `json:"future_features"` | ||||||
| } | } | ||||||
| @@ -66,6 +70,8 @@ func (f *Features) ToMap() map[string]interface{} { | |||||||
| 		"mhpns":                       *f.MHPNS, | 		"mhpns":                       *f.MHPNS, | ||||||
| 		"saml":                        *f.SAML, | 		"saml":                        *f.SAML, | ||||||
| 		"password":                    *f.PasswordRequirements, | 		"password":                    *f.PasswordRequirements, | ||||||
|  | 		"elastic_search":              *f.Elasticsearch, | ||||||
|  | 		"email_notification_contents": *f.EmailNotificationContents, | ||||||
| 		"future":                      *f.FutureFeatures, | 		"future":                      *f.FutureFeatures, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -135,6 +141,21 @@ func (f *Features) SetDefaults() { | |||||||
| 		f.PasswordRequirements = new(bool) | 		f.PasswordRequirements = new(bool) | ||||||
| 		*f.PasswordRequirements = *f.FutureFeatures | 		*f.PasswordRequirements = *f.FutureFeatures | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if f.Elasticsearch == nil { | ||||||
|  | 		f.Elasticsearch = new(bool) | ||||||
|  | 		*f.Elasticsearch = *f.FutureFeatures | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if f.Announcement == nil { | ||||||
|  | 		f.Announcement = new(bool) | ||||||
|  | 		*f.Announcement = true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if f.EmailNotificationContents == nil { | ||||||
|  | 		f.EmailNotificationContents = new(bool) | ||||||
|  | 		*f.EmailNotificationContents = *f.FutureFeatures | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (l *License) IsExpired() bool { | func (l *License) IsExpired() bool { | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								vendor/github.com/mattermost/platform/model/mfa_secret.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/mattermost/platform/model/mfa_secret.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type MfaSecret struct { | ||||||
|  | 	Secret string `json:"secret"` | ||||||
|  | 	QRCode string `json:"qr_code"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (me *MfaSecret) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(me) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func MfaSecretFromJson(data io.Reader) *MfaSecret { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var me MfaSecret | ||||||
|  | 	err := decoder.Decode(&me) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &me | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										26
									
								
								vendor/github.com/mattermost/platform/model/oauth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/mattermost/platform/model/oauth.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -7,6 +7,7 @@ import ( | |||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| 	"unicode/utf8" | 	"unicode/utf8" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -15,6 +16,7 @@ const ( | |||||||
| 	OAUTH_ACTION_LOGIN        = "login" | 	OAUTH_ACTION_LOGIN        = "login" | ||||||
| 	OAUTH_ACTION_EMAIL_TO_SSO = "email_to_sso" | 	OAUTH_ACTION_EMAIL_TO_SSO = "email_to_sso" | ||||||
| 	OAUTH_ACTION_SSO_TO_EMAIL = "sso_to_email" | 	OAUTH_ACTION_SSO_TO_EMAIL = "sso_to_email" | ||||||
|  | 	OAUTH_ACTION_MOBILE       = "mobile" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type OAuthApp struct { | type OAuthApp struct { | ||||||
| @@ -36,50 +38,50 @@ type OAuthApp struct { | |||||||
| func (a *OAuthApp) IsValid() *AppError { | func (a *OAuthApp) IsValid() *AppError { | ||||||
|  |  | ||||||
| 	if len(a.Id) != 26 { | 	if len(a.Id) != 26 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.app_id.app_error", nil, "") | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.app_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if a.CreateAt == 0 { | 	if a.CreateAt == 0 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.create_at.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.create_at.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if a.UpdateAt == 0 { | 	if a.UpdateAt == 0 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.update_at.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.update_at.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.CreatorId) != 26 { | 	if len(a.CreatorId) != 26 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.creator_id.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.creator_id.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.ClientSecret) == 0 || len(a.ClientSecret) > 128 { | 	if len(a.ClientSecret) == 0 || len(a.ClientSecret) > 128 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.client_secret.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.client_secret.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.Name) == 0 || len(a.Name) > 64 { | 	if len(a.Name) == 0 || len(a.Name) > 64 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.name.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.name.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.CallbackUrls) == 0 || len(fmt.Sprintf("%s", a.CallbackUrls)) > 1024 { | 	if len(a.CallbackUrls) == 0 || len(fmt.Sprintf("%s", a.CallbackUrls)) > 1024 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, callback := range a.CallbackUrls { | 	for _, callback := range a.CallbackUrls { | ||||||
| 		if !IsValidHttpUrl(callback) { | 		if !IsValidHttpUrl(callback) { | ||||||
| 			return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "") | 			return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.callback.app_error", nil, "", http.StatusBadRequest) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.Homepage) == 0 || len(a.Homepage) > 256 || !IsValidHttpUrl(a.Homepage) { | 	if len(a.Homepage) == 0 || len(a.Homepage) > 256 || !IsValidHttpUrl(a.Homepage) { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.homepage.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.homepage.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if utf8.RuneCountInString(a.Description) > 512 { | 	if utf8.RuneCountInString(a.Description) > 512 { | ||||||
| 		return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.description.app_error", nil, "app_id="+a.Id) | 		return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.description.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(a.IconURL) > 0 { | 	if len(a.IconURL) > 0 { | ||||||
| 		if len(a.IconURL) > 512 || !IsValidHttpUrl(a.IconURL) { | 		if len(a.IconURL) > 512 || !IsValidHttpUrl(a.IconURL) { | ||||||
| 			return NewLocAppError("OAuthApp.IsValid", "model.oauth.is_valid.icon_url.app_error", nil, "app_id="+a.Id) | 			return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.icon_url.app_error", nil, "app_id="+a.Id, http.StatusBadRequest) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										65
									
								
								vendor/github.com/mattermost/platform/model/outgoing_webhook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										65
									
								
								vendor/github.com/mattermost/platform/model/outgoing_webhook.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -7,6 +7,7 @@ import ( | |||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| @@ -41,6 +42,7 @@ type OutgoingWebhookPayload struct { | |||||||
| 	PostId      string `json:"post_id"` | 	PostId      string `json:"post_id"` | ||||||
| 	Text        string `json:"text"` | 	Text        string `json:"text"` | ||||||
| 	TriggerWord string `json:"trigger_word"` | 	TriggerWord string `json:"trigger_word"` | ||||||
|  | 	FileIds     string `json:"file_ids"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *OutgoingWebhookPayload) ToJSON() string { | func (o *OutgoingWebhookPayload) ToJSON() string { | ||||||
| @@ -65,6 +67,7 @@ func (o *OutgoingWebhookPayload) ToFormValues() string { | |||||||
| 	v.Set("post_id", o.PostId) | 	v.Set("post_id", o.PostId) | ||||||
| 	v.Set("text", o.Text) | 	v.Set("text", o.Text) | ||||||
| 	v.Set("trigger_word", o.TriggerWord) | 	v.Set("trigger_word", o.TriggerWord) | ||||||
|  | 	v.Set("file_ids", o.FileIds) | ||||||
|  |  | ||||||
| 	return v.Encode() | 	return v.Encode() | ||||||
| } | } | ||||||
| @@ -112,69 +115,69 @@ func OutgoingWebhookListFromJson(data io.Reader) []*OutgoingWebhook { | |||||||
| func (o *OutgoingWebhook) IsValid() *AppError { | func (o *OutgoingWebhook) IsValid() *AppError { | ||||||
|  |  | ||||||
| 	if len(o.Id) != 26 { | 	if len(o.Id) != 26 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.Token) != 26 { | 	if len(o.Token) != 26 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.token.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.token.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.CreateAt == 0 { | 	if o.CreateAt == 0 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.create_at.app_error", nil, "id="+o.Id) | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.create_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.UpdateAt == 0 { | 	if o.UpdateAt == 0 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id) | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.update_at.app_error", nil, "id="+o.Id, http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.CreatorId) != 26 { | 	if len(o.CreatorId) != 26 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.ChannelId) != 0 && len(o.ChannelId) != 26 { | 	if len(o.ChannelId) != 0 && len(o.ChannelId) != 26 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.TeamId) != 26 { | 	if len(o.TeamId) != 26 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.team_id.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(fmt.Sprintf("%s", o.TriggerWords)) > 1024 { | 	if len(fmt.Sprintf("%s", o.TriggerWords)) > 1024 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.words.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.TriggerWords) != 0 { | 	if len(o.TriggerWords) != 0 { | ||||||
| 		for _, triggerWord := range o.TriggerWords { | 		for _, triggerWord := range o.TriggerWords { | ||||||
| 			if len(triggerWord) == 0 { | 			if len(triggerWord) == 0 { | ||||||
| 				return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "") | 				return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "", http.StatusBadRequest) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { | 	if len(o.CallbackURLs) == 0 || len(fmt.Sprintf("%s", o.CallbackURLs)) > 1024 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.callback.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, callback := range o.CallbackURLs { | 	for _, callback := range o.CallbackURLs { | ||||||
| 		if !IsValidHttpUrl(callback) { | 		if !IsValidHttpUrl(callback) { | ||||||
| 			return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.url.app_error", nil, "") | 			return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.url.app_error", nil, "", http.StatusBadRequest) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.DisplayName) > 64 { | 	if len(o.DisplayName) > 64 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.display_name.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.Description) > 128 { | 	if len(o.Description) > 128 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.ContentType) > 128 { | 	if len(o.ContentType) > 128 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if o.TriggerWhen > 1 { | 	if o.TriggerWhen > 1 { | ||||||
| 		return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "") | 		return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "", http.StatusBadRequest) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| @@ -197,8 +200,8 @@ func (o *OutgoingWebhook) PreUpdate() { | |||||||
| 	o.UpdateAt = GetMillis() | 	o.UpdateAt = GetMillis() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *OutgoingWebhook) HasTriggerWord(word string) bool { | func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool { | ||||||
| 	if len(o.TriggerWords) == 0 || len(word) == 0 { | 	if len(word) == 0 { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -212,7 +215,7 @@ func (o *OutgoingWebhook) HasTriggerWord(word string) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool { | func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool { | ||||||
| 	if len(o.TriggerWords) == 0 || len(word) == 0 { | 	if len(word) == 0 { | ||||||
| 		return false | 		return false | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -224,3 +227,27 @@ func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool { | |||||||
|  |  | ||||||
| 	return false | 	return false | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (o *OutgoingWebhook) GetTriggerWord(word string, isExactMatch bool) (triggerWord string) { | ||||||
|  | 	if len(word) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if isExactMatch { | ||||||
|  | 		for _, trigger := range o.TriggerWords { | ||||||
|  | 			if trigger == word { | ||||||
|  | 				triggerWord = trigger | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		for _, trigger := range o.TriggerWords { | ||||||
|  | 			if strings.HasPrefix(word, trigger) { | ||||||
|  | 				triggerWord = trigger | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return triggerWord | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										37
									
								
								vendor/github.com/mattermost/platform/model/password_recovery.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/mattermost/platform/model/password_recovery.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,37 +0,0 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. |  | ||||||
| // See License.txt for license information. |  | ||||||
|  |  | ||||||
| package model |  | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	PASSWORD_RECOVERY_CODE_SIZE  = 128 |  | ||||||
| 	PASSWORD_RECOVER_EXPIRY_TIME = 1000 * 60 * 60 // 1 hour |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| type PasswordRecovery struct { |  | ||||||
| 	UserId   string |  | ||||||
| 	Code     string |  | ||||||
| 	CreateAt int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *PasswordRecovery) IsValid() *AppError { |  | ||||||
|  |  | ||||||
| 	if len(p.UserId) != 26 { |  | ||||||
| 		return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.user_id.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if len(p.Code) != PASSWORD_RECOVERY_CODE_SIZE { |  | ||||||
| 		return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.code.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if p.CreateAt == 0 { |  | ||||||
| 		return NewLocAppError("User.IsValid", "model.password_recovery.is_valid.create_at.app_error", nil, "") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (p *PasswordRecovery) PreSave() { |  | ||||||
| 	p.Code = NewRandomString(PASSWORD_RECOVERY_CODE_SIZE) |  | ||||||
| 	p.CreateAt = GetMillis() |  | ||||||
| } |  | ||||||
							
								
								
									
										59
									
								
								vendor/github.com/mattermost/platform/model/post.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/mattermost/platform/model/post.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -38,6 +38,7 @@ type Post struct { | |||||||
| 	UpdateAt      int64           `json:"update_at"` | 	UpdateAt      int64           `json:"update_at"` | ||||||
| 	EditAt        int64           `json:"edit_at"` | 	EditAt        int64           `json:"edit_at"` | ||||||
| 	DeleteAt      int64           `json:"delete_at"` | 	DeleteAt      int64           `json:"delete_at"` | ||||||
|  | 	IsPinned      bool            `json:"is_pinned"` | ||||||
| 	UserId        string          `json:"user_id"` | 	UserId        string          `json:"user_id"` | ||||||
| 	ChannelId     string          `json:"channel_id"` | 	ChannelId     string          `json:"channel_id"` | ||||||
| 	RootId        string          `json:"root_id"` | 	RootId        string          `json:"root_id"` | ||||||
| @@ -53,6 +54,20 @@ type Post struct { | |||||||
| 	HasReactions  bool            `json:"has_reactions,omitempty"` | 	HasReactions  bool            `json:"has_reactions,omitempty"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type PostPatch struct { | ||||||
|  | 	IsPinned     *bool            `json:"is_pinned"` | ||||||
|  | 	Message      *string          `json:"message"` | ||||||
|  | 	Props        *StringInterface `json:"props"` | ||||||
|  | 	FileIds      *StringArray     `json:"file_ids"` | ||||||
|  | 	HasReactions *bool            `json:"has_reactions"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type PostForIndexing struct { | ||||||
|  | 	Post | ||||||
|  | 	TeamId         string `json:"team_id"` | ||||||
|  | 	ParentCreateAt *int64 `json:"parent_create_at"` | ||||||
|  | } | ||||||
|  |  | ||||||
| func (o *Post) ToJson() string { | func (o *Post) ToJson() string { | ||||||
| 	b, err := json.Marshal(o) | 	b, err := json.Marshal(o) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -189,3 +204,45 @@ func (o *Post) AddProp(key string, value interface{}) { | |||||||
| func (o *Post) IsSystemMessage() bool { | func (o *Post) IsSystemMessage() bool { | ||||||
| 	return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX | 	return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (p *Post) Patch(patch *PostPatch) { | ||||||
|  | 	if patch.IsPinned != nil { | ||||||
|  | 		p.IsPinned = *patch.IsPinned | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.Message != nil { | ||||||
|  | 		p.Message = *patch.Message | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.Props != nil { | ||||||
|  | 		p.Props = *patch.Props | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.FileIds != nil { | ||||||
|  | 		p.FileIds = *patch.FileIds | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if patch.HasReactions != nil { | ||||||
|  | 		p.HasReactions = *patch.HasReactions | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *PostPatch) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return string(b) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func PostPatchFromJson(data io.Reader) *PostPatch { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var post PostPatch | ||||||
|  | 	err := decoder.Decode(&post) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &post | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/post_list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/post_list.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								vendor/github.com/mattermost/platform/model/preference.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/mattermost/platform/model/preference.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -16,14 +16,10 @@ const ( | |||||||
| 	PREFERENCE_CATEGORY_TUTORIAL_STEPS      = "tutorial_step" | 	PREFERENCE_CATEGORY_TUTORIAL_STEPS      = "tutorial_step" | ||||||
| 	PREFERENCE_CATEGORY_ADVANCED_SETTINGS   = "advanced_settings" | 	PREFERENCE_CATEGORY_ADVANCED_SETTINGS   = "advanced_settings" | ||||||
| 	PREFERENCE_CATEGORY_FLAGGED_POST        = "flagged_post" | 	PREFERENCE_CATEGORY_FLAGGED_POST        = "flagged_post" | ||||||
|  | 	PREFERENCE_CATEGORY_FAVORITE_CHANNEL    = "favorite_channel" | ||||||
|  |  | ||||||
| 	PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings" | 	PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings" | ||||||
| 	PREFERENCE_NAME_COLLAPSE_SETTING     = "collapse_previews" | 	PREFERENCE_NAME_COLLAPSE_SETTING     = "collapse_previews" | ||||||
| 	PREFERENCE_NAME_DISPLAY_NAME_FORMAT    = "name_format" |  | ||||||
| 	PREFERENCE_VALUE_DISPLAY_NAME_NICKNAME = "nickname_full_name" |  | ||||||
| 	PREFERENCE_VALUE_DISPLAY_NAME_FULL     = "full_name" |  | ||||||
| 	PREFERENCE_VALUE_DISPLAY_NAME_USERNAME = "username" |  | ||||||
| 	PREFERENCE_DEFAULT_DISPLAY_NAME_FORMAT = PREFERENCE_VALUE_DISPLAY_NAME_USERNAME |  | ||||||
|  |  | ||||||
| 	PREFERENCE_CATEGORY_THEME = "theme" | 	PREFERENCE_CATEGORY_THEME = "theme" | ||||||
| 	// the name for theme props is the team id | 	// the name for theme props is the team id | ||||||
| @@ -37,7 +33,9 @@ const ( | |||||||
|  |  | ||||||
| 	PREFERENCE_CATEGORY_NOTIFICATIONS = "notifications" | 	PREFERENCE_CATEGORY_NOTIFICATIONS = "notifications" | ||||||
| 	PREFERENCE_NAME_EMAIL_INTERVAL    = "email_interval" | 	PREFERENCE_NAME_EMAIL_INTERVAL    = "email_interval" | ||||||
| 	PREFERENCE_DEFAULT_EMAIL_INTERVAL = "30" // default to match the interval of the "immediate" setting (ie 30 seconds) |  | ||||||
|  | 	PREFERENCE_EMAIL_INTERVAL_NO_BATCHING_SECONDS = "30"  // the "immediate" setting is actually 30s | ||||||
|  | 	PREFERENCE_EMAIL_INTERVAL_BATCHING_SECONDS    = "900" // fifteen minutes is 900 seconds | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Preference struct { | type Preference struct { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/preferences.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/preferences.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								vendor/github.com/mattermost/platform/model/push_notification.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/mattermost/platform/model/push_notification.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -36,6 +36,10 @@ type PushNotification struct { | |||||||
| 	ChannelId        string `json:"channel_id"` | 	ChannelId        string `json:"channel_id"` | ||||||
| 	ChannelName      string `json:"channel_name"` | 	ChannelName      string `json:"channel_name"` | ||||||
| 	Type             string `json:"type"` | 	Type             string `json:"type"` | ||||||
|  | 	SenderId         string `json:"sender_id"` | ||||||
|  | 	OverrideUsername string `json:"override_username"` | ||||||
|  | 	OverrideIconUrl  string `json:"override_icon_url"` | ||||||
|  | 	FromWebhook      string `json:"from_webhook"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (me *PushNotification) ToJson() string { | func (me *PushNotification) ToJson() string { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/push_response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/push_response.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								vendor/github.com/mattermost/platform/model/reaction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/mattermost/platform/model/reaction.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -6,6 +6,7 @@ package model | |||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"regexp" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Reaction struct { | type Reaction struct { | ||||||
| @@ -60,7 +61,9 @@ func (o *Reaction) IsValid() *AppError { | |||||||
| 		return NewLocAppError("Reaction.IsValid", "model.reaction.is_valid.post_id.app_error", nil, "post_id="+o.PostId) | 		return NewLocAppError("Reaction.IsValid", "model.reaction.is_valid.post_id.app_error", nil, "post_id="+o.PostId) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(o.EmojiName) == 0 || len(o.EmojiName) > 64 { | 	validName := regexp.MustCompile(`^[a-zA-Z0-9\-\+_]+$`) | ||||||
|  |  | ||||||
|  | 	if len(o.EmojiName) == 0 || len(o.EmojiName) > 64 || !validName.MatchString(o.EmojiName) { | ||||||
| 		return NewLocAppError("Reaction.IsValid", "model.reaction.is_valid.emoji_name.app_error", nil, "emoji_name="+o.EmojiName) | 		return NewLocAppError("Reaction.IsValid", "model.reaction.is_valid.emoji_name.app_error", nil, "emoji_name="+o.EmojiName) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								vendor/github.com/mattermost/platform/model/saml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/mattermost/platform/model/saml.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +1,13 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	USER_AUTH_SERVICE_SAML      = "saml" | 	USER_AUTH_SERVICE_SAML      = "saml" | ||||||
| 	USER_AUTH_SERVICE_SAML_TEXT = "With SAML" | 	USER_AUTH_SERVICE_SAML_TEXT = "With SAML" | ||||||
| @@ -16,3 +21,29 @@ type SamlAuthRequest struct { | |||||||
| 	URL               string | 	URL               string | ||||||
| 	RelayState        string | 	RelayState        string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type SamlCertificateStatus struct { | ||||||
|  | 	IdpCertificateFile    bool `json:"idp_certificate_file"` | ||||||
|  | 	PrivateKeyFile        bool `json:"private_key_file"` | ||||||
|  | 	PublicCertificateFile bool `json:"public_certificate_file"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *SamlCertificateStatus) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(s) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SamlCertificateStatusFromJson(data io.Reader) *SamlCertificateStatus { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var status SamlCertificateStatus | ||||||
|  | 	err := decoder.Decode(&status) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &status | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								vendor/github.com/mattermost/platform/model/scheduled_task.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/mattermost/platform/model/scheduled_task.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"sync" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type TaskFunc func() | ||||||
|  |  | ||||||
|  | type ScheduledTask struct { | ||||||
|  | 	Name      string        `json:"name"` | ||||||
|  | 	Interval  time.Duration `json:"interval"` | ||||||
|  | 	Recurring bool          `json:"recurring"` | ||||||
|  | 	function  TaskFunc | ||||||
|  | 	timer     *time.Timer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var taskMutex = sync.Mutex{} | ||||||
|  | var tasks = make(map[string]*ScheduledTask) | ||||||
|  |  | ||||||
|  | func addTask(task *ScheduledTask) { | ||||||
|  | 	taskMutex.Lock() | ||||||
|  | 	defer taskMutex.Unlock() | ||||||
|  | 	tasks[task.Name] = task | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func removeTaskByName(name string) { | ||||||
|  | 	taskMutex.Lock() | ||||||
|  | 	defer taskMutex.Unlock() | ||||||
|  | 	delete(tasks, name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetTaskByName(name string) *ScheduledTask { | ||||||
|  | 	taskMutex.Lock() | ||||||
|  | 	defer taskMutex.Unlock() | ||||||
|  | 	if task, ok := tasks[name]; ok { | ||||||
|  | 		return task | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAllTasks() *map[string]*ScheduledTask { | ||||||
|  | 	taskMutex.Lock() | ||||||
|  | 	defer taskMutex.Unlock() | ||||||
|  | 	return &tasks | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func CreateTask(name string, function TaskFunc, timeToExecution time.Duration) *ScheduledTask { | ||||||
|  | 	task := &ScheduledTask{ | ||||||
|  | 		Name:      name, | ||||||
|  | 		Interval:  timeToExecution, | ||||||
|  | 		Recurring: false, | ||||||
|  | 		function:  function, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	taskRunner := func() { | ||||||
|  | 		go task.function() | ||||||
|  | 		removeTaskByName(task.Name) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	task.timer = time.AfterFunc(timeToExecution, taskRunner) | ||||||
|  |  | ||||||
|  | 	addTask(task) | ||||||
|  |  | ||||||
|  | 	return task | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func CreateRecurringTask(name string, function TaskFunc, interval time.Duration) *ScheduledTask { | ||||||
|  | 	task := &ScheduledTask{ | ||||||
|  | 		Name:      name, | ||||||
|  | 		Interval:  interval, | ||||||
|  | 		Recurring: true, | ||||||
|  | 		function:  function, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	taskRecurer := func() { | ||||||
|  | 		go task.function() | ||||||
|  | 		task.timer.Reset(task.Interval) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	task.timer = time.AfterFunc(interval, taskRecurer) | ||||||
|  |  | ||||||
|  | 	addTask(task) | ||||||
|  |  | ||||||
|  | 	return task | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (task *ScheduledTask) Cancel() { | ||||||
|  | 	task.timer.Stop() | ||||||
|  | 	removeTaskByName(task.Name) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Executes the task immediatly. A recurring task will be run regularally after interval. | ||||||
|  | func (task *ScheduledTask) Execute() { | ||||||
|  | 	task.function() | ||||||
|  | 	task.timer.Reset(task.Interval) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (task *ScheduledTask) String() string { | ||||||
|  | 	return fmt.Sprintf( | ||||||
|  | 		"%s\nInterval: %s\nRecurring: %t\n", | ||||||
|  | 		task.Name, | ||||||
|  | 		task.Interval.String(), | ||||||
|  | 		task.Recurring, | ||||||
|  | 	) | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/mattermost/platform/model/search_params.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/mattermost/platform/model/search_params.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,10 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"encoding/json" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| @@ -19,6 +20,15 @@ type SearchParams struct { | |||||||
| 	OrTerms    bool | 	OrTerms    bool | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (o *SearchParams) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| var searchFlags = [...]string{"from", "channel", "in"} | var searchFlags = [...]string{"from", "channel", "in"} | ||||||
|  |  | ||||||
| func splitWordsNoQuotes(text string) []string { | func splitWordsNoQuotes(text string) []string { | ||||||
| @@ -165,7 +175,7 @@ func ParseSearchParams(text string) []*SearchParams { | |||||||
| 	if len(plainTerms) == 0 && len(hashtagTerms) == 0 && (len(inChannels) != 0 || len(fromUsers) != 0) { | 	if len(plainTerms) == 0 && len(hashtagTerms) == 0 && (len(inChannels) != 0 || len(fromUsers) != 0) { | ||||||
| 		paramsList = append(paramsList, &SearchParams{ | 		paramsList = append(paramsList, &SearchParams{ | ||||||
| 			Terms:      "", | 			Terms:      "", | ||||||
| 			IsHashtag:  true, | 			IsHashtag:  false, | ||||||
| 			InChannels: inChannels, | 			InChannels: inChannels, | ||||||
| 			FromUsers:  fromUsers, | 			FromUsers:  fromUsers, | ||||||
| 		}) | 		}) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/security_bulletin.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/security_bulletin.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								vendor/github.com/mattermost/platform/model/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/mattermost/platform/model/session.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -11,10 +11,16 @@ import ( | |||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	SESSION_COOKIE_TOKEN              = "MMAUTHTOKEN" | 	SESSION_COOKIE_TOKEN              = "MMAUTHTOKEN" | ||||||
|  | 	SESSION_COOKIE_USER               = "MMUSERID" | ||||||
| 	SESSION_CACHE_SIZE                = 35000 | 	SESSION_CACHE_SIZE                = 35000 | ||||||
| 	SESSION_PROP_PLATFORM             = "platform" | 	SESSION_PROP_PLATFORM             = "platform" | ||||||
| 	SESSION_PROP_OS                   = "os" | 	SESSION_PROP_OS                   = "os" | ||||||
| 	SESSION_PROP_BROWSER              = "browser" | 	SESSION_PROP_BROWSER              = "browser" | ||||||
|  | 	SESSION_PROP_TYPE                 = "type" | ||||||
|  | 	SESSION_PROP_USER_ACCESS_TOKEN_ID = "user_access_token_id" | ||||||
|  | 	SESSION_TYPE_USER_ACCESS_TOKEN    = "UserAccessToken" | ||||||
|  | 	SESSION_ACTIVITY_TIMEOUT          = 1000 * 60 * 5 // 5 minutes | ||||||
|  | 	SESSION_USER_ACCESS_TOKEN_EXPIRY  = 100 * 365     // 100 years | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Session struct { | type Session struct { | ||||||
| @@ -56,7 +62,9 @@ func (me *Session) PreSave() { | |||||||
| 		me.Id = NewId() | 		me.Id = NewId() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if me.Token == "" { | ||||||
| 		me.Token = NewId() | 		me.Token = NewId() | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	me.CreateAt = GetMillis() | 	me.CreateAt = GetMillis() | ||||||
| 	me.LastActivityAt = me.CreateAt | 	me.LastActivityAt = me.CreateAt | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								vendor/github.com/mattermost/platform/model/slack_attachment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/mattermost/platform/model/slack_attachment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +1,13 @@ | |||||||
| // Copyright (c) 2017 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
| type SlackAttachment struct { | type SlackAttachment struct { | ||||||
| 	Id         int64                   `json:"id"` | 	Id         int64                   `json:"id"` | ||||||
| 	Fallback   string                  `json:"fallback"` | 	Fallback   string                  `json:"fallback"` | ||||||
| @@ -27,3 +32,48 @@ type SlackAttachmentField struct { | |||||||
| 	Value interface{} `json:"value"` | 	Value interface{} `json:"value"` | ||||||
| 	Short bool        `json:"short"` | 	Short bool        `json:"short"` | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // To mention @channel via a webhook in Slack, the message should contain | ||||||
|  | // <!channel>, as explained at the bottom of this article: | ||||||
|  | // https://get.slack.help/hc/en-us/articles/202009646-Making-announcements | ||||||
|  | func ExpandAnnouncement(text string) string { | ||||||
|  | 	c1 := "<!channel>" | ||||||
|  | 	c2 := "@channel" | ||||||
|  | 	if strings.Contains(text, c1) { | ||||||
|  | 		return strings.Replace(text, c1, c2, -1) | ||||||
|  | 	} | ||||||
|  | 	return text | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Expand announcements in incoming webhooks from Slack. Those announcements | ||||||
|  | // can be found in the text attribute, or in the pretext, text, title and value | ||||||
|  | // attributes of the attachment structure. The Slack attachment structure is | ||||||
|  | // documented here: https://api.slack.com/docs/attachments | ||||||
|  | func ProcessSlackAttachments(a []*SlackAttachment) []*SlackAttachment { | ||||||
|  | 	var nonNilAttachments []*SlackAttachment | ||||||
|  | 	for _, attachment := range a { | ||||||
|  | 		if attachment == nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		nonNilAttachments = append(nonNilAttachments, attachment) | ||||||
|  |  | ||||||
|  | 		attachment.Pretext = ExpandAnnouncement(attachment.Pretext) | ||||||
|  | 		attachment.Text = ExpandAnnouncement(attachment.Text) | ||||||
|  | 		attachment.Title = ExpandAnnouncement(attachment.Title) | ||||||
|  |  | ||||||
|  | 		var nonNilFields []*SlackAttachmentField | ||||||
|  | 		for _, field := range attachment.Fields { | ||||||
|  | 			if field == nil { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			nonNilFields = append(nonNilFields, field) | ||||||
|  |  | ||||||
|  | 			if field.Value != nil { | ||||||
|  | 				// Ensure the value is set to a string if it is set | ||||||
|  | 				field.Value = ExpandAnnouncement(fmt.Sprintf("%v", field.Value)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		attachment.Fields = nonNilFields | ||||||
|  | 	} | ||||||
|  | 	return nonNilAttachments | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								vendor/github.com/mattermost/platform/model/status.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/mattermost/platform/model/status.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
| @@ -22,7 +22,7 @@ type Status struct { | |||||||
| 	Status         string `json:"status"` | 	Status         string `json:"status"` | ||||||
| 	Manual         bool   `json:"manual"` | 	Manual         bool   `json:"manual"` | ||||||
| 	LastActivityAt int64  `json:"last_activity_at"` | 	LastActivityAt int64  `json:"last_activity_at"` | ||||||
| 	ActiveChannel  string `json:"active_channel" db:"-"` | 	ActiveChannel  string `json:"-" db:"-"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func (o *Status) ToJson() string { | func (o *Status) ToJson() string { | ||||||
| @@ -45,6 +45,26 @@ func StatusFromJson(data io.Reader) *Status { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func StatusListToJson(u []*Status) string { | ||||||
|  | 	b, err := json.Marshal(u) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func StatusListFromJson(data io.Reader) []*Status { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var statuses []*Status | ||||||
|  | 	err := decoder.Decode(&statuses) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return statuses | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func StatusMapToInterfaceMap(statusMap map[string]*Status) map[string]interface{} { | func StatusMapToInterfaceMap(statusMap map[string]*Status) map[string]interface{} { | ||||||
| 	interfaceMap := map[string]interface{}{} | 	interfaceMap := map[string]interface{}{} | ||||||
| 	for _, s := range statusMap { | 	for _, s := range statusMap { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/suggest_command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/suggest_command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								vendor/github.com/mattermost/platform/model/switch_request.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/mattermost/platform/model/switch_request.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. | ||||||
|  | // See License.txt for license information. | ||||||
|  |  | ||||||
|  | package model | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type SwitchRequest struct { | ||||||
|  | 	CurrentService string `json:"current_service"` | ||||||
|  | 	NewService     string `json:"new_service"` | ||||||
|  | 	Email          string `json:"email"` | ||||||
|  | 	Password       string `json:"password"` | ||||||
|  | 	NewPassword    string `json:"new_password"` | ||||||
|  | 	MfaCode        string `json:"mfa_code"` | ||||||
|  | 	LdapId         string `json:"ldap_id"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *SwitchRequest) ToJson() string { | ||||||
|  | 	b, err := json.Marshal(o) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "" | ||||||
|  | 	} else { | ||||||
|  | 		return string(b) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SwitchRequestFromJson(data io.Reader) *SwitchRequest { | ||||||
|  | 	decoder := json.NewDecoder(data) | ||||||
|  | 	var o SwitchRequest | ||||||
|  | 	err := decoder.Decode(&o) | ||||||
|  | 	if err == nil { | ||||||
|  | 		return &o | ||||||
|  | 	} else { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *SwitchRequest) EmailToOAuth() bool { | ||||||
|  | 	return o.CurrentService == USER_AUTH_SERVICE_EMAIL && | ||||||
|  | 		(o.NewService == USER_AUTH_SERVICE_SAML || | ||||||
|  | 			o.NewService == USER_AUTH_SERVICE_GITLAB || | ||||||
|  | 			o.NewService == SERVICE_GOOGLE || | ||||||
|  | 			o.NewService == SERVICE_OFFICE365) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *SwitchRequest) OAuthToEmail() bool { | ||||||
|  | 	return (o.CurrentService == USER_AUTH_SERVICE_SAML || | ||||||
|  | 		o.CurrentService == USER_AUTH_SERVICE_GITLAB || | ||||||
|  | 		o.CurrentService == SERVICE_GOOGLE || | ||||||
|  | 		o.CurrentService == SERVICE_OFFICE365) && o.NewService == USER_AUTH_SERVICE_EMAIL | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *SwitchRequest) EmailToLdap() bool { | ||||||
|  | 	return o.CurrentService == USER_AUTH_SERVICE_EMAIL && o.NewService == USER_AUTH_SERVICE_LDAP | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (o *SwitchRequest) LdapToEmail() bool { | ||||||
|  | 	return o.CurrentService == USER_AUTH_SERVICE_LDAP && o.NewService == USER_AUTH_SERVICE_EMAIL | ||||||
|  | } | ||||||
							
								
								
									
										2
									
								
								vendor/github.com/mattermost/platform/model/system.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/mattermost/platform/model/system.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. | // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. | ||||||
| // See License.txt for license information. | // See License.txt for license information. | ||||||
|  |  | ||||||
| package model | package model | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user