diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/import.go | 10 | ||||
-rw-r--r-- | app/login.go | 25 | ||||
-rw-r--r-- | app/login_test.go | 37 | ||||
-rw-r--r-- | app/notification.go | 5 | ||||
-rw-r--r-- | app/slackimport.go | 20 | ||||
-rw-r--r-- | app/user.go | 11 |
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 } |