summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorJoramWilander <jwawilander@gmail.com>2018-06-27 16:56:50 -0400
committerJoramWilander <jwawilander@gmail.com>2018-06-27 16:56:50 -0400
commit88c5e469ca869d9e8ceadb0f2b03e86005102f24 (patch)
treebbb1b4cc1312879476f222940651e4d3e763da9e /app
parentd7976549a0b45a42c04ac043a15677b7ca1228e9 (diff)
parent437f9f5b64ddb4e1f84e6c4e993120d074001777 (diff)
downloadchat-88c5e469ca869d9e8ceadb0f2b03e86005102f24.tar.gz
chat-88c5e469ca869d9e8ceadb0f2b03e86005102f24.tar.bz2
chat-88c5e469ca869d9e8ceadb0f2b03e86005102f24.zip
Merge branch 'master' into plugins-2
Diffstat (limited to 'app')
-rw-r--r--app/app.go3
-rw-r--r--app/channel.go72
-rw-r--r--app/channel_test.go206
-rw-r--r--app/command_join.go11
-rw-r--r--app/command_join_test.go88
-rw-r--r--app/diagnostics.go7
-rw-r--r--app/file.go2
-rw-r--r--app/import.go3
-rw-r--r--app/oauth.go8
9 files changed, 392 insertions, 8 deletions
diff --git a/app/app.go b/app/app.go
index 51aa1374e..6bf4c9f68 100644
--- a/app/app.go
+++ b/app/app.go
@@ -206,6 +206,9 @@ func New(options ...Option) (outApp *App, outErr error) {
}
app.initJobs()
+ app.AddLicenseListener(func() {
+ app.initJobs()
+ })
subpath, err := utils.GetSubpathFromConfig(app.Config())
if err != nil {
diff --git a/app/channel.go b/app/channel.go
index 7637e9d21..eee27a6de 100644
--- a/app/channel.go
+++ b/app/channel.go
@@ -397,13 +397,13 @@ func (a *App) UpdateChannelPrivacy(oldChannel *model.Channel, user *model.User)
}
func (a *App) postChannelPrivacyMessage(user *model.User, channel *model.Channel) *model.AppError {
- privacy := (map[string]string{
- model.CHANNEL_OPEN: "private_to_public",
- model.CHANNEL_PRIVATE: "public_to_private",
+ message := (map[string]string{
+ model.CHANNEL_OPEN: utils.T("api.channel.change_channel_privacy.private_to_public"),
+ model.CHANNEL_PRIVATE: utils.T("api.channel.change_channel_privacy.public_to_private"),
})[channel.Type]
post := &model.Post{
ChannelId: channel.Id,
- Message: utils.T("api.channel.change_channel_privacy." + privacy),
+ Message: message,
Type: model.POST_CHANGE_CHANNEL_PRIVACY,
UserId: user.Id,
Props: model.StringInterface{
@@ -1591,3 +1591,67 @@ func (a *App) ToggleMuteChannel(channelId string, userId string) *model.ChannelM
a.Srv.Store.Channel().UpdateMember(member)
return member
}
+
+func (a *App) FillInChannelProps(channel *model.Channel) *model.AppError {
+ return a.FillInChannelsProps(&model.ChannelList{channel})
+}
+
+func (a *App) FillInChannelsProps(channelList *model.ChannelList) *model.AppError {
+ // Group the channels by team and call GetChannelsByNames just once per team.
+ channelsByTeam := make(map[string]model.ChannelList)
+ for _, channel := range *channelList {
+ channelsByTeam[channel.TeamId] = append(channelsByTeam[channel.TeamId], channel)
+ }
+
+ for teamId, channelList := range channelsByTeam {
+ allChannelMentions := make(map[string]bool)
+ channelMentions := make(map[*model.Channel][]string, len(channelList))
+
+ // Collect mentions across the channels so as to query just once for this team.
+ for _, channel := range channelList {
+ channelMentions[channel] = model.ChannelMentions(channel.Header)
+
+ for _, channelMention := range channelMentions[channel] {
+ allChannelMentions[channelMention] = true
+ }
+ }
+
+ allChannelMentionNames := make([]string, 0, len(allChannelMentions))
+ for channelName := range allChannelMentions {
+ allChannelMentionNames = append(allChannelMentionNames, channelName)
+ }
+
+ if len(allChannelMentionNames) > 0 {
+ mentionedChannels, err := a.GetChannelsByNames(allChannelMentionNames, teamId)
+ if err != nil {
+ return err
+ }
+
+ mentionedChannelsByName := make(map[string]*model.Channel)
+ for _, channel := range mentionedChannels {
+ mentionedChannelsByName[channel.Name] = channel
+ }
+
+ for _, channel := range channelList {
+ channelMentionsProp := make(map[string]interface{}, len(channelMentions[channel]))
+ for _, channelMention := range channelMentions[channel] {
+ if mentioned, ok := mentionedChannelsByName[channelMention]; ok {
+ if mentioned.Type == model.CHANNEL_OPEN {
+ channelMentionsProp[mentioned.Name] = map[string]interface{}{
+ "display_name": mentioned.DisplayName,
+ }
+ }
+ }
+ }
+
+ if len(channelMentionsProp) > 0 {
+ channel.AddProp("channel_mentions", channelMentionsProp)
+ } else if channel.Props != nil {
+ delete(channel.Props, "channel_mentions")
+ }
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/app/channel_test.go b/app/channel_test.go
index 336d9b25b..4e6aaaf52 100644
--- a/app/channel_test.go
+++ b/app/channel_test.go
@@ -9,6 +9,7 @@ import (
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPermanentDeleteChannel(t *testing.T) {
@@ -399,3 +400,208 @@ func TestAppUpdateChannelScheme(t *testing.T) {
t.Fatal("Wrong Channel SchemeId")
}
}
+
+func TestFillInChannelProps(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ channelPublic1, err := th.App.CreateChannel(&model.Channel{DisplayName: "Public 1", Name: "public1", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
+ require.Nil(t, err)
+ defer th.App.PermanentDeleteChannel(channelPublic1)
+
+ channelPublic2, err := th.App.CreateChannel(&model.Channel{DisplayName: "Public 2", Name: "public2", Type: model.CHANNEL_OPEN, TeamId: th.BasicTeam.Id}, false)
+ require.Nil(t, err)
+ defer th.App.PermanentDeleteChannel(channelPublic2)
+
+ channelPrivate, err := th.App.CreateChannel(&model.Channel{DisplayName: "Private", Name: "private", Type: model.CHANNEL_PRIVATE, TeamId: th.BasicTeam.Id}, false)
+ require.Nil(t, err)
+ defer th.App.PermanentDeleteChannel(channelPrivate)
+
+ otherTeamId := model.NewId()
+ otherTeam := &model.Team{
+ DisplayName: "dn_" + otherTeamId,
+ Name: "name" + otherTeamId,
+ Email: "success+" + otherTeamId + "@simulator.amazonses.com",
+ Type: model.TEAM_OPEN,
+ }
+ otherTeam, err = th.App.CreateTeam(otherTeam)
+ require.Nil(t, err)
+ defer th.App.PermanentDeleteTeam(otherTeam)
+
+ channelOtherTeam, err := th.App.CreateChannel(&model.Channel{DisplayName: "Other Team Channel", Name: "other-team", Type: model.CHANNEL_OPEN, TeamId: otherTeam.Id}, false)
+ require.Nil(t, err)
+ defer th.App.PermanentDeleteChannel(channelOtherTeam)
+
+ // Note that purpose is intentionally plaintext below.
+
+ t.Run("single channels", func(t *testing.T) {
+ testCases := []struct {
+ Description string
+ Channel *model.Channel
+ ExpectedChannelProps map[string]interface{}
+ }{
+ {
+ "channel on basic team without references",
+ &model.Channel{
+ TeamId: th.BasicTeam.Id,
+ Header: "No references",
+ Purpose: "No references",
+ },
+ nil,
+ },
+ {
+ "channel on basic team",
+ &model.Channel{
+ TeamId: th.BasicTeam.Id,
+ Header: "~public1, ~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "public1": map[string]interface{}{
+ "display_name": "Public 1",
+ },
+ },
+ },
+ },
+ {
+ "channel on other team",
+ &model.Channel{
+ TeamId: otherTeam.Id,
+ Header: "~public1, ~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "other-team": map[string]interface{}{
+ "display_name": "Other Team Channel",
+ },
+ },
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.Description, func(t *testing.T) {
+ err = th.App.FillInChannelProps(testCase.Channel)
+ require.Nil(t, err)
+
+ assert.Equal(t, testCase.ExpectedChannelProps, testCase.Channel.Props)
+ })
+ }
+ })
+
+ t.Run("multiple channels", func(t *testing.T) {
+ testCases := []struct {
+ Description string
+ Channels *model.ChannelList
+ ExpectedChannelProps map[string]interface{}
+ }{
+ {
+ "single channel on basic team",
+ &model.ChannelList{
+ {
+ Name: "test",
+ TeamId: th.BasicTeam.Id,
+ Header: "~public1, ~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ },
+ map[string]interface{}{
+ "test": map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "public1": map[string]interface{}{
+ "display_name": "Public 1",
+ },
+ },
+ },
+ },
+ },
+ {
+ "multiple channels on basic team",
+ &model.ChannelList{
+ {
+ Name: "test",
+ TeamId: th.BasicTeam.Id,
+ Header: "~public1, ~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ {
+ Name: "test2",
+ TeamId: th.BasicTeam.Id,
+ Header: "~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ {
+ Name: "test3",
+ TeamId: th.BasicTeam.Id,
+ Header: "No references",
+ Purpose: "No references",
+ },
+ },
+ map[string]interface{}{
+ "test": map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "public1": map[string]interface{}{
+ "display_name": "Public 1",
+ },
+ },
+ },
+ "test2": map[string]interface{}(nil),
+ "test3": map[string]interface{}(nil),
+ },
+ },
+ {
+ "multiple channels across teams",
+ &model.ChannelList{
+ {
+ Name: "test",
+ TeamId: th.BasicTeam.Id,
+ Header: "~public1, ~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ {
+ Name: "test2",
+ TeamId: otherTeam.Id,
+ Header: "~private, ~other-team",
+ Purpose: "~public2, ~private, ~other-team",
+ },
+ {
+ Name: "test3",
+ TeamId: th.BasicTeam.Id,
+ Header: "No references",
+ Purpose: "No references",
+ },
+ },
+ map[string]interface{}{
+ "test": map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "public1": map[string]interface{}{
+ "display_name": "Public 1",
+ },
+ },
+ },
+ "test2": map[string]interface{}{
+ "channel_mentions": map[string]interface{}{
+ "other-team": map[string]interface{}{
+ "display_name": "Other Team Channel",
+ },
+ },
+ },
+ "test3": map[string]interface{}(nil),
+ },
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.Description, func(t *testing.T) {
+ err = th.App.FillInChannelsProps(testCase.Channels)
+ require.Nil(t, err)
+
+ for _, channel := range *testCase.Channels {
+ assert.Equal(t, testCase.ExpectedChannelProps[channel.Name], channel.Props)
+ }
+ })
+ }
+ })
+}
diff --git a/app/command_join.go b/app/command_join.go
index 92084448e..61ed65ba6 100644
--- a/app/command_join.go
+++ b/app/command_join.go
@@ -6,6 +6,7 @@ package app
import (
"github.com/mattermost/mattermost-server/model"
goi18n "github.com/nicksnyder/go-i18n/i18n"
+ "strings"
)
type JoinProvider struct {
@@ -34,12 +35,18 @@ func (me *JoinProvider) GetCommand(a *App, T goi18n.TranslateFunc) *model.Comman
}
func (me *JoinProvider) DoCommand(a *App, args *model.CommandArgs, message string) *model.CommandResponse {
- if result := <-a.Srv.Store.Channel().GetByName(args.TeamId, message, true); result.Err != nil {
+ channelName := message
+
+ if strings.HasPrefix(message, "~") {
+ channelName = message[1:]
+ }
+
+ if result := <-a.Srv.Store.Channel().GetByName(args.TeamId, channelName, true); result.Err != nil {
return &model.CommandResponse{Text: args.T("api.command_join.list.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
} else {
channel := result.Data.(*model.Channel)
- if channel.Name == message {
+ if channel.Name == channelName {
allowed := false
if (channel.Type == model.CHANNEL_PRIVATE && a.SessionHasPermissionToChannel(args.Session, channel.Id, model.PERMISSION_READ_CHANNEL)) || channel.Type == model.CHANNEL_OPEN {
allowed = true
diff --git a/app/command_join_test.go b/app/command_join_test.go
new file mode 100644
index 000000000..77574217b
--- /dev/null
+++ b/app/command_join_test.go
@@ -0,0 +1,88 @@
+// Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package app
+
+import (
+ "testing"
+ "github.com/mattermost/mattermost-server/model"
+ "github.com/nicksnyder/go-i18n/i18n"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestJoinCommandNoChannel(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ if testing.Short() {
+ t.SkipNow()
+ }
+
+ cmd := &JoinProvider{}
+ resp := cmd.DoCommand(th.App, &model.CommandArgs{
+ T: i18n.IdentityTfunc(),
+ UserId: th.BasicUser2.Id,
+ SiteURL: "http://test.url",
+ TeamId: th.BasicTeam.Id,
+ }, "asdsad")
+
+ assert.Equal(t, "api.command_join.list.app_error", resp.Text)
+}
+
+func TestJoinCommandForExistingChannel(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ if testing.Short() {
+ t.SkipNow()
+ }
+
+ channel2, _ := th.App.CreateChannel(&model.Channel{
+ DisplayName: "AA",
+ Name: "aa" + model.NewId() + "a",
+ Type: model.CHANNEL_OPEN,
+ TeamId: th.BasicTeam.Id,
+ CreatorId: th.BasicUser.Id,
+ }, false)
+
+
+ cmd := &JoinProvider{}
+ resp := cmd.DoCommand(th.App, &model.CommandArgs{
+ T: i18n.IdentityTfunc(),
+ UserId: th.BasicUser2.Id,
+ SiteURL: "http://test.url",
+ TeamId: th.BasicTeam.Id,
+ }, channel2.Name)
+
+ assert.Equal(t, "", resp.Text)
+ assert.Equal(t, "http://test.url/"+th.BasicTeam.Name+"/channels/"+channel2.Name, resp.GotoLocation)
+}
+
+func TestJoinCommandWithTilde(t *testing.T) {
+ th := Setup().InitBasic()
+ defer th.TearDown()
+
+ if testing.Short() {
+ t.SkipNow()
+ }
+
+ channel2, _ := th.App.CreateChannel(&model.Channel{
+ DisplayName: "AA",
+ Name: "aa" + model.NewId() + "a",
+ Type: model.CHANNEL_OPEN,
+ TeamId: th.BasicTeam.Id,
+ CreatorId: th.BasicUser.Id,
+ }, false)
+
+
+ cmd := &JoinProvider{}
+ resp := cmd.DoCommand(th.App, &model.CommandArgs{
+ T: i18n.IdentityTfunc(),
+ UserId: th.BasicUser2.Id,
+ SiteURL: "http://test.url",
+ TeamId: th.BasicTeam.Id,
+ }, "~"+channel2.Name)
+
+ assert.Equal(t, "", resp.Text)
+ assert.Equal(t, "http://test.url/"+th.BasicTeam.Name+"/channels/"+channel2.Name, resp.GotoLocation)
+}
diff --git a/app/diagnostics.go b/app/diagnostics.go
index c37d7d339..966cdb5be 100644
--- a/app/diagnostics.go
+++ b/app/diagnostics.go
@@ -36,6 +36,7 @@ const (
TRACK_CONFIG_WEBRTC = "config_webrtc"
TRACK_CONFIG_SUPPORT = "config_support"
TRACK_CONFIG_NATIVEAPP = "config_nativeapp"
+ TRACK_CONFIG_EXPERIMENTAL = "config_experimental"
TRACK_CONFIG_ANALYTICS = "config_analytics"
TRACK_CONFIG_ANNOUNCEMENT = "config_announcement"
TRACK_CONFIG_ELASTICSEARCH = "config_elasticsearch"
@@ -252,6 +253,7 @@ func (a *App) trackConfig() {
"allow_cookies_for_subdomains": *cfg.ServiceSettings.AllowCookiesForSubdomains,
"enable_api_team_deletion": *cfg.ServiceSettings.EnableAPITeamDeletion,
"experimental_enable_hardened_mode": *cfg.ServiceSettings.ExperimentalEnableHardenedMode,
+ "experimental_limit_client_config": *cfg.ServiceSettings.ExperimentalLimitClientConfig,
})
a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{
@@ -475,6 +477,11 @@ func (a *App) trackConfig() {
"isdefault_turn_uri": isDefault(*cfg.WebrtcSettings.TurnURI, model.WEBRTC_SETTINGS_DEFAULT_TURN_URI),
})
+ a.SendDiagnostic(TRACK_CONFIG_EXPERIMENTAL, map[string]interface{}{
+ "client_side_cert_enable": *cfg.ExperimentalSettings.ClientSideCertEnable,
+ "isdefault_client_side_cert_check": isDefault(*cfg.ExperimentalSettings.ClientSideCertCheck, model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH),
+ })
+
a.SendDiagnostic(TRACK_CONFIG_ANALYTICS, map[string]interface{}{
"isdefault_max_users_for_statistics": isDefault(*cfg.AnalyticsSettings.MaxUsersForStatistics, model.ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS),
})
diff --git a/app/file.go b/app/file.go
index add965fd7..95d11afed 100644
--- a/app/file.go
+++ b/app/file.go
@@ -54,7 +54,7 @@ const (
MaxImageSize = 6048 * 4032 // 24 megapixels, roughly 36MB as a raw image
IMAGE_THUMBNAIL_PIXEL_WIDTH = 120
IMAGE_THUMBNAIL_PIXEL_HEIGHT = 100
- IMAGE_PREVIEW_PIXEL_WIDTH = 1024
+ IMAGE_PREVIEW_PIXEL_WIDTH = 1920
)
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
diff --git a/app/import.go b/app/import.go
index 04e71b64c..64e53fe93 100644
--- a/app/import.go
+++ b/app/import.go
@@ -209,6 +209,9 @@ func (a *App) BulkImport(fileReader io.Reader, dryRun bool, workers int) (*model
scanner := bufio.NewScanner(fileReader)
lineNumber := 0
+ a.Srv.Store.LockToMaster()
+ defer a.Srv.Store.UnlockFromMaster()
+
errorsChan := make(chan LineImportWorkerError, (2*workers)+1) // size chosen to ensure it never gets filled up completely.
var wg sync.WaitGroup
var linesChan chan LineImportWorkerData
diff --git a/app/oauth.go b/app/oauth.go
index 477c0aeaf..80fe4342e 100644
--- a/app/oauth.go
+++ b/app/oauth.go
@@ -457,7 +457,13 @@ func (a *App) LoginByOAuth(service string, userData io.Reader, teamId string) (*
return nil, model.NewAppError("LoginByOAuth", "api.user.login_by_oauth.not_available.app_error",
map[string]interface{}{"Service": strings.Title(service)}, "", http.StatusNotImplemented)
} else {
- authData = provider.GetAuthDataFromJson(bytes.NewReader(buf.Bytes()))
+ authUser := provider.GetUserFromJson(bytes.NewReader(buf.Bytes()))
+
+ if authUser.AuthData != nil {
+ authData = *authUser.AuthData
+ } else {
+ authData = ""
+ }
}
if len(authData) == 0 {