summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/import.go10
-rw-r--r--app/login.go25
-rw-r--r--app/login_test.go37
-rw-r--r--app/notification.go5
-rw-r--r--app/slackimport.go20
-rw-r--r--app/user.go11
6 files changed, 94 insertions, 14 deletions
diff --git a/app/import.go b/app/import.go
index 8075497a0..5364b1026 100644
--- a/app/import.go
+++ b/app/import.go
@@ -1699,10 +1699,12 @@ func (a *App) OldImportFile(timestamp time.Time, file io.Reader, teamId string,
return nil, err
}
- img, width, height := prepareImage(data)
- if img != nil {
- a.generateThumbnailImage(*img, fileInfo.ThumbnailPath, width, height)
- a.generatePreviewImage(*img, fileInfo.PreviewPath, width)
+ if fileInfo.IsImage() && fileInfo.MimeType != "image/svg+xml" {
+ img, width, height := prepareImage(data)
+ if img != nil {
+ a.generateThumbnailImage(*img, fileInfo.ThumbnailPath, width, height)
+ a.generatePreviewImage(*img, fileInfo.PreviewPath, width)
+ }
}
return fileInfo, nil
diff --git a/app/login.go b/app/login.go
index 3001e1f4d..d3d2a423e 100644
--- a/app/login.go
+++ b/app/login.go
@@ -6,6 +6,7 @@ package app
import (
"fmt"
"net/http"
+ "strings"
"time"
"github.com/avct/uasurfer"
@@ -13,6 +14,23 @@ import (
"github.com/mattermost/mattermost-server/store"
)
+func (a *App) CheckForClienSideCert(r *http.Request) (string, string, string) {
+ pem := r.Header.Get("X-SSL-Client-Cert") // mapped to $ssl_client_cert from nginx
+ subject := r.Header.Get("X-SSL-Client-Cert-Subject-DN") // mapped to $ssl_client_s_dn from nginx
+ email := ""
+
+ if len(subject) > 0 {
+ for _, v := range strings.Split(subject, "/") {
+ kv := strings.Split(v, "=")
+ if len(kv) == 2 && kv[0] == "emailAddress" {
+ email = kv[1]
+ }
+ }
+ }
+
+ return pem, subject, email
+}
+
func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken string, ldapOnly bool) (user *model.User, err *model.AppError) {
// Do statistics
defer func() {
@@ -35,6 +53,13 @@ func (a *App) AuthenticateUserForLogin(id, loginId, password, mfaToken string, l
return nil, err
}
+ // If client side cert is enable and it's checking as a primary source
+ // then trust the proxy and cert that the correct user is supplied and allow
+ // them access
+ if *a.Config().ExperimentalSettings.ClientSideCertEnable && *a.Config().ExperimentalSettings.ClientSideCertCheck == model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH {
+ return user, nil
+ }
+
// and then authenticate them
if user, err = a.authenticateUser(user, password, mfaToken); err != nil {
return nil, err
diff --git a/app/login_test.go b/app/login_test.go
new file mode 100644
index 000000000..db92f1d7d
--- /dev/null
+++ b/app/login_test.go
@@ -0,0 +1,37 @@
+// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+package app
+
+import (
+ "net/http"
+ "testing"
+)
+
+func TestCheckForClienSideCert(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ var tests = []struct {
+ pem string
+ subject string
+ expectedEmail string
+ }{
+ {"blah", "blah", ""},
+ {"blah", "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=test@test.com", "test@test.com"},
+ {"blah", "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/EmailAddress=test@test.com", ""},
+ {"blah", "CN=www.freesoft.org/EmailAddress=test@test.com, C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft", ""},
+ }
+
+ for _, tt := range tests {
+ r := &http.Request{Header: http.Header{}}
+ r.Header.Add("X-SSL-Client-Cert", tt.pem)
+ r.Header.Add("X-SSL-Client-Cert-Subject-DN", tt.subject)
+
+ _, _, actualEmail := th.App.CheckForClienSideCert(r)
+
+ if actualEmail != tt.expectedEmail {
+ t.Fatalf("CheckForClienSideCert(%v): expected %v, actual %v", tt.subject, tt.expectedEmail, actualEmail)
+ }
+ }
+}
diff --git a/app/notification.go b/app/notification.go
index a3c1857d5..dbd37c7f2 100644
--- a/app/notification.go
+++ b/app/notification.go
@@ -752,6 +752,11 @@ func (a *App) sendPushNotification(post *model.Post, user *model.User, channel *
msg.Message = a.getPushNotificationMessage(post.Message, explicitMention, channelWideMention, hasFiles, senderName, channelName, channel.Type, replyToThreadType, userLocale)
for _, session := range sessions {
+
+ if session.IsExpired() {
+ continue
+ }
+
tmpMessage := *model.PushNotificationFromJson(strings.NewReader(msg.ToJson()))
tmpMessage.SetDeviceIdAndPlatform(session.DeviceId)
diff --git a/app/slackimport.go b/app/slackimport.go
index 3333af604..f9e2ac4ab 100644
--- a/app/slackimport.go
+++ b/app/slackimport.go
@@ -157,7 +157,7 @@ func (a *App) SlackAddUsers(teamId string, slackusers []SlackUser, importerLog *
if email == "" {
email = sUser.Username + "@example.com"
importerLog.WriteString(utils.T("api.slackimport.slack_add_users.missing_email_address", map[string]interface{}{"Email": email, "Username": sUser.Username}))
- mlog.Warn("Slack Import: User {{.Username}} does not have an email address in the Slack export. Used {{.Email}} as a placeholder. The user should update their email address once logged in to the system.")
+ mlog.Warn(fmt.Sprintf("Slack Import: User %v does not have an email address in the Slack export. Used %v as a placeholder. The user should update their email address once logged in to the system.", email, sUser.Username))
}
password := model.NewId()
@@ -396,7 +396,7 @@ func (a *App) SlackUploadFile(sPost SlackPost, uploads map[string]*zip.File, tea
if file, ok := uploads[sPost.File.Id]; ok {
openFile, err := file.Open()
if err != nil {
- mlog.Warn("Slack Import: Unable to open the file {{.FileId}} from the Slack export: {{.Error}}.")
+ mlog.Warn(fmt.Sprintf("Slack Import: Unable to open the file %v from the Slack export: %v.", sPost.File.Id, err.Error()))
return nil, false
}
defer openFile.Close()
@@ -404,13 +404,13 @@ func (a *App) SlackUploadFile(sPost SlackPost, uploads map[string]*zip.File, tea
timestamp := utils.TimeFromMillis(SlackConvertTimeStamp(sPost.TimeStamp))
uploadedFile, err := a.OldImportFile(timestamp, openFile, teamId, channelId, userId, filepath.Base(file.Name))
if err != nil {
- mlog.Warn("Slack Import: An error occurred when uploading file {{.FileId}}: {{.Error}}.")
+ mlog.Warn(fmt.Sprintf("Slack Import: An error occurred when uploading file %v: %v.", sPost.File.Id, err.Error()))
return nil, false
}
return uploadedFile, true
} else {
- mlog.Warn("Slack Import: Unable to import file {{.FileId}} as the file is missing from the Slack export zip file.")
+ mlog.Warn(fmt.Sprintf("Slack Import: Unable to import file %v as the file is missing from the Slack export zip file.", sPost.File.Id))
return nil, false
}
} else {
@@ -440,22 +440,22 @@ func (a *App) addSlackUsersToChannel(members []string, users map[string]*model.U
func SlackSanitiseChannelProperties(channel model.Channel) model.Channel {
if utf8.RuneCountInString(channel.DisplayName) > model.CHANNEL_DISPLAY_NAME_MAX_RUNES {
- mlog.Warn(fmt.Sprint("api.slackimport.slack_sanitise_channel_properties.display_name_too_long.warn", map[string]interface{}{"ChannelName": channel.DisplayName}))
+ mlog.Warn(fmt.Sprintf("Slack Import: Channel %v display name exceeds the maximum length. It will be truncated when imported.", channel.DisplayName))
channel.DisplayName = truncateRunes(channel.DisplayName, model.CHANNEL_DISPLAY_NAME_MAX_RUNES)
}
if len(channel.Name) > model.CHANNEL_NAME_MAX_LENGTH {
- mlog.Warn(fmt.Sprint("api.slackimport.slack_sanitise_channel_properties.name_too_long.warn", map[string]interface{}{"ChannelName": channel.DisplayName}))
+ mlog.Warn(fmt.Sprintf("Slack Import: Channel %v handle exceeds the maximum length. It will be truncated when imported.", channel.DisplayName))
channel.Name = channel.Name[0:model.CHANNEL_NAME_MAX_LENGTH]
}
if utf8.RuneCountInString(channel.Purpose) > model.CHANNEL_PURPOSE_MAX_RUNES {
- mlog.Warn(fmt.Sprint("api.slackimport.slack_sanitise_channel_properties.purpose_too_long.warn", map[string]interface{}{"ChannelName": channel.DisplayName}))
+ mlog.Warn(fmt.Sprintf("Slack Import: Channel %v purpose exceeds the maximum length. It will be truncated when imported.", channel.DisplayName))
channel.Purpose = truncateRunes(channel.Purpose, model.CHANNEL_PURPOSE_MAX_RUNES)
}
if utf8.RuneCountInString(channel.Header) > model.CHANNEL_HEADER_MAX_RUNES {
- mlog.Warn(fmt.Sprint("api.slackimport.slack_sanitise_channel_properties.header_too_long.warn", map[string]interface{}{"ChannelName": channel.DisplayName}))
+ mlog.Warn(fmt.Sprintf("Slack Import: Channel %v header exceeds the maximum length. It will be truncated when imported.", channel.DisplayName))
channel.Header = truncateRunes(channel.Header, model.CHANNEL_HEADER_MAX_RUNES)
}
@@ -514,7 +514,7 @@ func SlackConvertUserMentions(users []SlackUser, posts map[string][]SlackPost) m
for _, user := range users {
r, err := regexp.Compile("<@" + user.Id + `(\|` + user.Username + ")?>")
if err != nil {
- mlog.Warn(fmt.Sprint("Slack Import: Unable to compile the @mention, matching regular expression for the Slack user {{.Username}} (id={{.UserID}}).", user.Id, user.Username), mlog.String("user_id", user.Id))
+ mlog.Warn(fmt.Sprintf("Slack Import: Unable to compile the @mention, matching regular expression for the Slack user %v (id=%v).", user.Id, user.Username), mlog.String("user_id", user.Id))
continue
}
regexes["@"+user.Username] = r
@@ -542,7 +542,7 @@ func SlackConvertChannelMentions(channels []SlackChannel, posts map[string][]Sla
for _, channel := range channels {
r, err := regexp.Compile("<#" + channel.Id + `(\|` + channel.Name + ")?>")
if err != nil {
- mlog.Warn(fmt.Sprint("Slack Import: Unable to compile the !channel, matching regular expression for the Slack channel {{.ChannelName}} (id={{.ChannelID}}).", channel.Id, channel.Name))
+ mlog.Warn(fmt.Sprintf("Slack Import: Unable to compile the !channel, matching regular expression for the Slack channel %v (id=%v).", channel.Id, channel.Name))
continue
}
regexes["~"+channel.Name] = r
diff --git a/app/user.go b/app/user.go
index ccf8dd40e..27e6f347d 100644
--- a/app/user.go
+++ b/app/user.go
@@ -1373,6 +1373,17 @@ func (a *App) GetVerifyEmailToken(token string) (*model.Token, *model.AppError)
}
}
+func (a *App) GetTotalUsersStats() (*model.UsersStats, *model.AppError) {
+ stats := &model.UsersStats{}
+
+ if result := <-a.Srv.Store.User().GetTotalUsersCount(); result.Err != nil {
+ return nil, result.Err
+ } else {
+ stats.TotalUsersCount = result.Data.(int64)
+ }
+ return stats, nil
+}
+
func (a *App) VerifyUserEmail(userId string) *model.AppError {
return (<-a.Srv.Store.User().VerifyEmail(userId)).Err
}