Merge branch 'master' into advanced-permissions-phase-1

Этот коммит содержится в:
Martin Kraft
2018-03-23 09:08:49 -04:00
родитель 37f0e5e0eb 87762ae62e
Коммит 5fa1b35819
53 изменённых файлов: 2849 добавлений и 164 удалений

Просмотреть файл

@@ -66,6 +66,8 @@ type App struct {
clientLicenseValue atomic.Value
licenseListeners map[string]func()
timezones atomic.Value
siteURL string
newStore func() store.Store
@@ -127,6 +129,9 @@ func New(options ...Option) (outApp *App, outErr error) {
return nil, err
}
app.EnableConfigWatch()
app.LoadTimezones()
if err := utils.InitTranslations(app.Config().LocalizationSettings); err != nil {
return nil, errors.Wrapf(err, "unable to load Mattermost translation files")
}
@@ -439,7 +444,11 @@ func (a *App) WaitForGoroutines() {
}
func (a *App) HTMLTemplates() *template.Template {
return a.htmlTemplateWatcher.Templates()
if a.htmlTemplateWatcher != nil {
return a.htmlTemplateWatcher.Templates()
}
return nil
}
func (a *App) HTTPClient(trustURLs bool) *http.Client {

Просмотреть файл

@@ -7,6 +7,7 @@ import (
"bytes"
"io"
"os"
"path/filepath"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
@@ -43,7 +44,7 @@ func (cfg *AutoPostCreator) UploadTestFile() ([]string, bool) {
filename := cfg.ImageFilenames[utils.RandIntFromRange(utils.Range{Begin: 0, End: len(cfg.ImageFilenames) - 1})]
path, _ := utils.FindDir("web/static/images")
file, err := os.Open(path + "/" + filename)
file, err := os.Open(filepath.Join(path, filename))
if err != nil {
return nil, false
}

Просмотреть файл

@@ -54,6 +54,7 @@ func (a *App) LoadConfig(configFile string) *model.AppError {
a.configFile = configPath
utils.ConfigureLog(&cfg.LogSettings)
l4g.Info("Using config file at %s", configPath)
a.config.Store(cfg)

Просмотреть файл

@@ -399,7 +399,7 @@ func (a *App) ImportChannel(data *ChannelImportData, dryRun bool) *model.AppErro
var team *model.Team
if result := <-a.Srv.Store.Team().GetByName(*data.Team); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_channel.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_channel.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, result.Err.Error(), http.StatusBadRequest)
} else {
team = result.Data.(*model.Team)
}
@@ -781,7 +781,7 @@ func (a *App) ImportUser(data *UserImportData, dryRun bool) *model.AppError {
if len(preferences) > 0 {
if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_user.save_preferences.error", nil, "", http.StatusInternalServerError)
return model.NewAppError("BulkImport", "app.import.import_user.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError)
}
}
@@ -899,7 +899,7 @@ func (a *App) ImportUserChannels(user *model.User, team *model.Team, teamMember
if len(preferences) > 0 {
if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_user_channels.save_preferences.error", nil, "", http.StatusInternalServerError)
return model.NewAppError("BulkImport", "app.import.import_user_channels.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError)
}
}
@@ -1069,7 +1069,7 @@ func (a *App) ImportReaction(data *ReactionImportData, post *model.Post, dryRun
var user *model.User
if result := <-a.Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, result.Err.Error(), http.StatusBadRequest)
} else {
user = result.Data.(*model.User)
}
@@ -1092,7 +1092,7 @@ func (a *App) ImportReply(data *ReplyImportData, post *model.Post, dryRun bool)
var user *model.User
if result := <-a.Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": data.User}, result.Err.Error(), http.StatusBadRequest)
} else {
user = result.Data.(*model.User)
}
@@ -1147,21 +1147,21 @@ func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
var team *model.Team
if result := <-a.Srv.Store.Team().GetByName(*data.Team); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.team_not_found.error", map[string]interface{}{"TeamName": *data.Team}, result.Err.Error(), http.StatusBadRequest)
} else {
team = result.Data.(*model.Team)
}
var channel *model.Channel
if result := <-a.Srv.Store.Channel().GetByName(team.Id, *data.Channel, false); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.channel_not_found.error", map[string]interface{}{"ChannelName": *data.Channel}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.channel_not_found.error", map[string]interface{}{"ChannelName": *data.Channel}, result.Err.Error(), http.StatusBadRequest)
} else {
channel = result.Data.(*model.Channel)
}
var user *model.User
if result := <-a.Srv.Store.User().GetByUsername(*data.User); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": *data.User}, result.Err.Error(), http.StatusBadRequest)
} else {
user = result.Data.(*model.User)
}
@@ -1210,7 +1210,7 @@ func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
var user *model.User
if result := <-a.Srv.Store.User().GetByUsername(username); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": username}, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_post.user_not_found.error", map[string]interface{}{"Username": username}, result.Err.Error(), http.StatusBadRequest)
} else {
user = result.Data.(*model.User)
}
@@ -1225,7 +1225,7 @@ func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
if len(preferences) > 0 {
if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_post.save_preferences.error", nil, "", http.StatusInternalServerError)
return model.NewAppError("BulkImport", "app.import.import_post.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError)
}
}
}
@@ -1351,7 +1351,7 @@ func (a *App) ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *m
userIds = append(userIds, user.Id)
userMap[username] = user.Id
} else {
return model.NewAppError("BulkImport", "app.import.import_direct_channel.member_not_found.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_channel.member_not_found.error", nil, result.Err.Error(), http.StatusBadRequest)
}
}
@@ -1360,14 +1360,14 @@ func (a *App) ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *m
if len(userIds) == 2 {
ch, err := a.createDirectChannel(userIds[0], userIds[1])
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_direct_channel.error", nil, err.Error(), http.StatusBadRequest)
} else {
channel = ch
}
} else {
ch, err := a.createGroupChannel(userIds, userIds[0])
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_channel.create_group_channel.error", nil, err.Error(), http.StatusBadRequest)
} else {
channel = ch
}
@@ -1403,7 +1403,7 @@ func (a *App) ImportDirectChannel(data *DirectChannelImportData, dryRun bool) *m
if data.Header != nil {
channel.Header = *data.Header
if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_direct_channel.update_header_failed.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_channel.update_header_failed.error", nil, result.Err.Error(), http.StatusBadRequest)
}
}
@@ -1461,7 +1461,7 @@ func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.A
user := result.Data.(*model.User)
userIds = append(userIds, user.Id)
} else {
return model.NewAppError("BulkImport", "app.import.import_direct_post.channel_member_not_found.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_post.channel_member_not_found.error", nil, result.Err.Error(), http.StatusBadRequest)
}
}
@@ -1469,14 +1469,14 @@ func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.A
if len(userIds) == 2 {
ch, err := a.createDirectChannel(userIds[0], userIds[1])
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
return model.NewAppError("BulkImport", "app.import.import_direct_post.create_direct_channel.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_post.create_direct_channel.error", nil, err.Error(), http.StatusBadRequest)
} else {
channel = ch
}
} else {
ch, err := a.createGroupChannel(userIds, userIds[0])
if err != nil && err.Id != store.CHANNEL_EXISTS_ERROR {
return model.NewAppError("BulkImport", "app.import.import_direct_post.create_group_channel.error", nil, "", http.StatusBadRequest)
return model.NewAppError("BulkImport", "app.import.import_direct_post.create_group_channel.error", nil, err.Error(), http.StatusBadRequest)
} else {
channel = ch
}
@@ -1548,7 +1548,7 @@ func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.A
if len(preferences) > 0 {
if result := <-a.Srv.Store.Preference().Save(&preferences); result.Err != nil {
return model.NewAppError("BulkImport", "app.import.import_direct_post.save_preferences.error", nil, "", http.StatusInternalServerError)
return model.NewAppError("BulkImport", "app.import.import_direct_post.save_preferences.error", nil, result.Err.Error(), http.StatusInternalServerError)
}
}
}

Просмотреть файл

@@ -4,6 +4,7 @@
package app
import (
"path/filepath"
"runtime/debug"
"strings"
"testing"
@@ -370,7 +371,7 @@ func TestImportValidateUserImportData(t *testing.T) {
// Test a valid User with all fields populated.
testsDir, _ := utils.FindDir("tests")
data = UserImportData{
ProfileImage: ptrStr(testsDir + "test.png"),
ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")),
Username: ptrStr("bob"),
Email: ptrStr("bob@example.com"),
AuthService: ptrStr("ldap"),
@@ -1471,7 +1472,7 @@ func TestImportImportUser(t *testing.T) {
username := model.NewId()
testsDir, _ := utils.FindDir("tests")
data = UserImportData{
ProfileImage: ptrStr(testsDir + "test.png"),
ProfileImage: ptrStr(filepath.Join(testsDir, "test.png")),
Username: &username,
Email: ptrStr(model.NewId() + "@example.com"),
Nickname: ptrStr(model.NewId()),
@@ -1527,7 +1528,7 @@ func TestImportImportUser(t *testing.T) {
// Alter all the fields of that user.
data.Email = ptrStr(model.NewId() + "@example.com")
data.ProfileImage = ptrStr(testsDir + "testgif.gif")
data.ProfileImage = ptrStr(filepath.Join(testsDir, "testgif.gif"))
data.AuthService = ptrStr("ldap")
data.AuthData = &username
data.Nickname = ptrStr(model.NewId())

Просмотреть файл

@@ -401,7 +401,7 @@ func (a *App) InitPlugins(pluginPath, webappPath string, supervisorOverride plug
options = append(options, pluginenv.SupervisorProvider(supervisorOverride))
} else if err := sandbox.CheckSupport(); err != nil {
l4g.Warn(err.Error())
l4g.Warn("plugin sandboxing is not supported. plugins will run with the same access level as the server")
l4g.Warn("plugin sandboxing is not supported. plugins will run with the same access level as the server. See documentation to learn more: https://developers.mattermost.com/extend/plugins/security/")
options = append(options, pluginenv.SupervisorProvider(rpcplugin.SupervisorProvider))
} else {
options = append(options, pluginenv.SupervisorProvider(sandbox.SupervisorProvider))

Просмотреть файл

@@ -8,7 +8,6 @@ import (
"mime/multipart"
"net/http"
"os"
"path/filepath"
"github.com/mattermost/mattermost-server/model"
@@ -42,7 +41,7 @@ func WriteSamlFile(fileData *multipart.FileHeader) *model.AppError {
defer file.Close()
configDir, _ := utils.FindDir("config")
out, err := os.Create(configDir + filename)
out, err := os.Create(filepath.Join(configDir, filename))
if err != nil {
return model.NewAppError("AddSamlCertificate", "api.admin.add_certificate.saving.app_error", nil, err.Error(), http.StatusInternalServerError)
}

Просмотреть файл

@@ -225,7 +225,7 @@ func (a *App) UpdateLastActivityAtIfNeeded(session model.Session) {
}
if result := <-a.Srv.Store.Session().UpdateLastActivityAt(session.Id, now); result.Err != nil {
l4g.Error(utils.T("api.status.last_activity.error"), session.UserId, session.Id)
l4g.Error(utils.T("api.status.last_activity.error"), session.UserId, session.Id, result.Err)
}
session.LastActivityAt = now

28
app/timezone.go Обычный файл
Просмотреть файл

@@ -0,0 +1,28 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
)
func (a *App) Timezones() model.SupportedTimezones {
if cfg := a.timezones.Load(); cfg != nil {
return cfg.(model.SupportedTimezones)
}
return model.SupportedTimezones{}
}
func (a *App) LoadTimezones() {
timezonePath := "timezones.json"
if a.Config().TimezoneSettings.SupportedTimezonesPath != nil && len(*a.Config().TimezoneSettings.SupportedTimezonesPath) > 0 {
timezonePath = *a.Config().TimezoneSettings.SupportedTimezonesPath
}
timezoneCfg := utils.LoadTimezones(timezonePath)
a.timezones.Store(timezoneCfg)
}

Просмотреть файл

@@ -18,6 +18,7 @@ import (
"io/ioutil"
"mime/multipart"
"net/http"
"path/filepath"
"strconv"
"strings"
@@ -717,7 +718,7 @@ func CreateProfileImage(username string, userId string, initialFont string) ([]b
initial := string(strings.ToUpper(username)[0])
fontDir, _ := utils.FindDir("fonts")
fontBytes, err := ioutil.ReadFile(fontDir + initialFont)
fontBytes, err := ioutil.ReadFile(filepath.Join(fontDir, initialFont))
if err != nil {
return nil, model.NewAppError("CreateProfileImage", "api.user.create_profile_image.default_font.app_error", nil, err.Error(), http.StatusInternalServerError)
}