Merge branch 'release-4.7' into rm-willnorris-proxy-support

Этот коммит содержится в:
Chris
2018-02-12 18:36:39 -06:00
коммит произвёл GitHub
родитель 56f49cf486 32c1f7be23
Коммит fbef16f863
86 изменённых файлов: 1357 добавлений и 1348 удалений

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

@@ -276,7 +276,7 @@ store-mocks: ## Creates mock files.
GOPATH=$(shell go env GOPATH) $(shell go env GOPATH)/bin/mockery -dir store -all -output store/storetest/mocks -note 'Regenerate this file using `make store-mocks`.' GOPATH=$(shell go env GOPATH) $(shell go env GOPATH)/bin/mockery -dir store -all -output store/storetest/mocks -note 'Regenerate this file using `make store-mocks`.'
update-jira-plugin: ## Updates Jira plugin. update-jira-plugin: ## Updates Jira plugin.
go get github.com/mattermost/go-bindata/... go get github.com/jteeuwen/go-bindata/...
curl -s https://api.github.com/repos/mattermost/mattermost-plugin-jira/releases/latest | grep browser_download_url | grep darwin-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz curl -s https://api.github.com/repos/mattermost/mattermost-plugin-jira/releases/latest | grep browser_download_url | grep darwin-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz
$(shell go env GOPATH)/bin/go-bindata -pkg jira -o app/plugin/jira/plugin_darwin_amd64.go plugin.tar.gz $(shell go env GOPATH)/bin/go-bindata -pkg jira -o app/plugin/jira/plugin_darwin_amd64.go plugin.tar.gz
curl -s https://api.github.com/repos/mattermost/mattermost-plugin-jira/releases/latest | grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz curl -s https://api.github.com/repos/mattermost/mattermost-plugin-jira/releases/latest | grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz
@@ -287,7 +287,7 @@ update-jira-plugin: ## Updates Jira plugin.
gofmt -s -w ./app/plugin/jira gofmt -s -w ./app/plugin/jira
update-zoom-plugin: ## Updates Zoom plugin. update-zoom-plugin: ## Updates Zoom plugin.
go get github.com/mattermost/go-bindata/... go get github.com/jteeuwen/go-bindata/...
curl -s https://api.github.com/repos/mattermost/mattermost-plugin-zoom/releases/latest | grep browser_download_url | grep darwin-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz curl -s https://api.github.com/repos/mattermost/mattermost-plugin-zoom/releases/latest | grep browser_download_url | grep darwin-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz
$(shell go env GOPATH)/bin/go-bindata -pkg zoom -o app/plugin/zoom/plugin_darwin_amd64.go plugin.tar.gz $(shell go env GOPATH)/bin/go-bindata -pkg zoom -o app/plugin/zoom/plugin_darwin_amd64.go plugin.tar.gz
curl -s https://api.github.com/repos/mattermost/mattermost-plugin-zoom/releases/latest | grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz curl -s https://api.github.com/repos/mattermost/mattermost-plugin-zoom/releases/latest | grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4 | wget -qi - -O plugin.tar.gz

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

@@ -109,7 +109,7 @@ func Init(a *app.App, root *mux.Router) *API {
api.InitReaction() api.InitReaction()
// 404 on any api route before web.go has a chance to serve it // 404 on any api route before web.go has a chance to serve it
root.Handle("/api/{anything:.*}", http.HandlerFunc(api.Handle404)) root.Handle("/api/{anything:.*}", http.HandlerFunc(Handle404))
a.InitEmailBatching() a.InitEmailBatching()
@@ -120,10 +120,6 @@ func Init(a *app.App, root *mux.Router) *API {
return api return api
} }
func (api *API) Handle404(w http.ResponseWriter, r *http.Request) {
Handle404(api.App, w, r)
}
func ReturnStatusOK(w http.ResponseWriter) { func ReturnStatusOK(w http.ResponseWriter) {
m := make(map[string]string) m := make(map[string]string)
m[model.STATUS] = model.STATUS_OK m[model.STATUS] = model.STATUS_OK

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

@@ -105,11 +105,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
if testStore != nil { if testStore != nil {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
} }
serverErr := th.App.StartServer() th.App.StartServer()
if serverErr != nil {
panic(serverErr)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
api4.Init(th.App, th.App.Srv.Router, false) api4.Init(th.App, th.App.Srv.Router, false)
Init(th.App, th.App.Srv.Router) Init(th.App, th.App.Srv.Router)
@@ -118,10 +114,9 @@ func setupTestHelper(enterprise bool) *TestHelper {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
utils.SetIsLicensed(enterprise)
if enterprise { if enterprise {
th.App.SetLicense(model.NewTestLicense()) utils.License().Features.SetDefaults()
} else {
th.App.SetLicense(nil)
} }
return th return th

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

@@ -12,6 +12,7 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/store/sqlstore" "github.com/mattermost/mattermost-server/store/sqlstore"
"github.com/mattermost/mattermost-server/utils"
) )
func TestCreateChannel(t *testing.T) { func TestCreateChannel(t *testing.T) {
@@ -96,9 +97,23 @@ func TestCreateChannel(t *testing.T) {
t.Fatal("Should have errored out on direct channel type") t.Fatal("Should have errored out on direct channel type")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) th.App.SetDefaultRolesBasedOnConfig()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
channel2 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id} channel2 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel3 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel3 := &model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -115,6 +130,7 @@ func TestCreateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic2() th.LoginBasic2()
channel2.Name = "zz" + model.NewId() + "a" channel2.Name = "zz" + model.NewId() + "a"
@@ -144,6 +160,7 @@ func TestCreateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
channel2.Name = "zz" + model.NewId() + "a" channel2.Name = "zz" + model.NewId() + "a"
channel3.Name = "zz" + model.NewId() + "a" channel3.Name = "zz" + model.NewId() + "a"
@@ -164,7 +181,9 @@ func TestCreateChannel(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
channel4 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id} channel4 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_OPEN, TeamId: team.Id}
channel5 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel5 := model.Channel{DisplayName: "Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -177,6 +196,7 @@ func TestCreateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL })
th.App.SetDefaultRolesBasedOnConfig()
} }
func TestCreateDirectChannel(t *testing.T) { func TestCreateDirectChannel(t *testing.T) {
@@ -347,9 +367,23 @@ func TestUpdateChannel(t *testing.T) {
t.Fatal("should have failed - channel deleted") t.Fatal("should have failed - channel deleted")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel2 := th.CreateChannel(Client, team) channel2 := th.CreateChannel(Client, team)
channel3 := th.CreatePrivateChannel(Client, team) channel3 := th.CreatePrivateChannel(Client, team)
@@ -370,8 +404,14 @@ func TestUpdateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.MakeUserChannelUser(th.BasicUser, channel2) th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3) th.MakeUserChannelUser(th.BasicUser, channel3)
sqlstore.ClearChannelCaches() sqlstore.ClearChannelCaches()
@@ -407,9 +447,14 @@ func TestUpdateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannel(channel2); err == nil { if _, err := Client.UpdateChannel(channel2); err == nil {
t.Fatal("should have errored not team admin") t.Fatal("should have errored not team admin")
@@ -432,8 +477,14 @@ func TestUpdateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannel(channel2); err == nil { if _, err := Client.UpdateChannel(channel2); err == nil {
t.Fatal("should have errored not system admin") t.Fatal("should have errored not system admin")
@@ -452,7 +503,9 @@ func TestUpdateChannel(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannel(channel2); err != nil { if _, err := Client.UpdateChannel(channel2); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -565,9 +618,23 @@ func TestUpdateChannelHeader(t *testing.T) {
t.Fatal("should have errored non-channel member trying to update header") t.Fatal("should have errored non-channel member trying to update header")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
channel2 := th.CreateChannel(Client, team) channel2 := th.CreateChannel(Client, team)
@@ -592,8 +659,11 @@ func TestUpdateChannelHeader(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.MakeUserChannelUser(th.BasicUser, channel2) th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3) th.MakeUserChannelUser(th.BasicUser, channel3)
sqlstore.ClearChannelCaches() sqlstore.ClearChannelCaches()
@@ -618,8 +688,11 @@ func TestUpdateChannelHeader(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelHeader(data2); err == nil { if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not team admin") t.Fatal("should have errored not team admin")
@@ -642,8 +715,11 @@ func TestUpdateChannelHeader(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelHeader(data2); err == nil { if _, err := Client.UpdateChannelHeader(data2); err == nil {
t.Fatal("should have errored not system admin") t.Fatal("should have errored not system admin")
@@ -665,7 +741,9 @@ func TestUpdateChannelHeader(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil { if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -736,9 +814,23 @@ func TestUpdateChannelPurpose(t *testing.T) {
t.Fatal("should have errored non-channel member trying to update purpose") t.Fatal("should have errored non-channel member trying to update purpose")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
channel2 := th.CreateChannel(Client, team) channel2 := th.CreateChannel(Client, team)
@@ -763,8 +855,11 @@ func TestUpdateChannelPurpose(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.MakeUserChannelUser(th.BasicUser, channel2) th.MakeUserChannelUser(th.BasicUser, channel2)
th.MakeUserChannelUser(th.BasicUser, channel3) th.MakeUserChannelUser(th.BasicUser, channel3)
sqlstore.ClearChannelCaches() sqlstore.ClearChannelCaches()
@@ -789,8 +884,11 @@ func TestUpdateChannelPurpose(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelPurpose(data2); err == nil { if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not team admin") t.Fatal("should have errored not team admin")
@@ -813,8 +911,11 @@ func TestUpdateChannelPurpose(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.UpdateChannelPurpose(data2); err == nil { if _, err := Client.UpdateChannelPurpose(data2); err == nil {
t.Fatal("should have errored not system admin") t.Fatal("should have errored not system admin")
@@ -836,7 +937,9 @@ func TestUpdateChannelPurpose(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil { if _, err := SystemAdminClient.UpdateChannelHeader(data2); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@@ -1297,9 +1400,23 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal("should have failed - channel already deleted") t.Fatal("should have failed - channel already deleted")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin() th.LoginSystemAdmin()
th.LinkUserToTeam(th.BasicUser, team) th.LinkUserToTeam(th.BasicUser, team)
@@ -1321,10 +1438,16 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin() th.LoginSystemAdmin()
@@ -1375,11 +1498,16 @@ func TestDeleteChannel(t *testing.T) {
th.UpdateUserToNonTeamAdmin(th.BasicUser, team) th.UpdateUserToNonTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin() th.LoginSystemAdmin()
@@ -1409,10 +1537,16 @@ func TestDeleteChannel(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginSystemAdmin() th.LoginSystemAdmin()
@@ -1444,7 +1578,9 @@ func TestDeleteChannel(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
channel2 = th.CreateChannel(Client, team) channel2 = th.CreateChannel(Client, team)
channel3 = th.CreatePrivateChannel(Client, team) channel3 = th.CreatePrivateChannel(Client, team)
@@ -1459,6 +1595,10 @@ func TestDeleteChannel(t *testing.T) {
if _, err := Client.DeleteChannel(channel3.Id); err != nil { if _, err := Client.DeleteChannel(channel3.Id); err != nil {
t.Fatal(err) t.Fatal(err)
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_ALL })
th.App.SetDefaultRolesBasedOnConfig()
} }
func TestGetChannelStats(t *testing.T) { func TestGetChannelStats(t *testing.T) {
@@ -1535,9 +1675,16 @@ func TestAddChannelMember(t *testing.T) {
} }
// Test policy does not apply to TE. // Test policy does not apply to TE.
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel
})
}()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel) channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel)
@@ -1547,8 +1694,18 @@ func TestAddChannelMember(t *testing.T) {
} }
// Add a license // Add a license
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
// Check that a regular channel user can add other users. // Check that a regular channel user can add other users.
channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -1562,6 +1719,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel) channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel)
@@ -1572,7 +1733,10 @@ func TestAddChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, channel5) th.MakeUserChannelAdmin(user1, channel5)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.AddChannelMember(channel5.Id, user2.Id); err != nil { if _, err := Client.AddChannelMember(channel5.Id, user2.Id); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -1582,6 +1746,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel) channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel)
@@ -1592,7 +1760,10 @@ func TestAddChannelMember(t *testing.T) {
th.UpdateUserToTeamAdmin(user1, team) th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.AddChannelMember(channel6.Id, user2.Id); err != nil { if _, err := Client.AddChannelMember(channel6.Id, user2.Id); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -1602,6 +1773,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel) channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel)
@@ -1685,9 +1860,16 @@ func TestRemoveChannelMember(t *testing.T) {
th.LoginBasic() th.LoginBasic()
// Test policy does not apply to TE. // Test policy does not apply to TE.
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel
})
}()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel3 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel) channel3 = Client.Must(th.SystemAdminClient.CreateChannel(channel3)).Data.(*model.Channel)
@@ -1698,8 +1880,18 @@ func TestRemoveChannelMember(t *testing.T) {
} }
// Add a license // Add a license
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
// Check that a regular channel user can remove other users. // Check that a regular channel user can remove other users.
channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel4 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
@@ -1714,6 +1906,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel5 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel) channel5 = Client.Must(th.SystemAdminClient.CreateChannel(channel5)).Data.(*model.Channel)
@@ -1725,7 +1921,9 @@ func TestRemoveChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, channel5) th.MakeUserChannelAdmin(user1, channel5)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
if _, err := Client.RemoveChannelMember(channel5.Id, user2.Id); err != nil { if _, err := Client.RemoveChannelMember(channel5.Id, user2.Id); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -1735,6 +1933,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel6 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel) channel6 = Client.Must(th.SystemAdminClient.CreateChannel(channel6)).Data.(*model.Channel)
@@ -1746,7 +1948,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.UpdateUserToTeamAdmin(user1, team) th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.RemoveChannelMember(channel6.Id, user2.Id); err != nil { if _, err := Client.RemoveChannelMember(channel6.Id, user2.Id); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -1756,6 +1961,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id} channel7 := &model.Channel{DisplayName: "A Test API Name", Name: "zz" + model.NewId() + "a", Type: model.CHANNEL_PRIVATE, TeamId: team.Id}
channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel) channel7 = Client.Must(th.SystemAdminClient.CreateChannel(channel7)).Data.(*model.Channel)

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

@@ -229,7 +229,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if c.Err.StatusCode == http.StatusUnauthorized { if c.Err.StatusCode == http.StatusUnauthorized {
http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect) http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect)
} else { } else {
utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) utils.RenderWebError(c.Err, w, r)
} }
} }
@@ -434,7 +434,7 @@ func IsApiCall(r *http.Request) bool {
return strings.Index(r.URL.Path, "/api/") == 0 return strings.Index(r.URL.Path, "/api/") == 0
} }
func Handle404(a *app.App, w http.ResponseWriter, r *http.Request) { func Handle404(w http.ResponseWriter, r *http.Request) {
err := model.NewAppError("Handle404", "api.context.404.app_error", nil, "", http.StatusNotFound) err := model.NewAppError("Handle404", "api.context.404.app_error", nil, "", http.StatusNotFound)
l4g.Debug("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r)) l4g.Debug("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r))
@@ -444,7 +444,7 @@ func Handle404(a *app.App, w http.ResponseWriter, r *http.Request) {
err.DetailedError = "There doesn't appear to be an api call for the url='" + r.URL.Path + "'. Typo? are you missing a team_id or user_id as part of the url?" err.DetailedError = "There doesn't appear to be an api call for the url='" + r.URL.Path + "'. Typo? are you missing a team_id or user_id as part of the url?"
w.Write([]byte(err.ToJson())) w.Write([]byte(err.ToJson()))
} else { } else {
utils.RenderWebAppError(w, r, err, a.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
} }
} }

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

@@ -174,12 +174,12 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
if hash != correctHash { if hash != correctHash {
c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest)
utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect)
return return
} }
} else { } else {
c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest)
utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect)
return return
} }

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

@@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
) )
func (api *API) InitLicense() { func (api *API) InitLicense() {
@@ -82,7 +83,7 @@ func removeLicense(c *Context, w http.ResponseWriter, r *http.Request) {
func getClientLicenceConfig(c *Context, w http.ResponseWriter, r *http.Request) { func getClientLicenceConfig(c *Context, w http.ResponseWriter, r *http.Request) {
useSanitizedLicense := !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) useSanitizedLicense := !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM)
etag := c.App.GetClientLicenseEtag(useSanitizedLicense) etag := utils.GetClientLicenseEtag(useSanitizedLicense)
if c.HandleEtag(etag, "Get Client License Config", w, r) { if c.HandleEtag(etag, "Get Client License Config", w, r) {
return return
} }
@@ -90,9 +91,9 @@ func getClientLicenceConfig(c *Context, w http.ResponseWriter, r *http.Request)
var clientLicense map[string]string var clientLicense map[string]string
if useSanitizedLicense { if useSanitizedLicense {
clientLicense = c.App.ClientLicense() clientLicense = utils.ClientLicense()
} else { } else {
clientLicense = c.App.GetSanitizedClientLicense() clientLicense = utils.GetSanitizedClientLicense()
} }
w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Header().Set(model.HEADER_ETAG_SERVER, etag)

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

@@ -5,6 +5,8 @@ package api
import ( import (
"testing" "testing"
"github.com/mattermost/mattermost-server/utils"
) )
func TestGetLicenceConfig(t *testing.T) { func TestGetLicenceConfig(t *testing.T) {
@@ -30,7 +32,7 @@ func TestGetLicenceConfig(t *testing.T) {
t.Fatal("cache should be empty") t.Fatal("cache should be empty")
} }
th.App.SetClientLicense(map[string]string{"IsLicensed": "true"}) utils.SetClientLicense(map[string]string{"IsLicensed": "true"})
if cache_result, err := Client.GetClientLicenceConfig(result.Etag); err != nil { if cache_result, err := Client.GetClientLicenceConfig(result.Etag); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -38,7 +40,7 @@ func TestGetLicenceConfig(t *testing.T) {
t.Fatal("result should not be empty") t.Fatal("result should not be empty")
} }
th.App.SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "true"}) utils.SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "true"})
if cache_result, err := Client.GetClientLicenceConfig(result.Etag); err != nil { if cache_result, err := Client.GetClientLicenceConfig(result.Etag); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -46,6 +48,6 @@ func TestGetLicenceConfig(t *testing.T) {
t.Fatal("result should not be empty") t.Fatal("result should not be empty")
} }
th.App.SetClientLicense(map[string]string{"IsLicensed": "false"}) utils.SetClientLicense(map[string]string{"IsLicensed": "false"})
} }
} }

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

@@ -160,8 +160,20 @@ func TestCreatePost(t *testing.T) {
} }
} }
isLicensed := utils.IsLicensed()
license := utils.License()
disableTownSquareReadOnly := th.App.Config().TeamSettings.ExperimentalTownSquareIsReadOnly
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
th.App.SetLicense(model.NewTestLicense()) th.App.SetDefaultRolesBasedOnConfig()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
defaultChannel := store.Must(th.App.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, true)).(*model.Channel) defaultChannel := store.Must(th.App.Srv.Store.Channel().GetByName(team.Id, model.DEFAULT_CHANNEL, true)).(*model.Channel)
defaultPost := &model.Post{ defaultPost := &model.Post{
@@ -454,7 +466,16 @@ func TestUpdatePost(t *testing.T) {
} }
// Test licensed policy controls for edit post // Test licensed policy controls for edit post
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_NEVER }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_NEVER })
post4 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id} post4 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a", RootId: rpost1.Data.(*model.Post).Id}
@@ -945,6 +966,7 @@ func TestDeletePosts(t *testing.T) {
team1 := th.BasicTeam team1 := th.BasicTeam
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_ALL })
th.App.SetDefaultRolesBasedOnConfig()
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
post1 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"} post1 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}
@@ -999,7 +1021,15 @@ func TestDeletePosts(t *testing.T) {
} }
// Test licensed policy controls for delete post // Test licensed policy controls for delete post
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam) th.UpdateUserToTeamAdmin(th.BasicUser2, th.BasicTeam)
@@ -1014,6 +1044,7 @@ func TestDeletePosts(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_TEAM_ADMIN *cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
@@ -1038,6 +1069,7 @@ func TestDeletePosts(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_SYSTEM_ADMIN *cfg.ServiceSettings.RestrictPostDelete = model.PERMISSIONS_DELETE_POST_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
@@ -1056,7 +1088,9 @@ func TestDeletePosts(t *testing.T) {
} }
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
time.Sleep(10 * time.Millisecond) time.Sleep(10 * time.Millisecond)
post7 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"} post7 := &model.Post{ChannelId: channel1.Id, Message: "zz" + model.NewId() + "a"}

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

@@ -139,8 +139,20 @@ func TestAddUserToTeam(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Restore config/license at end of test case.
restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
// Set the config so that only team admins can add a user to a team. // Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
// Test without the EE license to see that the permission restriction is ignored. // Test without the EE license to see that the permission restriction is ignored.
user3 := th.CreateUser(th.BasicClient) user3 := th.CreateUser(th.BasicClient)
@@ -149,7 +161,10 @@ func TestAddUserToTeam(t *testing.T) {
} }
// Add an EE license. // Add an EE license.
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
// Check that a regular user can't add someone to the team. // Check that a regular user can't add someone to the team.
user4 := th.CreateUser(th.BasicClient) user4 := th.CreateUser(th.BasicClient)
@@ -160,8 +175,11 @@ func TestAddUserToTeam(t *testing.T) {
// Should work as team admin. // Should work as team admin.
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam) th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense())
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
user5 := th.CreateUser(th.BasicClient) user5 := th.CreateUser(th.BasicClient)
if _, err := th.BasicClient.AddUserToTeam(th.BasicTeam.Id, user5.Id); err != nil { if _, err := th.BasicClient.AddUserToTeam(th.BasicTeam.Id, user5.Id); err != nil {
@@ -170,6 +188,7 @@ func TestAddUserToTeam(t *testing.T) {
// Change permission level to System Admin // Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
// Should not work as team admin. // Should not work as team admin.
user6 := th.CreateUser(th.BasicClient) user6 := th.CreateUser(th.BasicClient)
@@ -546,7 +565,13 @@ func TestInviteMembers(t *testing.T) {
t.Fatal("Should have errored out on no invites to send") t.Fatal("Should have errored out on no invites to send")
} }
restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite })
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic2() th.LoginBasic2()
th.LinkUserToTeam(th.BasicUser2, team) th.LinkUserToTeam(th.BasicUser2, team)
@@ -555,7 +580,17 @@ func TestInviteMembers(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.InviteMembers(invites); err == nil { if _, err := Client.InviteMembers(invites); err == nil {
t.Fatal("should have errored not team admin and licensed") t.Fatal("should have errored not team admin and licensed")
@@ -571,6 +606,7 @@ func TestInviteMembers(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.InviteMembers(invites); err == nil { if _, err := Client.InviteMembers(invites); err == nil {
t.Fatal("should have errored not system admin and licensed") t.Fatal("should have errored not system admin and licensed")

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

@@ -299,9 +299,9 @@ func getInitialLoad(c *Context, w http.ResponseWriter, r *http.Request) {
il.ClientCfg = c.App.ClientConfig() il.ClientCfg = c.App.ClientConfig()
if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
il.LicenseCfg = c.App.ClientLicense() il.LicenseCfg = utils.ClientLicense()
} else { } else {
il.LicenseCfg = c.App.GetSanitizedClientLicense() il.LicenseCfg = utils.GetSanitizedClientLicense()
} }
w.Write([]byte(il.ToJson())) w.Write([]byte(il.ToJson()))

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

@@ -1889,7 +1889,17 @@ func TestUpdateMfa(t *testing.T) {
Client := th.BasicClient Client := th.BasicClient
th.App.SetLicense(nil) isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
}()
utils.SetIsLicensed(false)
utils.SetLicense(&model.License{Features: &model.Features{}})
if utils.License().Features.MFA == nil {
utils.License().Features.MFA = new(bool)
}
team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN} team := model.Team{DisplayName: "Name", Name: "z-z-" + model.NewId() + "a", Email: "test@nowhere.com", Type: model.TEAM_OPEN}
rteam, _ := Client.CreateTeam(&team) rteam, _ := Client.CreateTeam(&team)
@@ -1915,7 +1925,8 @@ func TestUpdateMfa(t *testing.T) {
t.Fatal("should have failed - not licensed") t.Fatal("should have failed - not licensed")
} }
th.App.SetLicense(model.NewTestLicense("mfa")) utils.SetIsLicensed(true)
*utils.License().Features.MFA = true
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true })
if _, err := Client.UpdateMfa(true, "123456"); err == nil { if _, err := Client.UpdateMfa(true, "123456"); err == nil {

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

@@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
) )
func TestCreateIncomingHook(t *testing.T) { func TestCreateIncomingHook(t *testing.T) {
@@ -92,6 +93,7 @@ func TestCreateIncomingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.CreateIncomingWebhook(hook); err != nil { if _, err := Client.CreateIncomingWebhook(hook); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -131,6 +133,7 @@ func TestUpdateIncomingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := createIncomingWebhook(channel1.Id, Client, t) hook := createIncomingWebhook(channel1.Id, Client, t)
@@ -214,6 +217,7 @@ func TestUpdateIncomingHook(t *testing.T) {
t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) { t.Run("OnlyAdminIntegrationsDisabled", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
t.Run("UpdateHookOfSameUser", func(t *testing.T) { t.Run("UpdateHookOfSameUser", func(t *testing.T) {
sameUserHook := &model.IncomingWebhook{ChannelId: channel1.Id, UserId: user2.Id} sameUserHook := &model.IncomingWebhook{ChannelId: channel1.Id, UserId: user2.Id}
@@ -236,6 +240,7 @@ func TestUpdateIncomingHook(t *testing.T) {
}) })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
Client.Logout() Client.Logout()
th.UpdateUserToTeamAdmin(user2, team) th.UpdateUserToTeamAdmin(user2, team)
@@ -319,6 +324,7 @@ func TestListIncomingHooks(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook1 := &model.IncomingWebhook{ChannelId: channel1.Id} hook1 := &model.IncomingWebhook{ChannelId: channel1.Id}
hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook) hook1 = Client.Must(Client.CreateIncomingWebhook(hook1)).Data.(*model.IncomingWebhook)
@@ -345,6 +351,7 @@ func TestListIncomingHooks(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.ListIncomingWebhooks(); err != nil { if _, err := Client.ListIncomingWebhooks(); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -369,6 +376,7 @@ func TestDeleteIncomingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := &model.IncomingWebhook{ChannelId: channel1.Id} hook := &model.IncomingWebhook{ChannelId: channel1.Id}
hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook) hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook)
@@ -402,6 +410,7 @@ func TestDeleteIncomingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil { if _, err := Client.DeleteIncomingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin") t.Fatal("should have failed - not creator or team admin")
@@ -438,6 +447,7 @@ func TestCreateOutgoingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}} hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
@@ -508,6 +518,7 @@ func TestCreateOutgoingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.CreateOutgoingWebhook(hook); err != nil { if _, err := Client.CreateOutgoingWebhook(hook); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -540,6 +551,7 @@ func TestListOutgoingHooks(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}} hook1 := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook) hook1 = Client.Must(Client.CreateOutgoingWebhook(hook1)).Data.(*model.OutgoingWebhook)
@@ -566,6 +578,7 @@ func TestListOutgoingHooks(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.ListOutgoingWebhooks(); err != nil { if _, err := Client.ListOutgoingWebhooks(); err != nil {
t.Fatal(err) t.Fatal(err)
@@ -596,6 +609,7 @@ func TestUpdateOutgoingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"cats"}, Client, t) hook := createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"cats"}, Client, t)
createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"dogs"}, Client, t) createOutgoingWebhook(channel1.Id, []string{"http://nowhere.com"}, []string{"dogs"}, Client, t)
@@ -669,6 +683,7 @@ func TestUpdateOutgoingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
hook2 := createOutgoingWebhook(channel1.Id, []string{"http://nowhereelse.com"}, []string{"dogs"}, Client, t) hook2 := createOutgoingWebhook(channel1.Id, []string{"http://nowhereelse.com"}, []string{"dogs"}, Client, t)
if _, err := Client.UpdateOutgoingWebhook(hook2); err != nil { if _, err := Client.UpdateOutgoingWebhook(hook2); err != nil {
@@ -676,6 +691,7 @@ func TestUpdateOutgoingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
Client.Logout() Client.Logout()
th.LinkUserToTeam(user3, team) th.LinkUserToTeam(user3, team)
@@ -763,6 +779,7 @@ func TestDeleteOutgoingHook(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}} hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook) hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -796,6 +813,7 @@ func TestDeleteOutgoingHook(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil { if _, err := Client.DeleteOutgoingWebhook(hook.Id); err == nil {
t.Fatal("should have failed - not creator or team admin") t.Fatal("should have failed - not creator or team admin")
@@ -830,6 +848,7 @@ func TestRegenOutgoingHookToken(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}} hook := &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook) hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -864,6 +883,7 @@ func TestRegenOutgoingHookToken(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}} hook = &model.OutgoingWebhook{ChannelId: channel1.Id, CallbackURLs: []string{"http://nowhere.com"}}
hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook) hook = Client.Must(Client.CreateOutgoingWebhook(hook)).Data.(*model.OutgoingWebhook)
@@ -897,6 +917,10 @@ func TestIncomingWebhooks(t *testing.T) {
user2 := th.CreateUser(Client) user2 := th.CreateUser(Client)
th.LinkUserToTeam(user2, team) th.LinkUserToTeam(user2, team)
enableIncomingHooks := th.App.Config().ServiceSettings.EnableIncomingWebhooks
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = enableIncomingHooks })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true })
hook := &model.IncomingWebhook{ChannelId: channel1.Id} hook := &model.IncomingWebhook{ChannelId: channel1.Id}
@@ -938,8 +962,20 @@ func TestIncomingWebhooks(t *testing.T) {
t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is false and it's not a read only channel") t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is false and it's not a read only channel")
} }
isLicensed := utils.IsLicensed()
license := utils.License()
disableTownSquareReadOnly := th.App.Config().TeamSettings.ExperimentalTownSquareIsReadOnly
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = disableTownSquareReadOnly })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true })
th.App.SetLicense(model.NewTestLicense()) th.App.SetDefaultRolesBasedOnConfig()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err == nil { if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err == nil {
t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel") t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel")

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

@@ -113,11 +113,7 @@ func setupTestHelper(enterprise bool) *TestHelper {
if testStore != nil { if testStore != nil {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
} }
serverErr := th.App.StartServer() th.App.StartServer()
if serverErr != nil {
panic(serverErr)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
Init(th.App, th.App.Srv.Router, true) Init(th.App, th.App.Srv.Router, true)
wsapi.Init(th.App, th.App.Srv.WebSocketRouter) wsapi.Init(th.App, th.App.Srv.WebSocketRouter)
@@ -125,10 +121,9 @@ func setupTestHelper(enterprise bool) *TestHelper {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
utils.SetIsLicensed(enterprise)
if enterprise { if enterprise {
th.App.SetLicense(model.NewTestLicense()) utils.License().Features.SetDefaults()
} else {
th.App.SetLicense(nil)
} }
th.Client = th.CreateClient() th.Client = th.CreateClient()
@@ -303,7 +298,8 @@ func (me *TestHelper) CreateUserWithClient(client *model.Client4) *model.User {
} }
utils.DisableDebugLogForTest() utils.DisableDebugLogForTest()
ruser, _ := client.CreateUser(user) ruser, r := client.CreateUser(user)
fmt.Println(r)
ruser.Password = "Password1" ruser.Password = "Password1"
store.Must(me.App.Srv.Store.User().VerifyEmail(ruser.Id)) store.Must(me.App.Srv.Store.User().VerifyEmail(ruser.Id))
utils.EnableDebugLogForTest() utils.EnableDebugLogForTest()

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

@@ -14,6 +14,7 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store/sqlstore" "github.com/mattermost/mattermost-server/store/sqlstore"
"github.com/mattermost/mattermost-server/utils"
) )
func TestCreateChannel(t *testing.T) { func TestCreateChannel(t *testing.T) {
@@ -81,9 +82,23 @@ func TestCreateChannel(t *testing.T) {
th.LoginBasic() th.LoginBasic()
// Check permissions with policy config changes // Check permissions with policy config changes
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelCreation
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelCreation
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
channel.Name = GenerateTestChannelName() channel.Name = GenerateTestChannelName()
_, resp = Client.CreateChannel(channel) _, resp = Client.CreateChannel(channel)
@@ -95,8 +110,11 @@ func TestCreateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.CreateChannel(channel) _, resp = Client.CreateChannel(channel)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -124,8 +142,11 @@ func TestCreateChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelCreation = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
@@ -152,7 +173,9 @@ func TestCreateChannel(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// Check that if unlicensed the policy restriction is not enforced. // Check that if unlicensed the policy restriction is not enforced.
th.App.SetLicense(nil) utils.SetIsLicensed(false)
utils.SetLicense(nil)
th.App.SetDefaultRolesBasedOnConfig()
channel.Name = GenerateTestChannelName() channel.Name = GenerateTestChannelName()
_, resp = Client.CreateChannel(channel) _, resp = Client.CreateChannel(channel)
@@ -864,9 +887,23 @@ func TestDeleteChannel(t *testing.T) {
th.InitBasic().InitSystemAdmin() th.InitBasic().InitSystemAdmin()
isLicensed := utils.IsLicensed()
license := utils.License()
restrictPublicChannel := *th.App.Config().TeamSettings.RestrictPublicChannelManagement
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManagement
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = restrictPublicChannel })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = restrictPrivateChannel })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPublicChannelManagement = model.PERMISSIONS_ALL })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManagement = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client = th.Client Client = th.Client
team = th.BasicTeam team = th.BasicTeam
@@ -889,8 +926,11 @@ func TestDeleteChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
// channels created by SystemAdmin // channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
@@ -927,7 +967,9 @@ func TestDeleteChannel(t *testing.T) {
// successful delete by team admin // successful delete by team admin
th.UpdateUserToTeamAdmin(user, team) th.UpdateUserToTeamAdmin(user, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
_, resp = Client.DeleteChannel(publicChannel6.Id) _, resp = Client.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -937,11 +979,16 @@ func TestDeleteChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_TEAM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
th.UpdateUserToNonTeamAdmin(user, team) th.UpdateUserToNonTeamAdmin(user, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
// channels created by SystemAdmin // channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
@@ -971,7 +1018,9 @@ func TestDeleteChannel(t *testing.T) {
// successful delete by team admin // successful delete by team admin
th.UpdateUserToTeamAdmin(th.BasicUser, team) th.UpdateUserToTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
_, resp = Client.DeleteChannel(publicChannel6.Id) _, resp = Client.DeleteChannel(publicChannel6.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -981,8 +1030,11 @@ func TestDeleteChannel(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPublicChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
})
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelDeletion = model.PERMISSIONS_SYSTEM_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
// channels created by SystemAdmin // channels created by SystemAdmin
publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN) publicChannel6 = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_OPEN)
@@ -1012,7 +1064,9 @@ func TestDeleteChannel(t *testing.T) {
// cannot delete by team admin // cannot delete by team admin
th.UpdateUserToTeamAdmin(th.BasicUser, team) th.UpdateUserToTeamAdmin(th.BasicUser, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
_, resp = Client.DeleteChannel(publicChannel6.Id) _, resp = Client.DeleteChannel(publicChannel6.Id)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -1769,9 +1823,16 @@ func TestAddChannelMember(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// Test policy does not apply to TE. // Test policy does not apply to TE.
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel
})
}()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user2.Username, user2.Password) Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel() privateChannel = th.CreatePrivateChannel()
@@ -1785,8 +1846,18 @@ func TestAddChannelMember(t *testing.T) {
Client.Logout() Client.Logout()
// Add a license // Add a license
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
// Check that a regular channel user can add other users. // Check that a regular channel user can add other users.
Client.Login(user2.Username, user2.Password) Client.Login(user2.Username, user2.Password)
@@ -1804,6 +1875,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user2.Username, user2.Password) Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel() privateChannel = th.CreatePrivateChannel()
@@ -1818,7 +1893,10 @@ func TestAddChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user, privateChannel) th.MakeUserChannelAdmin(user, privateChannel)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user.Username, user.Password) Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id) _, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
@@ -1829,6 +1907,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user2.Username, user2.Password) Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel() privateChannel = th.CreatePrivateChannel()
@@ -1843,7 +1925,10 @@ func TestAddChannelMember(t *testing.T) {
th.UpdateUserToTeamAdmin(user, team) th.UpdateUserToTeamAdmin(user, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user.Username, user.Password) Client.Login(user.Username, user.Password)
_, resp = Client.AddChannelMember(privateChannel.Id, user3.Id) _, resp = Client.AddChannelMember(privateChannel.Id, user3.Id)
@@ -1854,6 +1939,10 @@ func TestAddChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
Client.Login(user2.Username, user2.Password) Client.Login(user2.Username, user2.Password)
privateChannel = th.CreatePrivateChannel() privateChannel = th.CreatePrivateChannel()
@@ -1930,9 +2019,16 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
// Test policy does not apply to TE. // Test policy does not apply to TE.
restrictPrivateChannel := *th.App.Config().TeamSettings.RestrictPrivateChannelManageMembers
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = restrictPrivateChannel
})
}()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
th.App.SetDefaultRolesBasedOnConfig()
privateChannel := th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) privateChannel := th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
@@ -1944,8 +2040,18 @@ func TestRemoveChannelMember(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// Add a license // Add a license
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
// Check that a regular channel user can remove other users. // Check that a regular channel user can remove other users.
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
@@ -1961,6 +2067,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_CHANNEL_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
@@ -1973,7 +2083,9 @@ func TestRemoveChannelMember(t *testing.T) {
th.MakeUserChannelAdmin(user1, privateChannel) th.MakeUserChannelAdmin(user1, privateChannel)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -1982,6 +2094,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_TEAM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)
@@ -1994,7 +2110,9 @@ func TestRemoveChannelMember(t *testing.T) {
th.UpdateUserToTeamAdmin(user1, team) th.UpdateUserToTeamAdmin(user1, team)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
_, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id) _, resp = Client.RemoveUserFromChannel(privateChannel.Id, user2.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -2003,6 +2121,10 @@ func TestRemoveChannelMember(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN *cfg.TeamSettings.RestrictPrivateChannelManageMembers = model.PERMISSIONS_SYSTEM_ADMIN
}) })
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE) privateChannel = th.CreateChannelWithClient(th.SystemAdminClient, model.CHANNEL_PRIVATE)
_, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id) _, resp = th.SystemAdminClient.AddChannelMember(privateChannel.Id, user1.Id)

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

@@ -281,13 +281,13 @@ func getPublicFile(c *Context, w http.ResponseWriter, r *http.Request) {
if len(hash) == 0 { if len(hash) == 0 {
c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest)
utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect)
return return
} }
if hash != app.GeneratePublicLinkHash(info.Id, *c.App.Config().FileSettings.PublicLinkSalt) { if hash != app.GeneratePublicLinkHash(info.Id, *c.App.Config().FileSettings.PublicLinkSalt) {
c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest) c.Err = model.NewAppError("getPublicFile", "api.file.get_file.public_invalid.app_error", nil, "", http.StatusBadRequest)
utils.RenderWebAppError(w, r, c.Err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+utils.T(c.Err.Message), http.StatusTemporaryRedirect)
return return
} }

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

@@ -313,7 +313,7 @@ func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) {
func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) { func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
if !c.App.Config().ServiceSettings.EnableOAuthServiceProvider { if !c.App.Config().ServiceSettings.EnableOAuthServiceProvider {
err := model.NewAppError("authorizeOAuth", "api.oauth.authorize_oauth.disabled.app_error", nil, "", http.StatusNotImplemented) err := model.NewAppError("authorizeOAuth", "api.oauth.authorize_oauth.disabled.app_error", nil, "", http.StatusNotImplemented)
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
return return
} }
@@ -326,13 +326,13 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if err := authRequest.IsValid(); err != nil { if err := authRequest.IsValid(); err != nil {
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
return return
} }
oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId) oauthApp, err := c.App.GetOAuthApp(authRequest.ClientId)
if err != nil { if err != nil {
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
return return
} }
@@ -343,8 +343,7 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !oauthApp.IsValidRedirectURL(authRequest.RedirectUri) { if !oauthApp.IsValidRedirectURL(authRequest.RedirectUri) {
err := model.NewAppError("authorizeOAuthPage", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest) utils.RenderWebError(model.NewAppError("authorizeOAuthPage", "api.oauth.allow_oauth.redirect_callback.app_error", nil, "", http.StatusBadRequest), w, r)
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey())
return return
} }
@@ -361,7 +360,7 @@ func authorizeOAuthPage(c *Context, w http.ResponseWriter, r *http.Request) {
redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest) redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest)
if err != nil { if err != nil {
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
return return
} }
@@ -442,10 +441,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code") code := r.URL.Query().Get("code")
if len(code) == 0 { if len(code) == 0 {
utils.RenderWebError(w, r, http.StatusTemporaryRedirect, url.Values{ http.Redirect(w, r, c.GetSiteURLHeader()+"/error?type=oauth_missing_code&service="+strings.Title(service), http.StatusTemporaryRedirect)
"type": []string{"oauth_missing_code"},
"service": []string{strings.Title(service)},
}, c.App.AsymmetricSigningKey())
return return
} }
@@ -466,7 +462,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
if action == model.OAUTH_ACTION_MOBILE { if action == model.OAUTH_ACTION_MOBILE {
w.Write([]byte(err.ToJson())) w.Write([]byte(err.ToJson()))
} else { } else {
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(err.Message), http.StatusTemporaryRedirect)
} }
return return
} }
@@ -478,7 +474,7 @@ func completeOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
if action == model.OAUTH_ACTION_MOBILE { if action == model.OAUTH_ACTION_MOBILE {
w.Write([]byte(err.ToJson())) w.Write([]byte(err.ToJson()))
} else { } else {
utils.RenderWebAppError(w, r, err, c.App.AsymmetricSigningKey()) http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(err.Message), http.StatusTemporaryRedirect)
} }
return return
} }
@@ -563,9 +559,7 @@ func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) {
} }
if !c.App.Config().TeamSettings.EnableUserCreation { if !c.App.Config().TeamSettings.EnableUserCreation {
utils.RenderWebError(w, r, http.StatusBadRequest, url.Values{ http.Redirect(w, r, c.GetSiteURLHeader()+"/error?message="+url.QueryEscape(utils.T("api.oauth.singup_with_oauth.disabled.app_error")), http.StatusTemporaryRedirect)
"message": []string{utils.T("api.oauth.singup_with_oauth.disabled.app_error")},
}, c.App.AsymmetricSigningKey())
return return
} }

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

@@ -18,7 +18,14 @@ func TestCreateOAuthApp(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}, IsTrusted: true} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}, IsTrusted: true}
@@ -35,10 +42,12 @@ func TestCreateOAuthApp(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.CreateOAuthApp(oapp) _, resp = Client.CreateOAuthApp(oapp)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
rapp, resp = Client.CreateOAuthApp(oapp) rapp, resp = Client.CreateOAuthApp(oapp)
CheckNoError(t, resp) CheckNoError(t, resp)
CheckCreatedStatus(t, resp) CheckCreatedStatus(t, resp)
@@ -77,7 +86,14 @@ func TestUpdateOAuthApp(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{ oapp := &model.OAuthApp{
Name: "oapp", Name: "oapp",
@@ -156,6 +172,7 @@ func TestUpdateOAuthApp(t *testing.T) {
th.LoginBasic() th.LoginBasic()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.UpdateOAuthApp(oapp) _, resp = Client.UpdateOAuthApp(oapp)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -182,8 +199,15 @@ func TestGetOAuthApps(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -227,6 +251,7 @@ func TestGetOAuthApps(t *testing.T) {
} }
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.GetOAuthApps(0, 1000) _, resp = Client.GetOAuthApps(0, 1000)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -247,8 +272,15 @@ func TestGetOAuthApp(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -288,6 +320,7 @@ func TestGetOAuthApp(t *testing.T) {
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.GetOAuthApp(rapp2.Id) _, resp = Client.GetOAuthApp(rapp2.Id)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -314,8 +347,15 @@ func TestGetOAuthAppInfo(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -355,6 +395,7 @@ func TestGetOAuthAppInfo(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.GetOAuthAppInfo(rapp2.Id) _, resp = Client.GetOAuthAppInfo(rapp2.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
@@ -381,8 +422,15 @@ func TestDeleteOAuthApp(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -417,6 +465,7 @@ func TestDeleteOAuthApp(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.DeleteOAuthApp(rapp.Id) _, resp = Client.DeleteOAuthApp(rapp.Id)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -441,8 +490,15 @@ func TestRegenerateOAuthAppSecret(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
adminOnly := *th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = adminOnly })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}
@@ -481,6 +537,7 @@ func TestRegenerateOAuthAppSecret(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = false })
th.App.SetDefaultRolesBasedOnConfig()
_, resp = Client.RegenerateOAuthAppSecret(rapp.Id) _, resp = Client.RegenerateOAuthAppSecret(rapp.Id)
CheckForbiddenStatus(t, resp) CheckForbiddenStatus(t, resp)
@@ -565,7 +622,12 @@ func TestAuthorizeOAuthApp(t *testing.T) {
Client := th.Client Client := th.Client
AdminClient := th.SystemAdminClient AdminClient := th.SystemAdminClient
enableOAuth := th.App.Config().ServiceSettings.EnableOAuthServiceProvider
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = enableOAuth })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOAuthServiceProvider = true })
th.App.SetDefaultRolesBasedOnConfig()
oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}} oapp := &model.OAuthApp{Name: GenerateTestAppName(), Homepage: "https://nowhere.com", Description: "test", CallbackUrls: []string{"https://nowhere.com"}}

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

@@ -17,6 +17,7 @@ import (
"github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
) )
func TestCreatePost(t *testing.T) { func TestCreatePost(t *testing.T) {
@@ -129,8 +130,20 @@ func testCreatePostWithOutgoingHook(
team := th.BasicTeam team := th.BasicTeam
channel := th.BasicChannel channel := th.BasicChannel
enableOutgoingHooks := th.App.Config().ServiceSettings.EnableOutgoingWebhooks
enableAdminOnlyHooks := th.App.Config().ServiceSettings.EnableOnlyAdminIntegrations
allowedInternalConnections := *th.App.Config().ServiceSettings.AllowedUntrustedInternalConnections
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = enableOutgoingHooks })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOnlyAdminIntegrations = enableAdminOnlyHooks })
th.App.SetDefaultRolesBasedOnConfig()
th.App.UpdateConfig(func(cfg *model.Config) {
cfg.ServiceSettings.AllowedUntrustedInternalConnections = &allowedInternalConnections
})
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableOutgoingWebhooks = true })
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableOnlyAdminIntegrations = true })
th.App.SetDefaultRolesBasedOnConfig()
th.App.UpdateConfig(func(cfg *model.Config) { th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1" *cfg.ServiceSettings.AllowedUntrustedInternalConnections = "localhost 127.0.0.1"
}) })
@@ -476,8 +489,21 @@ func TestUpdatePost(t *testing.T) {
Client := th.Client Client := th.Client
channel := th.BasicChannel channel := th.BasicChannel
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
allowEditPost := *th.App.Config().ServiceSettings.AllowEditPost
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = allowEditPost })
th.App.SetDefaultRolesBasedOnConfig()
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS })
th.App.SetDefaultRolesBasedOnConfig()
post := &model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a"} post := &model.Post{ChannelId: channel.Id, Message: "zz" + model.NewId() + "a"}
rpost, resp := Client.CreatePost(post) rpost, resp := Client.CreatePost(post)
@@ -548,8 +574,21 @@ func TestPatchPost(t *testing.T) {
Client := th.Client Client := th.Client
channel := th.BasicChannel channel := th.BasicChannel
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
allowEditPost := *th.App.Config().ServiceSettings.AllowEditPost
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = allowEditPost })
th.App.SetDefaultRolesBasedOnConfig()
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.AllowEditPost = model.ALLOW_EDIT_POST_ALWAYS })
th.App.SetDefaultRolesBasedOnConfig()
post := &model.Post{ post := &model.Post{
ChannelId: channel.Id, ChannelId: channel.Id,

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

@@ -266,7 +266,7 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) {
return return
} }
etag := c.App.GetClientLicenseEtag(true) etag := utils.GetClientLicenseEtag(true)
if c.HandleEtag(etag, "Get Client License", w, r) { if c.HandleEtag(etag, "Get Client License", w, r) {
return return
} }
@@ -274,9 +274,9 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) {
var clientLicense map[string]string var clientLicense map[string]string
if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) {
clientLicense = c.App.ClientLicense() clientLicense = utils.ClientLicense()
} else { } else {
clientLicense = c.App.GetSanitizedClientLicense() clientLicense = utils.GetSanitizedClientLicense()
} }
w.Header().Set(model.HEADER_ETAG_SERVER, etag) w.Header().Set(model.HEADER_ETAG_SERVER, etag)

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

@@ -68,7 +68,13 @@ func TestCreateTeam(t *testing.T) {
CheckUnauthorizedStatus(t, resp) CheckUnauthorizedStatus(t, resp)
// Update permission // Update permission
enableTeamCreation := th.App.Config().TeamSettings.EnableTeamCreation
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = enableTeamCreation })
th.App.SetDefaultRolesBasedOnConfig()
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = false }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.EnableTeamCreation = false })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
_, resp = Client.CreateTeam(team) _, resp = Client.CreateTeam(team)
@@ -1286,8 +1292,20 @@ func TestAddTeamMember(t *testing.T) {
Client.Logout() Client.Logout()
// Check effects of config and license changes.
restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
// Set the config so that only team admins can add a user to a team. // Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Test without the EE license to see that the permission restriction is ignored. // Test without the EE license to see that the permission restriction is ignored.
@@ -1295,7 +1313,10 @@ func TestAddTeamMember(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// Add an EE license. // Add an EE license.
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Check that a regular user can't add someone to the team. // Check that a regular user can't add someone to the team.
@@ -1306,7 +1327,10 @@ func TestAddTeamMember(t *testing.T) {
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam) th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Should work as a team admin. // Should work as a team admin.
@@ -1315,6 +1339,7 @@ func TestAddTeamMember(t *testing.T) {
// Change permission level to System Admin // Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
// Should not work as team admin. // Should not work as team admin.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id) _, resp = Client.AddTeamMember(team.Id, otherUser.Id)
@@ -1328,13 +1353,21 @@ func TestAddTeamMember(t *testing.T) {
th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam) th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Should work as a regular user. // Should work as a regular user.
_, resp = Client.AddTeamMember(team.Id, otherUser.Id) _, resp = Client.AddTeamMember(team.Id, otherUser.Id)
CheckNoError(t, resp) CheckNoError(t, resp)
// Reset config and license.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// by hash and data // by hash and data
@@ -1474,8 +1507,20 @@ func TestAddTeamMembers(t *testing.T) {
Client.Logout() Client.Logout()
// Check effects of config and license changes.
restrictTeamInvite := *th.App.Config().TeamSettings.RestrictTeamInvite
isLicensed := utils.IsLicensed()
license := utils.License()
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = restrictTeamInvite })
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.SetDefaultRolesBasedOnConfig()
}()
// Set the config so that only team admins can add a user to a team. // Set the config so that only team admins can add a user to a team.
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Test without the EE license to see that the permission restriction is ignored. // Test without the EE license to see that the permission restriction is ignored.
@@ -1483,7 +1528,10 @@ func TestAddTeamMembers(t *testing.T) {
CheckNoError(t, resp) CheckNoError(t, resp)
// Add an EE license. // Add an EE license.
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Check that a regular user can't add someone to the team. // Check that a regular user can't add someone to the team.
@@ -1494,7 +1542,10 @@ func TestAddTeamMembers(t *testing.T) {
th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam) th.UpdateUserToTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_TEAM_ADMIN })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Should work as a team admin. // Should work as a team admin.
@@ -1503,6 +1554,7 @@ func TestAddTeamMembers(t *testing.T) {
// Change permission level to System Admin // Change permission level to System Admin
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_SYSTEM_ADMIN })
th.App.SetDefaultRolesBasedOnConfig()
// Should not work as team admin. // Should not work as team admin.
_, resp = Client.AddTeamMembers(team.Id, userList) _, resp = Client.AddTeamMembers(team.Id, userList)
@@ -1516,7 +1568,10 @@ func TestAddTeamMembers(t *testing.T) {
th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam) th.UpdateUserToNonTeamAdmin(th.BasicUser, th.BasicTeam)
th.App.InvalidateAllCaches() th.App.InvalidateAllCaches()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.RestrictTeamInvite = model.PERMISSIONS_ALL })
th.App.SetLicense(model.NewTestLicense()) utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.SetDefaultRolesBasedOnConfig()
th.LoginBasic() th.LoginBasic()
// Should work as a regular user. // Should work as a regular user.
@@ -1875,6 +1930,10 @@ func TestInviteUsersToTeam(t *testing.T) {
} }
} }
restrictCreationToDomains := th.App.Config().TeamSettings.RestrictCreationToDomains
defer func() {
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = restrictCreationToDomains })
}()
th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = "@example.com" }) th.App.UpdateConfig(func(cfg *model.Config) { cfg.TeamSettings.RestrictCreationToDomains = "@example.com" })
err := th.App.InviteNewUsersToTeam(emailList, th.BasicTeam.Id, th.BasicUser.Id) err := th.App.InviteNewUsersToTeam(emailList, th.BasicTeam.Id, th.BasicUser.Id)

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

@@ -1566,7 +1566,18 @@ func TestUpdateUserMfa(t *testing.T) {
defer th.TearDown() defer th.TearDown()
Client := th.Client Client := th.Client
th.App.SetLicense(model.NewTestLicense("mfa")) isLicensed := utils.IsLicensed()
license := utils.License()
enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa })
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
*utils.License().Features.MFA = true
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true })
session, _ := th.App.GetSession(Client.AuthToken) session, _ := th.App.GetSession(Client.AuthToken)
@@ -1601,7 +1612,18 @@ func TestCheckUserMfa(t *testing.T) {
t.Fatal("should be false - mfa not active") t.Fatal("should be false - mfa not active")
} }
th.App.SetLicense(model.NewTestLicense("mfa")) isLicensed := utils.IsLicensed()
license := utils.License()
enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa })
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
*utils.License().Features.MFA = true
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true })
th.LoginBasic() th.LoginBasic()
@@ -1637,7 +1659,18 @@ func TestGenerateMfaSecret(t *testing.T) {
_, resp = Client.GenerateMfaSecret("junk") _, resp = Client.GenerateMfaSecret("junk")
CheckBadRequestStatus(t, resp) CheckBadRequestStatus(t, resp)
th.App.SetLicense(model.NewTestLicense("mfa")) isLicensed := utils.IsLicensed()
license := utils.License()
enableMfa := *th.App.Config().ServiceSettings.EnableMultifactorAuthentication
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = enableMfa })
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
*utils.License().Features.MFA = true
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.EnableMultifactorAuthentication = true })
_, resp = Client.GenerateMfaSecret(model.NewId()) _, resp = Client.GenerateMfaSecret(model.NewId())
@@ -2154,7 +2187,19 @@ func TestSwitchAccount(t *testing.T) {
t.Fatal("bad link") t.Fatal("bad link")
} }
th.App.SetLicense(model.NewTestLicense()) isLicensed := utils.IsLicensed()
license := utils.License()
enableAuthenticationTransfer := *th.App.Config().ServiceSettings.ExperimentalEnableAuthenticationTransfer
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = enableAuthenticationTransfer
})
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer = false })
sr = &model.SwitchRequest{ sr = &model.SwitchRequest{

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

@@ -237,8 +237,7 @@ func (a *App) TestEmail(userId string, cfg *model.Config) *model.AppError {
return err return err
} else { } else {
T := utils.GetUserTranslations(user.Locale) T := utils.GetUserTranslations(user.Locale)
license := a.License() if err := utils.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg); err != nil {
if err := utils.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg, license != nil && *license.Features.Compliance); err != nil {
return err return err
} }
} }

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

@@ -4,7 +4,6 @@
package app package app
import ( import (
"crypto/ecdsa"
"html/template" "html/template"
"net" "net"
"net/http" "net/http"
@@ -59,20 +58,15 @@ type App struct {
configFile string configFile string
configListeners map[string]func(*model.Config, *model.Config) configListeners map[string]func(*model.Config, *model.Config)
licenseValue atomic.Value
clientLicenseValue atomic.Value
licenseListeners map[string]func()
newStore func() store.Store newStore func() store.Store
htmlTemplateWatcher *utils.HTMLTemplateWatcher htmlTemplateWatcher *utils.HTMLTemplateWatcher
sessionCache *utils.Cache sessionCache *utils.Cache
roles map[string]*model.Role roles map[string]*model.Role
configListenerId string configListenerId string
licenseListenerId string licenseListenerId string
disableConfigWatch bool disableConfigWatch bool
configWatcher *utils.ConfigWatcher configWatcher *utils.ConfigWatcher
asymmetricSigningKey *ecdsa.PrivateKey
pluginCommands []*PluginCommand pluginCommands []*PluginCommand
pluginCommandsLock sync.RWMutex pluginCommandsLock sync.RWMutex
@@ -86,7 +80,7 @@ var appCount = 0
// New creates a new App. You must call Shutdown when you're done with it. // New creates a new App. You must call Shutdown when you're done with it.
// XXX: For now, only one at a time is allowed as some resources are still shared. // XXX: For now, only one at a time is allowed as some resources are still shared.
func New(options ...Option) (outApp *App, outErr error) { func New(options ...Option) (*App, error) {
appCount++ appCount++
if appCount > 1 { if appCount > 1 {
panic("Only one App should exist at a time. Did you forget to call Shutdown()?") panic("Only one App should exist at a time. Did you forget to call Shutdown()?")
@@ -97,17 +91,11 @@ func New(options ...Option) (outApp *App, outErr error) {
Srv: &Server{ Srv: &Server{
Router: mux.NewRouter(), Router: mux.NewRouter(),
}, },
sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE), sessionCache: utils.NewLru(model.SESSION_CACHE_SIZE),
configFile: "config.json", configFile: "config.json",
configListeners: make(map[string]func(*model.Config, *model.Config)), configListeners: make(map[string]func(*model.Config, *model.Config)),
clientConfig: make(map[string]string), clientConfig: make(map[string]string),
licenseListeners: map[string]func(){},
} }
defer func() {
if outErr != nil {
app.Shutdown()
}
}()
for _, option := range options { for _, option := range options {
option(app) option(app)
@@ -130,9 +118,9 @@ func New(options ...Option) (outApp *App, outErr error) {
app.configListenerId = app.AddConfigListener(func(_, _ *model.Config) { app.configListenerId = app.AddConfigListener(func(_, _ *model.Config) {
app.configOrLicenseListener() app.configOrLicenseListener()
}) })
app.licenseListenerId = app.AddLicenseListener(app.configOrLicenseListener) app.licenseListenerId = utils.AddLicenseListener(app.configOrLicenseListener)
app.regenerateClientConfig() app.regenerateClientConfig()
app.setDefaultRolesBasedOnConfig() app.SetDefaultRolesBasedOnConfig()
l4g.Info(utils.T("api.server.new_server.init.info")) l4g.Info(utils.T("api.server.new_server.init.info"))
@@ -151,10 +139,6 @@ func New(options ...Option) (outApp *App, outErr error) {
} }
app.Srv.Store = app.newStore() app.Srv.Store = app.newStore()
if err := app.ensureAsymmetricSigningKey(); err != nil {
return nil, errors.Wrapf(err, "unable to ensure asymmetric signing key")
}
app.initJobs() app.initJobs()
app.initBuiltInPlugins() app.initBuiltInPlugins()
@@ -173,7 +157,7 @@ func New(options ...Option) (outApp *App, outErr error) {
func (a *App) configOrLicenseListener() { func (a *App) configOrLicenseListener() {
a.regenerateClientConfig() a.regenerateClientConfig()
a.setDefaultRolesBasedOnConfig() a.SetDefaultRolesBasedOnConfig()
} }
func (a *App) Shutdown() { func (a *App) Shutdown() {
@@ -187,9 +171,7 @@ func (a *App) Shutdown() {
a.ShutDownPlugins() a.ShutDownPlugins()
a.WaitForGoroutines() a.WaitForGoroutines()
if a.Srv.Store != nil { a.Srv.Store.Close()
a.Srv.Store.Close()
}
a.Srv = nil a.Srv = nil
if a.htmlTemplateWatcher != nil { if a.htmlTemplateWatcher != nil {
@@ -197,7 +179,7 @@ func (a *App) Shutdown() {
} }
a.RemoveConfigListener(a.configListenerId) a.RemoveConfigListener(a.configListenerId)
a.RemoveLicenseListener(a.licenseListenerId) utils.RemoveLicenseListener(a.licenseListenerId)
l4g.Info(utils.T("api.server.stop_server.stopped.info")) l4g.Info(utils.T("api.server.stop_server.stopped.info"))
a.DisableConfigWatch() a.DisableConfigWatch()
@@ -466,5 +448,5 @@ func (a *App) Handle404(w http.ResponseWriter, r *http.Request) {
l4g.Debug("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r)) l4g.Debug("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r))
utils.RenderWebAppError(w, r, err, a.AsymmetricSigningKey()) utils.RenderWebError(err, w, r)
} }

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

@@ -51,8 +51,7 @@ func TestAppRace(t *testing.T) {
a, err := New() a, err := New()
require.NoError(t, err) require.NoError(t, err)
a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
serverErr := a.StartServer() a.StartServer()
require.NoError(t, serverErr)
a.Shutdown() a.Shutdown()
} }
} }

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

@@ -96,20 +96,15 @@ func setupTestHelper(enterprise bool) *TestHelper {
if testStore != nil { if testStore != nil {
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
} }
serverErr := th.App.StartServer() th.App.StartServer()
if serverErr != nil {
panic(serverErr)
}
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
th.App.Srv.Store.MarkSystemRanUnitTests() th.App.Srv.Store.MarkSystemRanUnitTests()
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
utils.SetIsLicensed(enterprise)
if enterprise { if enterprise {
th.App.SetLicense(model.NewTestLicense()) utils.License().Features.SetDefaults()
} else {
th.App.SetLicense(nil)
} }
return th return th

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

@@ -1359,7 +1359,7 @@ func (a *App) PermanentDeleteChannel(channel *model.Channel) *model.AppError {
// This function is intended for use from the CLI. It is not robust against people joining the channel while the move // This function is intended for use from the CLI. It is not robust against people joining the channel while the move
// is in progress, and therefore should not be used from the API without first fixing this potential race condition. // is in progress, and therefore should not be used from the API without first fixing this potential race condition.
func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.User) *model.AppError { func (a *App) MoveChannel(team *model.Team, channel *model.Channel) *model.AppError {
// Check that all channel members are in the destination team. // Check that all channel members are in the destination team.
if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil { if channelMembers, err := a.GetChannelMembersPage(channel.Id, 0, 10000000); err != nil {
return err return err
@@ -1378,37 +1378,11 @@ func (a *App) MoveChannel(team *model.Team, channel *model.Channel, user *model.
} }
} }
// keep instance of the previous team // Change the Team ID of the channel.
var previousTeam *model.Team
if result := <-a.Srv.Store.Team().Get(channel.TeamId); result.Err != nil {
return result.Err
} else {
previousTeam = result.Data.(*model.Team)
}
channel.TeamId = team.Id channel.TeamId = team.Id
if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil { if result := <-a.Srv.Store.Channel().Update(channel); result.Err != nil {
return result.Err return result.Err
} }
a.postChannelMoveMessage(user, channel, previousTeam)
return nil
}
func (a *App) postChannelMoveMessage(user *model.User, channel *model.Channel, previousTeam *model.Team) *model.AppError {
post := &model.Post{
ChannelId: channel.Id,
Message: fmt.Sprintf(utils.T("api.team.move_channel.success"), previousTeam.Name),
Type: model.POST_MOVE_CHANNEL,
UserId: user.Id,
Props: model.StringInterface{
"username": user.Username,
},
}
if _, err := a.CreatePost(post, channel, false); err != nil {
return model.NewAppError("postChannelMoveMessage", "api.team.move_channel.post.error", nil, err.Error(), http.StatusInternalServerError)
}
return nil return nil
} }

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

@@ -97,7 +97,7 @@ func TestMoveChannel(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if err := th.App.MoveChannel(targetTeam, channel1, th.BasicUser); err == nil { if err := th.App.MoveChannel(targetTeam, channel1); err == nil {
t.Fatal("Should have failed due to mismatched members.") t.Fatal("Should have failed due to mismatched members.")
} }
@@ -105,7 +105,7 @@ func TestMoveChannel(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
if err := th.App.MoveChannel(targetTeam, channel1, th.BasicUser); err != nil { if err := th.App.MoveChannel(targetTeam, channel1); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }

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

@@ -4,12 +4,7 @@
package app package app
import ( import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/md5" "crypto/md5"
"crypto/rand"
"crypto/x509"
"encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"runtime/debug" "runtime/debug"
@@ -121,91 +116,8 @@ func (a *App) InvokeConfigListeners(old, current *model.Config) {
} }
} }
// EnsureAsymmetricSigningKey ensures that an asymmetric signing key exists and future calls to
// AsymmetricSigningKey will always return a valid signing key.
func (a *App) ensureAsymmetricSigningKey() error {
if a.asymmetricSigningKey != nil {
return nil
}
var key *model.SystemAsymmetricSigningKey
result := <-a.Srv.Store.System().GetByName(model.SYSTEM_ASYMMETRIC_SIGNING_KEY)
if result.Err == nil {
if err := json.Unmarshal([]byte(result.Data.(*model.System).Value), &key); err != nil {
return err
}
}
// If we don't already have a key, try to generate one.
if key == nil {
newECDSAKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
newKey := &model.SystemAsymmetricSigningKey{
ECDSAKey: &model.SystemECDSAKey{
Curve: "P-256",
X: newECDSAKey.X,
Y: newECDSAKey.Y,
D: newECDSAKey.D,
},
}
system := &model.System{
Name: model.SYSTEM_ASYMMETRIC_SIGNING_KEY,
}
v, err := json.Marshal(newKey)
if err != nil {
return err
}
system.Value = string(v)
if result = <-a.Srv.Store.System().Save(system); result.Err == nil {
// If we were able to save the key, use it, otherwise ignore the error.
key = newKey
}
}
// If we weren't able to save a new key above, another server must have beat us to it. Get the
// key from the database, and if that fails, error out.
if key == nil {
result := <-a.Srv.Store.System().GetByName(model.SYSTEM_ASYMMETRIC_SIGNING_KEY)
if result.Err != nil {
return result.Err
} else if err := json.Unmarshal([]byte(result.Data.(*model.System).Value), &key); err != nil {
return err
}
}
var curve elliptic.Curve
switch key.ECDSAKey.Curve {
case "P-256":
curve = elliptic.P256()
default:
return fmt.Errorf("unknown curve: " + key.ECDSAKey.Curve)
}
a.asymmetricSigningKey = &ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: curve,
X: key.ECDSAKey.X,
Y: key.ECDSAKey.Y,
},
D: key.ECDSAKey.D,
}
a.regenerateClientConfig()
return nil
}
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
return a.asymmetricSigningKey
}
func (a *App) regenerateClientConfig() { func (a *App) regenerateClientConfig() {
a.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId(), a.License()) a.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId())
if key := a.AsymmetricSigningKey(); key != nil {
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
a.clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
}
clientConfigJSON, _ := json.Marshal(a.clientConfig) clientConfigJSON, _ := json.Marshal(a.clientConfig)
a.clientConfigHash = fmt.Sprintf("%x", md5.Sum(clientConfigJSON)) a.clientConfigHash = fmt.Sprintf("%x", md5.Sum(clientConfigJSON))
} }
@@ -254,3 +166,11 @@ func (a *App) Desanitize(cfg *model.Config) {
cfg.SqlSettings.DataSourceSearchReplicas[i] = actual.SqlSettings.DataSourceSearchReplicas[i] cfg.SqlSettings.DataSourceSearchReplicas[i] = actual.SqlSettings.DataSourceSearchReplicas[i]
} }
} }
// License returns the currently active license or nil if the application is unlicensed.
func (a *App) License() *model.License {
if utils.IsLicensed() {
return utils.License()
}
return nil
}

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

@@ -6,8 +6,6 @@ package app
import ( import (
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
) )
@@ -56,10 +54,3 @@ func TestConfigListener(t *testing.T) {
t.Fatal("listener 2 should've been called") t.Fatal("listener 2 should've been called")
} }
} }
func TestAsymmetricSigningKey(t *testing.T) {
th := Setup().InitBasic()
defer th.TearDown()
assert.NotNil(t, th.App.AsymmetricSigningKey())
assert.NotEmpty(t, th.App.ClientConfig()["AsymmetricSigningPublicKey"])
}

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

@@ -501,7 +501,6 @@ func (a *App) trackConfig() {
a.SendDiagnostic(TRACK_CONFIG_MESSAGE_EXPORT, map[string]interface{}{ a.SendDiagnostic(TRACK_CONFIG_MESSAGE_EXPORT, map[string]interface{}{
"enable_message_export": *cfg.MessageExportSettings.EnableExport, "enable_message_export": *cfg.MessageExportSettings.EnableExport,
"export_format": *cfg.MessageExportSettings.ExportFormat,
"daily_run_time": *cfg.MessageExportSettings.DailyRunTime, "daily_run_time": *cfg.MessageExportSettings.DailyRunTime,
"default_export_from_timestamp": *cfg.MessageExportSettings.ExportFromTimestamp, "default_export_from_timestamp": *cfg.MessageExportSettings.ExportFromTimestamp,
"batch_size": *cfg.MessageExportSettings.BatchSize, "batch_size": *cfg.MessageExportSettings.BatchSize,

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

@@ -317,6 +317,5 @@ func (a *App) NewEmailTemplate(name, locale string) *utils.HTMLTemplate {
} }
func (a *App) SendMail(to, subject, htmlBody string) *model.AppError { func (a *App) SendMail(to, subject, htmlBody string) *model.AppError {
license := a.License() return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config())
return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance)
} }

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

@@ -58,8 +58,7 @@ const (
) )
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) { func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
license := a.License() return utils.NewFileBackend(&a.Config().FileSettings)
return utils.NewFileBackend(&a.Config().FileSettings, license != nil && *license.Features.Compliance)
} }
func (a *App) ReadFile(path string) ([]byte, *model.AppError) { func (a *App) ReadFile(path string) ([]byte, *model.AppError) {

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

@@ -4,19 +4,16 @@
package app package app
import ( import (
"crypto/md5"
"fmt"
"net/http" "net/http"
"strings" "strings"
l4g "github.com/alecthomas/log4go" l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
) )
func (a *App) LoadLicense() { func (a *App) LoadLicense() {
a.SetLicense(nil) utils.RemoveLicense()
licenseId := "" licenseId := ""
if result := <-a.Srv.Store.System().Get(); result.Err == nil { if result := <-a.Srv.Store.System().Get(); result.Err == nil {
@@ -39,7 +36,7 @@ func (a *App) LoadLicense() {
if result := <-a.Srv.Store.License().Get(licenseId); result.Err == nil { if result := <-a.Srv.Store.License().Get(licenseId); result.Err == nil {
record := result.Data.(*model.LicenseRecord) record := result.Data.(*model.LicenseRecord)
a.ValidateAndSetLicenseBytes([]byte(record.Bytes)) utils.LoadLicense([]byte(record.Bytes))
l4g.Info("License key valid unlocking enterprise features.") l4g.Info("License key valid unlocking enterprise features.")
} else { } else {
l4g.Info(utils.T("mattermost.load_license.find.warn")) l4g.Info(utils.T("mattermost.load_license.find.warn"))
@@ -62,7 +59,7 @@ func (a *App) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError)
} }
} }
if ok := a.SetLicense(license); !ok { if ok := utils.SetLicense(license); !ok {
return nil, model.NewAppError("addLicense", model.EXPIRED_LICENSE_ERROR, nil, "", http.StatusBadRequest) return nil, model.NewAppError("addLicense", model.EXPIRED_LICENSE_ERROR, nil, "", http.StatusBadRequest)
} }
@@ -105,115 +102,21 @@ func (a *App) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError)
return license, nil return license, nil
} }
// License returns the currently active license or nil if the application is unlicensed.
func (a *App) License() *model.License {
license, _ := a.licenseValue.Load().(*model.License)
return license
}
func (a *App) SetLicense(license *model.License) bool {
defer func() {
a.setDefaultRolesBasedOnConfig()
for _, listener := range a.licenseListeners {
listener()
}
}()
if license != nil {
license.Features.SetDefaults()
if !license.IsExpired() {
a.licenseValue.Store(license)
a.clientLicenseValue.Store(utils.GetClientLicense(license))
return true
}
}
a.licenseValue.Store((*model.License)(nil))
a.SetClientLicense(map[string]string{"IsLicensed": "false"})
return false
}
func (a *App) ValidateAndSetLicenseBytes(b []byte) {
if success, licenseStr := utils.ValidateLicense(b); success {
license := model.LicenseFromJson(strings.NewReader(licenseStr))
a.SetLicense(license)
return
}
l4g.Warn(utils.T("utils.license.load_license.invalid.warn"))
}
func (a *App) SetClientLicense(m map[string]string) {
a.clientLicenseValue.Store(m)
}
func (a *App) ClientLicense() map[string]string {
clientLicense, _ := a.clientLicenseValue.Load().(map[string]string)
return clientLicense
}
func (a *App) RemoveLicense() *model.AppError { func (a *App) RemoveLicense() *model.AppError {
if license, _ := a.licenseValue.Load().(*model.License); license == nil { utils.RemoveLicense()
return nil
}
sysVar := &model.System{} sysVar := &model.System{}
sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID sysVar.Name = model.SYSTEM_ACTIVE_LICENSE_ID
sysVar.Value = "" sysVar.Value = ""
if result := <-a.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil { if result := <-a.Srv.Store.System().SaveOrUpdate(sysVar); result.Err != nil {
utils.RemoveLicense()
return result.Err return result.Err
} }
a.SetLicense(nil)
a.ReloadConfig() a.ReloadConfig()
a.InvalidateAllCaches() a.InvalidateAllCaches()
return nil return nil
} }
func (a *App) AddLicenseListener(listener func()) string {
id := model.NewId()
a.licenseListeners[id] = listener
return id
}
func (a *App) RemoveLicenseListener(id string) {
delete(a.licenseListeners, id)
}
func (a *App) GetClientLicenseEtag(useSanitized bool) string {
value := ""
lic := a.ClientLicense()
if useSanitized {
lic = a.GetSanitizedClientLicense()
}
for k, v := range lic {
value += fmt.Sprintf("%s:%s;", k, v)
}
return model.Etag(fmt.Sprintf("%x", md5.Sum([]byte(value))))
}
func (a *App) GetSanitizedClientLicense() map[string]string {
sanitizedLicense := make(map[string]string)
for k, v := range a.ClientLicense() {
sanitizedLicense[k] = v
}
delete(sanitizedLicense, "Id")
delete(sanitizedLicense, "Name")
delete(sanitizedLicense, "Email")
delete(sanitizedLicense, "PhoneNumber")
delete(sanitizedLicense, "IssuedAt")
delete(sanitizedLicense, "StartsAt")
delete(sanitizedLicense, "ExpiresAt")
return sanitizedLicense
}

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

@@ -4,9 +4,8 @@
package app package app
import ( import (
//"github.com/mattermost/mattermost-server/model"
"testing" "testing"
"github.com/mattermost/mattermost-server/model"
) )
func TestLoadLicense(t *testing.T) { func TestLoadLicense(t *testing.T) {
@@ -38,75 +37,3 @@ func TestRemoveLicense(t *testing.T) {
t.Fatal("should have removed license") t.Fatal("should have removed license")
} }
} }
func TestSetLicense(t *testing.T) {
th := Setup()
defer th.TearDown()
l1 := &model.License{}
l1.Features = &model.Features{}
l1.Customer = &model.Customer{}
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
if ok := th.App.SetLicense(l1); !ok {
t.Fatal("license should have worked")
}
l2 := &model.License{}
l2.Features = &model.Features{}
l2.Customer = &model.Customer{}
l2.StartsAt = model.GetMillis() - 1000
l2.ExpiresAt = model.GetMillis() - 100
if ok := th.App.SetLicense(l2); ok {
t.Fatal("license should have failed")
}
l3 := &model.License{}
l3.Features = &model.Features{}
l3.Customer = &model.Customer{}
l3.StartsAt = model.GetMillis() + 10000
l3.ExpiresAt = model.GetMillis() + 100000
if ok := th.App.SetLicense(l3); !ok {
t.Fatal("license should have passed")
}
}
func TestClientLicenseEtag(t *testing.T) {
th := Setup()
defer th.TearDown()
etag1 := th.App.GetClientLicenseEtag(false)
th.App.SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "true"})
etag2 := th.App.GetClientLicenseEtag(false)
if etag1 == etag2 {
t.Fatal("etags should not match")
}
th.App.SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "false"})
etag3 := th.App.GetClientLicenseEtag(false)
if etag2 == etag3 {
t.Fatal("etags should not match")
}
}
func TestGetSanitizedClientLicense(t *testing.T) {
th := Setup()
defer th.TearDown()
l1 := &model.License{}
l1.Features = &model.Features{}
l1.Customer = &model.Customer{}
l1.Customer.Name = "TestName"
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
th.App.SetLicense(l1)
m := th.App.GetSanitizedClientLicense()
if _, ok := m["Name"]; ok {
t.Fatal("should have been sanatized")
}
}

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

@@ -565,7 +565,6 @@ func (a *App) RegisterPluginCommand(pluginId string, command *model.Command) err
TeamId: command.TeamId, TeamId: command.TeamId,
AutoComplete: command.AutoComplete, AutoComplete: command.AutoComplete,
AutoCompleteDesc: command.AutoCompleteDesc, AutoCompleteDesc: command.AutoCompleteDesc,
AutoCompleteHint: command.AutoCompleteHint,
DisplayName: command.DisplayName, DisplayName: command.DisplayName,
} }

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

@@ -10,6 +10,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"regexp" "regexp"
"strings" "strings"
@@ -732,23 +733,68 @@ func (a *App) GetFileInfosForPost(postId string, readFromMaster bool) ([]*model.
return infos, nil return infos, nil
} }
func (a *App) GetOpenGraphMetadata(url string) *opengraph.OpenGraph { func (a *App) GetOpenGraphMetadata(requestURL string) *opengraph.OpenGraph {
og := opengraph.NewOpenGraph() og := opengraph.NewOpenGraph()
res, err := a.HTTPClient(false).Get(url) res, err := a.HTTPClient(false).Get(requestURL)
if err != nil { if err != nil {
l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", url, err.Error()) l4g.Error("GetOpenGraphMetadata request failed for url=%v with err=%v", requestURL, err.Error())
return og return og
} }
defer consumeAndClose(res) defer consumeAndClose(res)
if err := og.ProcessHTML(res.Body); err != nil { if err := og.ProcessHTML(res.Body); err != nil {
l4g.Error("GetOpenGraphMetadata processing failed for url=%v with err=%v", url, err.Error()) l4g.Error("GetOpenGraphMetadata processing failed for url=%v with err=%v", requestURL, err.Error())
} }
makeOpenGraphURLsAbsolute(og, requestURL)
return og return og
} }
func makeOpenGraphURLsAbsolute(og *opengraph.OpenGraph, requestURL string) {
parsedRequestURL, err := url.Parse(requestURL)
if err != nil {
l4g.Warn("makeOpenGraphURLsAbsolute failed to parse url=%v", requestURL)
return
}
makeURLAbsolute := func(resultURL string) string {
if resultURL == "" {
return resultURL
}
parsedResultURL, err := url.Parse(resultURL)
if err != nil {
l4g.Warn("makeOpenGraphURLsAbsolute failed to parse result url=%v", resultURL)
return resultURL
}
if parsedResultURL.IsAbs() {
return resultURL
}
return parsedRequestURL.ResolveReference(parsedResultURL).String()
}
og.URL = makeURLAbsolute(og.URL)
for _, image := range og.Images {
image.URL = makeURLAbsolute(image.URL)
image.SecureURL = makeURLAbsolute(image.SecureURL)
}
for _, audio := range og.Audios {
audio.URL = makeURLAbsolute(audio.URL)
audio.SecureURL = makeURLAbsolute(audio.SecureURL)
}
for _, video := range og.Videos {
video.URL = makeURLAbsolute(video.URL)
video.SecureURL = makeURLAbsolute(video.SecureURL)
}
}
func (a *App) DoPostAction(postId string, actionId string, userId string) *model.AppError { func (a *App) DoPostAction(postId string, actionId string, userId string) *model.AppError {
pchan := a.Srv.Store.Post().GetSingle(postId) pchan := a.Srv.Store.Post().GetSingle(postId)

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

@@ -8,9 +8,11 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strings"
"testing" "testing"
"time" "time"
"github.com/dyatlov/go-opengraph/opengraph"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -254,3 +256,93 @@ func TestImageProxy(t *testing.T) {
}) })
} }
} }
func TestMakeOpenGraphURLsAbsolute(t *testing.T) {
for name, tc := range map[string]struct {
HTML string
RequestURL string
URL string
ImageURL string
}{
"absolute URLs": {
HTML: `
<html>
<head>
<meta property="og:url" content="https://example.com/apps/mattermost">
<meta property="og:image" content="https://images.example.com/image.png">
</head>
</html>`,
RequestURL: "https://example.com",
URL: "https://example.com/apps/mattermost",
ImageURL: "https://images.example.com/image.png",
},
"URLs starting with /": {
HTML: `
<html>
<head>
<meta property="og:url" content="/apps/mattermost">
<meta property="og:image" content="/image.png">
</head>
</html>`,
RequestURL: "http://example.com",
URL: "http://example.com/apps/mattermost",
ImageURL: "http://example.com/image.png",
},
"HTTPS URLs starting with /": {
HTML: `
<html>
<head>
<meta property="og:url" content="/apps/mattermost">
<meta property="og:image" content="/image.png">
</head>
</html>`,
RequestURL: "https://example.com",
URL: "https://example.com/apps/mattermost",
ImageURL: "https://example.com/image.png",
},
"missing image URL": {
HTML: `
<html>
<head>
<meta property="og:url" content="/apps/mattermost">
</head>
</html>`,
RequestURL: "http://example.com",
URL: "http://example.com/apps/mattermost",
ImageURL: "",
},
"relative URLs": {
HTML: `
<html>
<head>
<meta property="og:url" content="index.html">
<meta property="og:image" content="../resources/image.png">
</head>
</html>`,
RequestURL: "http://example.com/content/index.html",
URL: "http://example.com/content/index.html",
ImageURL: "http://example.com/resources/image.png",
},
} {
t.Run(name, func(t *testing.T) {
og := opengraph.NewOpenGraph()
if err := og.ProcessHTML(strings.NewReader(tc.HTML)); err != nil {
t.Fatal(err)
}
makeOpenGraphURLsAbsolute(og, tc.RequestURL)
if og.URL != tc.URL {
t.Fatalf("incorrect url, expected %v, got %v", tc.URL, og.URL)
}
if len(og.Images) > 0 {
if og.Images[0].URL != tc.ImageURL {
t.Fatalf("incorrect image url, expected %v, got %v", tc.ImageURL, og.Images[0].URL)
}
} else if tc.ImageURL != "" {
t.Fatalf("missing image url, expected %v, got nothing", tc.ImageURL)
}
})
}
}

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

@@ -12,6 +12,8 @@ func (a *App) Role(id string) *model.Role {
return a.roles[id] return a.roles[id]
} }
func (a *App) setDefaultRolesBasedOnConfig() { // Updates the roles based on the app config and the global license check. You may need to invoke
a.roles = utils.DefaultRolesBasedOnConfig(a.Config(), a.License() != nil) // this when license changes are made.
func (a *App) SetDefaultRolesBasedOnConfig() {
a.roles = utils.DefaultRolesBasedOnConfig(a.Config())
} }

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

@@ -17,7 +17,6 @@ import (
l4g "github.com/alecthomas/log4go" l4g "github.com/alecthomas/log4go"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pkg/errors"
"golang.org/x/crypto/acme/autocert" "golang.org/x/crypto/acme/autocert"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
@@ -117,7 +116,7 @@ func redirectHTTPToHTTPS(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, url.String(), http.StatusFound) http.Redirect(w, r, url.String(), http.StatusFound)
} }
func (a *App) StartServer() error { func (a *App) StartServer() {
l4g.Info(utils.T("api.server.start_server.starting.info")) l4g.Info(utils.T("api.server.start_server.starting.info"))
var handler http.Handler = &CorsWrapper{a.Config, a.Srv.Router} var handler http.Handler = &CorsWrapper{a.Config, a.Srv.Router}
@@ -127,7 +126,8 @@ func (a *App) StartServer() error {
rateLimiter, err := NewRateLimiter(&a.Config().RateLimitSettings) rateLimiter, err := NewRateLimiter(&a.Config().RateLimitSettings)
if err != nil { if err != nil {
return err l4g.Critical(err.Error())
return
} }
a.Srv.RateLimiter = rateLimiter a.Srv.RateLimiter = rateLimiter
@@ -151,8 +151,8 @@ func (a *App) StartServer() error {
listener, err := net.Listen("tcp", addr) listener, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
errors.Wrapf(err, utils.T("api.server.start_server.starting.critical"), err) l4g.Critical(utils.T("api.server.start_server.starting.critical"), err)
return err return
} }
a.Srv.ListenAddr = listener.Addr().(*net.TCPAddr) a.Srv.ListenAddr = listener.Addr().(*net.TCPAddr)
@@ -214,8 +214,6 @@ func (a *App) StartServer() error {
} }
close(a.Srv.didFinishListen) close(a.Srv.didFinishListen)
}() }()
return nil
} }
type tcpKeepAliveListener struct { type tcpKeepAliveListener struct {

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

@@ -1,50 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package app
import (
"testing"
"github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/require"
)
func TestStartServerSuccess(t *testing.T) {
a, err := New()
require.NoError(t, err)
a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
serverErr := a.StartServer()
a.Shutdown()
require.NoError(t, serverErr)
}
func TestStartServerRateLimiterCriticalError(t *testing.T) {
a, err := New()
require.NoError(t, err)
// Attempt to use Rate Limiter with an invalid config
a.UpdateConfig(func(cfg *model.Config) {
*cfg.RateLimitSettings.Enable = true
*cfg.RateLimitSettings.MaxBurst = -100
})
serverErr := a.StartServer()
a.Shutdown()
require.Error(t, serverErr)
}
func TestStartServerPortUnavailable(t *testing.T) {
a, err := New()
require.NoError(t, err)
// Attempt to listen on a system-reserved port
a.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.ListenAddress = ":21"
})
serverErr := a.StartServer()
a.Shutdown()
require.Error(t, serverErr)
}

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

@@ -6,10 +6,11 @@ package app
import ( import (
"testing" "testing"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/model"
) )
func TestCache(t *testing.T) { func TestCache(t *testing.T) {
@@ -47,7 +48,18 @@ func TestGetSessionIdleTimeoutInMinutes(t *testing.T) {
session, _ = th.App.CreateSession(session) session, _ = th.App.CreateSession(session)
th.App.SetLicense(model.NewTestLicense("compliance")) isLicensed := utils.IsLicensed()
license := utils.License()
timeout := *th.App.Config().ServiceSettings.SessionIdleTimeoutInMinutes
defer func() {
utils.SetIsLicensed(isLicensed)
utils.SetLicense(license)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SessionIdleTimeoutInMinutes = timeout })
}()
utils.SetIsLicensed(true)
utils.SetLicense(&model.License{Features: &model.Features{}})
utils.License().Features.SetDefaults()
*utils.License().Features.Compliance = true
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SessionIdleTimeoutInMinutes = 5 }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SessionIdleTimeoutInMinutes = 5 })
rsession, err := th.App.GetSession(session.Token) rsession, err := th.App.GetSession(session.Token)
@@ -110,7 +122,7 @@ func TestGetSessionIdleTimeoutInMinutes(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
// Test regular session with license off, should not timeout // Test regular session with license off, should not timeout
th.App.SetLicense(nil) *utils.License().Features.Compliance = false
session = &model.Session{ session = &model.Session{
UserId: model.NewId(), UserId: model.NewId(),
@@ -124,7 +136,7 @@ func TestGetSessionIdleTimeoutInMinutes(t *testing.T) {
_, err = th.App.GetSession(session.Token) _, err = th.App.GetSession(session.Token)
assert.Nil(t, err) assert.Nil(t, err)
th.App.SetLicense(model.NewTestLicense("compliance")) *utils.License().Features.Compliance = true
// Test regular session with timeout set to 0, should not timeout // Test regular session with timeout set to 0, should not timeout
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SessionIdleTimeoutInMinutes = 0 }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SessionIdleTimeoutInMinutes = 0 })

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

@@ -106,8 +106,6 @@ func init() {
channelCreateCmd.Flags().String("purpose", "", "Channel purpose") channelCreateCmd.Flags().String("purpose", "", "Channel purpose")
channelCreateCmd.Flags().Bool("private", false, "Create a private channel.") channelCreateCmd.Flags().Bool("private", false, "Create a private channel.")
moveChannelsCmd.Flags().String("username", "", "Required. Username who is moving the channel.")
deleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.") deleteChannelsCmd.Flags().Bool("confirm", false, "Confirm you really want to delete the channels.")
modifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel") modifyChannelCmd.Flags().Bool("private", false, "Convert the channel to a private channel")
@@ -321,33 +319,26 @@ func moveChannelsCmdF(cmd *cobra.Command, args []string) error {
return errors.New("Unable to find destination team '" + args[0] + "'") return errors.New("Unable to find destination team '" + args[0] + "'")
} }
username, erru := cmd.Flags().GetString("username")
if erru != nil || username == "" {
return errors.New("Username is required")
}
user := getUserFromUserArg(a, username)
channels := getChannelsFromChannelArgs(a, args[1:]) channels := getChannelsFromChannelArgs(a, args[1:])
for i, channel := range channels { for i, channel := range channels {
if channel == nil { if channel == nil {
CommandPrintErrorln("Unable to find channel '" + args[i] + "'") CommandPrintErrorln("Unable to find channel '" + args[i] + "'")
continue continue
} }
originTeamID := channel.TeamId if err := moveChannel(a, team, channel); err != nil {
if err := moveChannel(a, team, channel, user); err != nil {
CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error()) CommandPrintErrorln("Unable to move channel '" + channel.Name + "' error: " + err.Error())
} else { } else {
CommandPrettyPrintln("Moved channel '" + channel.Name + "' to " + team.Name + "(" + team.Id + ") from " + originTeamID + ".") CommandPrettyPrintln("Moved channel '" + channel.Name + "'")
} }
} }
return nil return nil
} }
func moveChannel(a *app.App, team *model.Team, channel *model.Channel, user *model.User) *model.AppError { func moveChannel(a *app.App, team *model.Team, channel *model.Channel) *model.AppError {
oldTeamId := channel.TeamId oldTeamId := channel.TeamId
if err := a.MoveChannel(team, channel, user); err != nil { if err := a.MoveChannel(team, channel); err != nil {
return err return err
} }

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

@@ -44,33 +44,6 @@ func TestRemoveChannel(t *testing.T) {
checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email) checkCommand(t, "channel", "remove", th.BasicTeam.Name+":"+channel.Name, th.BasicUser2.Email)
} }
func TestMoveChannel(t *testing.T) {
th := api.Setup().InitBasic()
defer th.TearDown()
client := th.BasicClient
team1 := th.BasicTeam
team2 := th.CreateTeam(client)
user1 := th.BasicUser
th.LinkUserToTeam(user1, team2)
channel := th.BasicChannel
th.LinkUserToTeam(user1, team1)
th.LinkUserToTeam(user1, team2)
adminEmail := user1.Email
adminUsername := user1.Username
origin := team1.Name + ":" + channel.Name
dest := team2.Name
checkCommand(t, "channel", "add", origin, adminEmail)
// should fail with nill because errors are logged instead of returned when a channel does not exist
require.Nil(t, runCommand(t, "channel", "move", dest, team1.Name+":doesnotexist", "--username", adminUsername))
checkCommand(t, "channel", "move", dest, origin, "--username", adminUsername)
}
func TestListChannels(t *testing.T) { func TestListChannels(t *testing.T) {
th := api.Setup().InitBasic() th := api.Setup().InitBasic()
defer th.TearDown() defer th.TearDown()

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

@@ -35,7 +35,7 @@ func jobserverCmdF(cmd *cobra.Command, args []string) {
defer l4g.Close() defer l4g.Close()
defer a.Shutdown() defer a.Shutdown()
a.LoadLicense() a.Jobs.LoadLicense()
// Run jobs // Run jobs
l4g.Info("Starting Mattermost job server") l4g.Info("Starting Mattermost job server")

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

@@ -42,11 +42,10 @@ func runServerCmd(cmd *cobra.Command, args []string) error {
disableConfigWatch, _ := cmd.Flags().GetBool("disableconfigwatch") disableConfigWatch, _ := cmd.Flags().GetBool("disableconfigwatch")
interruptChan := make(chan os.Signal, 1) return runServer(config, disableConfigWatch)
return runServer(config, disableConfigWatch, interruptChan)
} }
func runServer(configFileLocation string, disableConfigWatch bool, interruptChan chan os.Signal) error { func runServer(configFileLocation string, disableConfigWatch bool) error {
options := []app.Option{app.ConfigFile(configFileLocation)} options := []app.Option{app.ConfigFile(configFileLocation)}
if disableConfigWatch { if disableConfigWatch {
options = append(options, app.DisableConfigWatch) options = append(options, app.DisableConfigWatch)
@@ -54,7 +53,7 @@ func runServer(configFileLocation string, disableConfigWatch bool, interruptChan
a, err := app.New(options...) a, err := app.New(options...)
if err != nil { if err != nil {
l4g.Critical(err.Error()) l4g.Error(err.Error())
return err return err
} }
defer a.Shutdown() defer a.Shutdown()
@@ -88,12 +87,7 @@ func runServer(configFileLocation string, disableConfigWatch bool, interruptChan
} }
}) })
serverErr := a.StartServer() a.StartServer()
if serverErr != nil {
l4g.Critical(serverErr.Error())
return serverErr
}
api4.Init(a, a.Srv.Router, false) api4.Init(a, a.Srv.Router, false)
api3 := api.Init(a, a.Srv.Router) api3 := api.Init(a, a.Srv.Router)
wsapi.Init(a, a.Srv.WebSocketRouter) wsapi.Init(a, a.Srv.WebSocketRouter)
@@ -166,8 +160,9 @@ func runServer(configFileLocation string, disableConfigWatch bool, interruptChan
// wait for kill signal before attempting to gracefully shutdown // wait for kill signal before attempting to gracefully shutdown
// the running service // the running service
signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) c := make(chan os.Signal, 1)
<-interruptChan signal.Notify(c, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
<-c
if a.Cluster != nil { if a.Cluster != nil {
a.Cluster.StopInterNodeCommunication() a.Cluster.StopInterNodeCommunication()

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

@@ -1,72 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package main
import (
"io/ioutil"
"os"
"syscall"
"testing"
"github.com/mattermost/mattermost-server/jobs"
"github.com/mattermost/mattermost-server/utils"
"github.com/stretchr/testify/require"
)
type ServerTestHelper struct {
configPath string
disableConfigWatch bool
interruptChan chan os.Signal
originalInterval int
}
func SetupServerTest() *ServerTestHelper {
// Build a channel that will be used by the server to receive system signals…
interruptChan := make(chan os.Signal, 1)
// …and sent it immediately a SIGINT value.
// This will make the server loop stop as soon as it started successfully.
interruptChan <- syscall.SIGINT
// Let jobs poll for termination every 0.2s (instead of every 15s by default)
// Otherwise we would have to wait the whole polling duration before the test
// terminates.
originalInterval := jobs.DEFAULT_WATCHER_POLLING_INTERVAL
jobs.DEFAULT_WATCHER_POLLING_INTERVAL = 200
th := &ServerTestHelper{
configPath: utils.FindConfigFile("config.json"),
disableConfigWatch: true,
interruptChan: interruptChan,
originalInterval: originalInterval,
}
return th
}
func (th *ServerTestHelper) TearDownServerTest() {
jobs.DEFAULT_WATCHER_POLLING_INTERVAL = th.originalInterval
}
func TestRunServerSuccess(t *testing.T) {
th := SetupServerTest()
defer th.TearDownServerTest()
err := runServer(th.configPath, th.disableConfigWatch, th.interruptChan)
require.NoError(t, err)
}
func TestRunServerInvalidConfigFile(t *testing.T) {
th := SetupServerTest()
defer th.TearDownServerTest()
// Start the server with an unreadable config file
unreadableConfigFile, err := ioutil.TempFile("", "mattermost-unreadable-config-file-")
if err != nil {
panic(err)
}
os.Chmod(unreadableConfigFile.Name(), 0200)
defer os.Remove(unreadableConfigFile.Name())
err = runServer(unreadableConfigFile.Name(), th.disableConfigWatch, th.interruptChan)
require.Error(t, err)
}

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

@@ -53,11 +53,7 @@ func webClientTestsCmdF(cmd *cobra.Command, args []string) error {
defer a.Shutdown() defer a.Shutdown()
utils.InitTranslations(a.Config().LocalizationSettings) utils.InitTranslations(a.Config().LocalizationSettings)
serverErr := a.StartServer() a.StartServer()
if serverErr != nil {
return serverErr
}
api4.Init(a, a.Srv.Router, false) api4.Init(a, a.Srv.Router, false)
api.Init(a, a.Srv.Router) api.Init(a, a.Srv.Router)
wsapi.Init(a, a.Srv.WebSocketRouter) wsapi.Init(a, a.Srv.WebSocketRouter)
@@ -75,11 +71,7 @@ func serverForWebClientTestsCmdF(cmd *cobra.Command, args []string) error {
defer a.Shutdown() defer a.Shutdown()
utils.InitTranslations(a.Config().LocalizationSettings) utils.InitTranslations(a.Config().LocalizationSettings)
serverErr := a.StartServer() a.StartServer()
if serverErr != nil {
return serverErr
}
api4.Init(a, a.Srv.Router, false) api4.Init(a, a.Srv.Router, false)
api.Init(a, a.Srv.Router) api.Init(a, a.Srv.Router)
wsapi.Init(a, a.Srv.WebSocketRouter) wsapi.Init(a, a.Srv.WebSocketRouter)

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

@@ -131,6 +131,10 @@
"id": "api.admin.upload_brand_image.too_large.app_error", "id": "api.admin.upload_brand_image.too_large.app_error",
"translation": "Unable to upload file. File is too large." "translation": "Unable to upload file. File is too large."
}, },
{
"id": "api.api.init.parsing_templates.debug",
"translation": "Parsing server templates at %v"
},
{ {
"id": "api.api.init.parsing_templates.error", "id": "api.api.init.parsing_templates.error",
"translation": "Failed to parse server templates %v" "translation": "Failed to parse server templates %v"
@@ -3130,14 +3134,6 @@
"id": "app.channel.move_channel.members_do_not_match.error", "id": "app.channel.move_channel.members_do_not_match.error",
"translation": "Cannot move a channel unless all its members are already members of the destination team." "translation": "Cannot move a channel unless all its members are already members of the destination team."
}, },
{
"id": "api.team.move_channel.success",
"translation": "This channel has been moved to this team from %v."
},
{
"id": "api.team.move_channel.post.error",
"translation": "Failed to post channel move message."
},
{ {
"id": "app.channel.post_update_channel_purpose_message.post.error", "id": "app.channel.post_update_channel_purpose_message.post.error",
"translation": "Failed to post channel purpose message" "translation": "Failed to post channel purpose message"
@@ -4862,14 +4858,6 @@
"id": "model.config.is_valid.message_export.batch_size.app_error", "id": "model.config.is_valid.message_export.batch_size.app_error",
"translation": "Message export job BatchSize must be a positive integer" "translation": "Message export job BatchSize must be a positive integer"
}, },
{
"id": "model.config.is_valid.message_export.export_type.app_error",
"translation": "Message export job ExportFormat must be one of either 'actiance' or 'globalrelay'"
},
{
"id": "model.config.is_valid.message_export.global_relay_email_address.app_error",
"translation": "Message export job GlobalRelayEmailAddress must be set to a valid email address"
},
{ {
"id": "model.config.is_valid.message_export.daily_runtime.app_error", "id": "model.config.is_valid.message_export.daily_runtime.app_error",
"translation": "Message export job DailyRuntime must be a 24-hour time stamp in the form HH:MM." "translation": "Message export job DailyRuntime must be a 24-hour time stamp in the form HH:MM."
@@ -7094,10 +7082,6 @@
"id": "utils.mail.new_client.auth.app_error", "id": "utils.mail.new_client.auth.app_error",
"translation": "Failed to authenticate on SMTP server" "translation": "Failed to authenticate on SMTP server"
}, },
{
"id": "utils.mail.sendMail.attachments.write_error",
"translation": "Failed to write attachment to email"
},
{ {
"id": "utils.mail.new_client.helo.error", "id": "utils.mail.new_client.helo.error",
"translation": "Failed to to set the HELO to SMTP server %v" "translation": "Failed to to set the HELO to SMTP server %v"
@@ -7174,6 +7158,10 @@
"id": "web.create_dir.error", "id": "web.create_dir.error",
"translation": "Failed to create directory watcher %v" "translation": "Failed to create directory watcher %v"
}, },
{
"id": "web.dir_fail.error",
"translation": "Failed in directory watcher %v"
},
{ {
"id": "web.do_load_channel.error", "id": "web.do_load_channel.error",
"translation": "Error in getting users profile for id=%v forcing logout" "translation": "Error in getting users profile for id=%v forcing logout"
@@ -7278,10 +7266,18 @@
"id": "web.parsing_templates.debug", "id": "web.parsing_templates.debug",
"translation": "Parsing templates at %v" "translation": "Parsing templates at %v"
}, },
{
"id": "web.parsing_templates.error",
"translation": "Failed to parse templates %v"
},
{ {
"id": "web.post_permalink.app_error", "id": "web.post_permalink.app_error",
"translation": "Invalid Post ID" "translation": "Invalid Post ID"
}, },
{
"id": "web.reparse_templates.info",
"translation": "Re-parsing templates because of modified file %v"
},
{ {
"id": "web.reset_password.expired_link.app_error", "id": "web.reset_password.expired_link.app_error",
"translation": "The password reset link has expired" "translation": "The password reset link has expired"

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

@@ -11,9 +11,9 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
) )
// Default polling interval for jobs termination. const (
// (Defining as `var` rather than `const` allows tests to lower the interval.) DEFAULT_WATCHER_POLLING_INTERVAL = 15000
var DEFAULT_WATCHER_POLLING_INTERVAL = 15000 )
type Watcher struct { type Watcher struct {
srv *JobServer srv *JobServer

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

@@ -4,9 +4,12 @@
package jobs package jobs
import ( import (
l4g "github.com/alecthomas/log4go"
ejobs "github.com/mattermost/mattermost-server/einterfaces/jobs" ejobs "github.com/mattermost/mattermost-server/einterfaces/jobs"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store" "github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils"
) )
type ConfigService interface { type ConfigService interface {
@@ -47,6 +50,36 @@ func (srv *JobServer) Config() *model.Config {
return srv.ConfigService.Config() return srv.ConfigService.Config()
} }
func (srv *JobServer) LoadLicense() {
licenseId := ""
if result := <-srv.Store.System().Get(); result.Err == nil {
props := result.Data.(model.StringMap)
licenseId = props[model.SYSTEM_ACTIVE_LICENSE_ID]
}
var licenseBytes []byte
if len(licenseId) != 26 {
// Lets attempt to load the file from disk since it was missing from the DB
_, licenseBytes = utils.GetAndValidateLicenseFileFromDisk(*srv.ConfigService.Config().ServiceSettings.LicenseFileLocation)
} else {
if result := <-srv.Store.License().Get(licenseId); result.Err == nil {
record := result.Data.(*model.LicenseRecord)
licenseBytes = []byte(record.Bytes)
l4g.Info("License key valid unlocking enterprise features.")
} else {
l4g.Info(utils.T("mattermost.load_license.find.warn"))
}
}
if licenseBytes != nil {
utils.LoadLicense(licenseBytes)
l4g.Info("License key valid unlocking enterprise features.")
} else {
l4g.Info(utils.T("mattermost.load_license.find.warn"))
}
}
func (srv *JobServer) StartWorkers() { func (srv *JobServer) StartWorkers() {
srv.Workers = srv.InitWorkers().Start() srv.Workers = srv.InitWorkers().Start()
} }

39
jobs/server_test.go Обычный файл
Просмотреть файл

@@ -0,0 +1,39 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package jobs
import (
"testing"
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/store/storetest"
"github.com/mattermost/mattermost-server/utils"
)
func TestJobServer_LoadLicense(t *testing.T) {
if utils.T == nil {
utils.TranslationsPreInit()
}
mockStore := &storetest.Store{}
defer mockStore.AssertExpectations(t)
server := &JobServer{
Store: mockStore,
}
mockStore.SystemStore.On("Get").Return(storetest.NewStoreChannel(store.StoreResult{
Data: model.StringMap{
model.SYSTEM_ACTIVE_LICENSE_ID: "thelicenseid00000000000000",
},
}))
mockStore.LicenseStore.On("Get", "thelicenseid00000000000000").Return(storetest.NewStoreChannel(store.StoreResult{
Data: &model.LicenseRecord{
Id: "thelicenseid00000000000000",
},
}))
server.LoadLicense()
}

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

@@ -6,10 +6,7 @@ package model
type ChannelMemberHistory struct { type ChannelMemberHistory struct {
ChannelId string ChannelId string
UserId string UserId string
UserEmail string `db:"Email"`
JoinTime int64 JoinTime int64
LeaveTime *int64 LeaveTime *int64
// these two fields are never set in the database - when we SELECT, we join on Users to get them
UserEmail string `db:"Email"`
Username string
} }

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

@@ -1729,7 +1729,7 @@ func (c *Client4) RemoveUserFromChannel(channelId, userId string) (bool, *Respon
// CreatePost creates a post based on the provided post struct. // CreatePost creates a post based on the provided post struct.
func (c *Client4) CreatePost(post *Post) (*Post, *Response) { func (c *Client4) CreatePost(post *Post) (*Post, *Response) {
if r, err := c.DoApiPost(c.GetPostsRoute(), post.ToUnsanitizedJson()); err != nil { if r, err := c.DoApiPost(c.GetPostsRoute(), post.ToJson()); err != nil {
return nil, BuildErrorResponse(r, err) return nil, BuildErrorResponse(r, err)
} else { } else {
defer closeBody(r) defer closeBody(r)
@@ -1739,7 +1739,7 @@ func (c *Client4) CreatePost(post *Post) (*Post, *Response) {
// UpdatePost updates a post based on the provided post struct. // UpdatePost updates a post based on the provided post struct.
func (c *Client4) UpdatePost(postId string, post *Post) (*Post, *Response) { func (c *Client4) UpdatePost(postId string, post *Post) (*Post, *Response) {
if r, err := c.DoApiPut(c.GetPostRoute(postId), post.ToUnsanitizedJson()); err != nil { if r, err := c.DoApiPut(c.GetPostRoute(postId), post.ToJson()); err != nil {
return nil, BuildErrorResponse(r, err) return nil, BuildErrorResponse(r, err)
} else { } else {
defer closeBody(r) defer closeBody(r)

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

@@ -1,58 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package model
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
)
// https://github.com/mattermost/mattermost-server/issues/8205
func TestClient4CreatePost(t *testing.T) {
post := &Post{
Props: map[string]interface{}{
"attachments": []*SlackAttachment{
&SlackAttachment{
Actions: []*PostAction{
&PostAction{
Integration: &PostActionIntegration{
Context: map[string]interface{}{
"foo": "bar",
},
URL: "http://foo.com",
},
Name: "Foo",
},
},
},
},
},
}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
attachments := PostFromJson(r.Body).Attachments()
assert.Equal(t, []*SlackAttachment{
&SlackAttachment{
Actions: []*PostAction{
&PostAction{
Integration: &PostActionIntegration{
Context: map[string]interface{}{
"foo": "bar",
},
URL: "http://foo.com",
},
Name: "Foo",
},
},
},
}, attachments)
}))
client := NewAPIv4Client(server.URL)
_, resp := client.CreatePost(post)
assert.Equal(t, http.StatusOK, resp.StatusCode)
}

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

@@ -158,9 +158,6 @@ const (
PLUGIN_SETTINGS_DEFAULT_DIRECTORY = "./plugins" PLUGIN_SETTINGS_DEFAULT_DIRECTORY = "./plugins"
PLUGIN_SETTINGS_DEFAULT_CLIENT_DIRECTORY = "./client/plugins" PLUGIN_SETTINGS_DEFAULT_CLIENT_DIRECTORY = "./client/plugins"
COMPLIANCE_EXPORT_TYPE_ACTIANCE = "actiance"
COMPLIANCE_EXPORT_TYPE_GLOBALRELAY = "globalrelay"
) )
type ServiceSettings struct { type ServiceSettings struct {
@@ -1626,13 +1623,9 @@ func (s *PluginSettings) SetDefaults() {
type MessageExportSettings struct { type MessageExportSettings struct {
EnableExport *bool EnableExport *bool
ExportFormat *string
DailyRunTime *string DailyRunTime *string
ExportFromTimestamp *int64 ExportFromTimestamp *int64
BatchSize *int BatchSize *int
// formatter-specific settings - these are only expected to be non-nil if ExportFormat is set to the associated format
GlobalRelayEmailAddress *string
} }
func (s *MessageExportSettings) SetDefaults() { func (s *MessageExportSettings) SetDefaults() {
@@ -1640,10 +1633,6 @@ func (s *MessageExportSettings) SetDefaults() {
s.EnableExport = NewBool(false) s.EnableExport = NewBool(false)
} }
if s.ExportFormat == nil {
s.ExportFormat = NewString(COMPLIANCE_EXPORT_TYPE_ACTIANCE)
}
if s.DailyRunTime == nil { if s.DailyRunTime == nil {
s.DailyRunTime = NewString("01:00") s.DailyRunTime = NewString("01:00")
} }
@@ -2181,16 +2170,6 @@ func (mes *MessageExportSettings) isValid(fs FileSettings) *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, err.Error(), http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.message_export.daily_runtime.app_error", nil, err.Error(), http.StatusBadRequest)
} else if mes.BatchSize == nil || *mes.BatchSize < 0 { } else if mes.BatchSize == nil || *mes.BatchSize < 0 {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.batch_size.app_error", nil, "", http.StatusBadRequest) return NewAppError("Config.IsValid", "model.config.is_valid.message_export.batch_size.app_error", nil, "", http.StatusBadRequest)
} else if mes.ExportFormat == nil || (*mes.ExportFormat != COMPLIANCE_EXPORT_TYPE_ACTIANCE && *mes.ExportFormat != COMPLIANCE_EXPORT_TYPE_GLOBALRELAY) {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.export_type.app_error", nil, "", http.StatusBadRequest)
}
if *mes.ExportFormat == COMPLIANCE_EXPORT_TYPE_GLOBALRELAY {
// validating email addresses is hard - just make sure it contains an '@' sign
// see https://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address
if mes.GlobalRelayEmailAddress == nil || !strings.Contains(*mes.GlobalRelayEmailAddress, "@") {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.global_relay_email_address.app_error", nil, "", http.StatusBadRequest)
}
} }
} }
return nil return nil

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

@@ -136,7 +136,7 @@ func TestMessageExportSettingsIsValidBatchSizeInvalid(t *testing.T) {
require.Error(t, mes.isValid(*fs)) require.Error(t, mes.isValid(*fs))
} }
func TestMessageExportSettingsIsValidExportFormatInvalid(t *testing.T) { func TestMessageExportSettingsIsValid(t *testing.T) {
fs := &FileSettings{ fs := &FileSettings{
DriverName: NewString("foo"), // bypass file location check DriverName: NewString("foo"), // bypass file location check
} }
@@ -147,55 +147,6 @@ func TestMessageExportSettingsIsValidExportFormatInvalid(t *testing.T) {
BatchSize: NewInt(100), BatchSize: NewInt(100),
} }
// should fail fast because export format isn't set
require.Error(t, mes.isValid(*fs))
}
func TestMessageExportSettingsIsValidGlobalRelayEmailAddressInvalid(t *testing.T) {
fs := &FileSettings{
DriverName: NewString("foo"), // bypass file location check
}
mes := &MessageExportSettings{
EnableExport: NewBool(true),
ExportFormat: NewString(COMPLIANCE_EXPORT_TYPE_GLOBALRELAY),
ExportFromTimestamp: NewInt64(0),
DailyRunTime: NewString("15:04"),
BatchSize: NewInt(100),
}
// should fail fast because global relay email address isn't set
require.Error(t, mes.isValid(*fs))
}
func TestMessageExportSettingsIsValidActiance(t *testing.T) {
fs := &FileSettings{
DriverName: NewString("foo"), // bypass file location check
}
mes := &MessageExportSettings{
EnableExport: NewBool(true),
ExportFormat: NewString(COMPLIANCE_EXPORT_TYPE_ACTIANCE),
ExportFromTimestamp: NewInt64(0),
DailyRunTime: NewString("15:04"),
BatchSize: NewInt(100),
}
// should pass because everything is valid
require.Nil(t, mes.isValid(*fs))
}
func TestMessageExportSettingsIsValidGlobalRelay(t *testing.T) {
fs := &FileSettings{
DriverName: NewString("foo"), // bypass file location check
}
mes := &MessageExportSettings{
EnableExport: NewBool(true),
ExportFormat: NewString(COMPLIANCE_EXPORT_TYPE_GLOBALRELAY),
ExportFromTimestamp: NewInt64(0),
DailyRunTime: NewString("15:04"),
BatchSize: NewInt(100),
GlobalRelayEmailAddress: NewString("test@mattermost.com"),
}
// should pass because everything is valid // should pass because everything is valid
require.Nil(t, mes.isValid(*fs)) require.Nil(t, mes.isValid(*fs))
} }
@@ -208,7 +159,6 @@ func TestMessageExportSetDefaults(t *testing.T) {
require.Equal(t, "01:00", *mes.DailyRunTime) require.Equal(t, "01:00", *mes.DailyRunTime)
require.Equal(t, int64(0), *mes.ExportFromTimestamp) require.Equal(t, int64(0), *mes.ExportFromTimestamp)
require.Equal(t, 10000, *mes.BatchSize) require.Equal(t, 10000, *mes.BatchSize)
require.Equal(t, COMPLIANCE_EXPORT_TYPE_ACTIANCE, *mes.ExportFormat)
} }
func TestMessageExportSetDefaultsExportEnabledExportFromTimestampNil(t *testing.T) { func TestMessageExportSetDefaultsExportEnabledExportFromTimestampNil(t *testing.T) {

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

@@ -173,25 +173,6 @@ func (l *License) ToJson() string {
return string(b) return string(b)
} }
// NewTestLicense returns a license that expires in the future and has the given features.
func NewTestLicense(features ...string) *License {
ret := &License{
ExpiresAt: GetMillis() + 90*24*60*60*1000,
Customer: &Customer{},
Features: &Features{},
}
ret.Features.SetDefaults()
featureMap := map[string]bool{}
for _, feature := range features {
featureMap[feature] = true
}
featureJson, _ := json.Marshal(featureMap)
json.Unmarshal(featureJson, &ret.Features)
return ret
}
func LicenseFromJson(data io.Reader) *License { func LicenseFromJson(data io.Reader) *License {
var o *License var o *License
json.NewDecoder(data).Decode(&o) json.NewDecoder(data).Decode(&o)

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

@@ -9,7 +9,6 @@ type MessageExport struct {
UserId *string UserId *string
UserEmail *string UserEmail *string
Username *string
PostId *string PostId *string
PostCreateAt *int64 PostCreateAt *int64

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

@@ -28,7 +28,6 @@ const (
POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead POST_ADD_REMOVE = "system_add_remove" // Deprecated, use POST_ADD_TO_CHANNEL or POST_REMOVE_FROM_CHANNEL instead
POST_ADD_TO_CHANNEL = "system_add_to_channel" POST_ADD_TO_CHANNEL = "system_add_to_channel"
POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel" POST_REMOVE_FROM_CHANNEL = "system_remove_from_channel"
POST_MOVE_CHANNEL = "system_move_channel"
POST_ADD_TO_TEAM = "system_add_to_team" POST_ADD_TO_TEAM = "system_add_to_team"
POST_REMOVE_FROM_TEAM = "system_remove_from_team" POST_REMOVE_FROM_TEAM = "system_remove_from_team"
POST_HEADER_CHANGE = "system_header_change" POST_HEADER_CHANGE = "system_header_change"
@@ -122,13 +121,12 @@ type PostActionIntegrationResponse struct {
func (o *Post) ToJson() string { func (o *Post) ToJson() string {
copy := *o copy := *o
copy.StripActionIntegrations() copy.StripActionIntegrations()
b, _ := json.Marshal(&copy) b, err := json.Marshal(&copy)
return string(b) if err != nil {
} return ""
} else {
func (o *Post) ToUnsanitizedJson() string { return string(b)
b, _ := json.Marshal(o) }
return string(b)
} }
func PostFromJson(data io.Reader) *Post { func PostFromJson(data io.Reader) *Post {
@@ -198,7 +196,6 @@ func (o *Post) IsValid() *AppError {
POST_LEAVE_TEAM, POST_LEAVE_TEAM,
POST_ADD_TO_CHANNEL, POST_ADD_TO_CHANNEL,
POST_REMOVE_FROM_CHANNEL, POST_REMOVE_FROM_CHANNEL,
POST_MOVE_CHANNEL,
POST_ADD_TO_TEAM, POST_ADD_TO_TEAM,
POST_REMOVE_FROM_TEAM, POST_REMOVE_FROM_TEAM,
POST_SLACK_ATTACHMENT, POST_SLACK_ATTACHMENT,

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

@@ -6,16 +6,14 @@ package model
import ( import (
"encoding/json" "encoding/json"
"io" "io"
"math/big"
) )
const ( const (
SYSTEM_DIAGNOSTIC_ID = "DiagnosticId" SYSTEM_DIAGNOSTIC_ID = "DiagnosticId"
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests" SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime" SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId" SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime" SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime"
SYSTEM_ASYMMETRIC_SIGNING_KEY = "AsymmetricSigningKey"
) )
type System struct { type System struct {
@@ -33,14 +31,3 @@ func SystemFromJson(data io.Reader) *System {
json.NewDecoder(data).Decode(&o) json.NewDecoder(data).Decode(&o)
return o return o
} }
type SystemAsymmetricSigningKey struct {
ECDSAKey *SystemECDSAKey `json:"ecdsa_key,omitempty"`
}
type SystemECDSAKey struct {
Curve string `json:"curve"`
X *big.Int `json:"x"`
Y *big.Int `json:"y"`
D *big.Int `json:"d,omitempty"`
}

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

@@ -110,8 +110,7 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime
query := ` query := `
SELECT SELECT
cmh.*, cmh.*,
u.Email, u.Email
u.Username
FROM ChannelMemberHistory cmh FROM ChannelMemberHistory cmh
INNER JOIN Users u ON cmh.UserId = u.Id INNER JOIN Users u ON cmh.UserId = u.Id
WHERE cmh.ChannelId = :ChannelId WHERE cmh.ChannelId = :ChannelId
@@ -131,10 +130,9 @@ func (s SqlChannelMemberHistoryStore) getFromChannelMemberHistoryTable(startTime
func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) { func (s SqlChannelMemberHistoryStore) getFromChannelMembersTable(startTime int64, endTime int64, channelId string) ([]*model.ChannelMemberHistory, error) {
query := ` query := `
SELECT DISTINCT SELECT DISTINCT
ch.ChannelId, ch.ChannelId,
ch.UserId, ch.UserId,
u.Email, u.email
u.Username
FROM ChannelMembers AS ch FROM ChannelMembers AS ch
INNER JOIN Users AS u ON ch.UserId = u.id INNER JOIN Users AS u ON ch.UserId = u.id
WHERE ch.ChannelId = :ChannelId` WHERE ch.ChannelId = :ChannelId`
@@ -160,7 +158,7 @@ func (s SqlChannelMemberHistoryStore) PermanentDeleteBatch(endTime int64, limit
query = query =
`DELETE FROM ChannelMemberHistory `DELETE FROM ChannelMemberHistory
WHERE ctid IN ( WHERE ctid IN (
SELECT ctid FROM ChannelMemberHistory SELECT ctid FROM ChannelMemberHistory
WHERE LeaveTime IS NOT NULL WHERE LeaveTime IS NOT NULL
AND LeaveTime <= :EndTime AND LeaveTime <= :EndTime
LIMIT :Limit LIMIT :Limit

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

@@ -225,8 +225,7 @@ func (s SqlComplianceStore) MessageExport(after int64, limit int) store.StoreCha
Channels.Id AS ChannelId, Channels.Id AS ChannelId,
Channels.DisplayName AS ChannelDisplayName, Channels.DisplayName AS ChannelDisplayName,
Users.Id AS UserId, Users.Id AS UserId,
Users.Email AS UserEmail, Users.Email AS UserEmail
Users.Username
FROM FROM
Posts Posts
LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id LEFT OUTER JOIN Channels ON Posts.ChannelId = Channels.Id

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

@@ -322,10 +322,7 @@ type etagPosts struct {
func (s SqlPostStore) InvalidateLastPostTimeCache(channelId string) { func (s SqlPostStore) InvalidateLastPostTimeCache(channelId string) {
lastPostTimeCache.Remove(channelId) lastPostTimeCache.Remove(channelId)
lastPostsCache.Remove(channelId)
// Keys are "{channelid}{limit}" and caching only occurs on limits of 30 and 60
lastPostsCache.Remove(channelId + "30")
lastPostsCache.Remove(channelId + "60")
} }
func (s SqlPostStore) GetEtag(channelId string, allowFromCache bool) store.StoreChannel { func (s SqlPostStore) GetEtag(channelId string, allowFromCache bool) store.StoreChannel {
@@ -442,9 +439,8 @@ func (s SqlPostStore) GetPosts(channelId string, offset int, limit int, allowFro
return return
} }
// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients if allowFromCache && offset == 0 && limit == 60 {
if allowFromCache && offset == 0 && (limit == 60 || limit == 30) { if cacheItem, ok := lastPostsCache.Get(channelId); ok {
if cacheItem, ok := lastPostsCache.Get(fmt.Sprintf("%s%v", channelId, limit)); ok {
if s.metrics != nil { if s.metrics != nil {
s.metrics.IncrementMemCacheHitCounter("Last Posts Cache") s.metrics.IncrementMemCacheHitCounter("Last Posts Cache")
} }
@@ -486,9 +482,8 @@ func (s SqlPostStore) GetPosts(channelId string, offset int, limit int, allowFro
list.MakeNonNil() list.MakeNonNil()
// Caching only occurs on limits of 30 and 60, the common limits requested by MM clients if offset == 0 && limit == 60 {
if offset == 0 && (limit == 60 || limit == 30) { lastPostsCache.AddWithExpiresInSecs(channelId, list, LAST_POSTS_CACHE_SEC)
lastPostsCache.AddWithExpiresInSecs(fmt.Sprintf("%s%v", channelId, limit), list, LAST_POSTS_CACHE_SEC)
} }
result.Data = list result.Data = list

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

@@ -15,7 +15,6 @@ import (
) )
const ( const (
VERSION_4_8_0 = "4.8.0"
VERSION_4_7_0 = "4.7.0" VERSION_4_7_0 = "4.7.0"
VERSION_4_6_0 = "4.6.0" VERSION_4_6_0 = "4.6.0"
VERSION_4_5_0 = "4.5.0" VERSION_4_5_0 = "4.5.0"
@@ -65,7 +64,6 @@ func UpgradeDatabase(sqlStore SqlStore) {
UpgradeDatabaseToVersion45(sqlStore) UpgradeDatabaseToVersion45(sqlStore)
UpgradeDatabaseToVersion46(sqlStore) UpgradeDatabaseToVersion46(sqlStore)
UpgradeDatabaseToVersion47(sqlStore) UpgradeDatabaseToVersion47(sqlStore)
UpgradeDatabaseToVersion48(sqlStore)
// If the SchemaVersion is empty this this is the first time it has ran // If the SchemaVersion is empty this this is the first time it has ran
// so lets set it to the current version. // so lets set it to the current version.
@@ -349,10 +347,3 @@ func UpgradeDatabaseToVersion47(sqlStore SqlStore) {
saveSchemaVersion(sqlStore, VERSION_4_7_0) saveSchemaVersion(sqlStore, VERSION_4_7_0)
} }
} }
func UpgradeDatabaseToVersion48(sqlStore SqlStore) {
//TODO: Uncomment the following condition when version 4.8.0 is released
//if shouldPerformUpgrade(sqlStore, VERSION_4_7_0, VERSION_4_8_0) {
// saveSchemaVersion(sqlStore, VERSION_4_8_0)
//}
}

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

@@ -35,7 +35,6 @@ func testLogJoinEvent(t *testing.T, ss store.Store) {
user := model.User{ user := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user = *store.Must(ss.User().Save(&user)).(*model.User) user = *store.Must(ss.User().Save(&user)).(*model.User)
@@ -58,7 +57,6 @@ func testLogLeaveEvent(t *testing.T, ss store.Store) {
user := model.User{ user := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user = *store.Must(ss.User().Save(&user)).(*model.User) user = *store.Must(ss.User().Save(&user)).(*model.User)
@@ -84,7 +82,6 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
user := model.User{ user := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user = *store.Must(ss.User().Save(&user)).(*model.User) user = *store.Must(ss.User().Save(&user)).(*model.User)
@@ -111,7 +108,6 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime, channelMembers[0].JoinTime) assert.Equal(t, joinTime, channelMembers[0].JoinTime)
assert.Nil(t, channelMembers[0].LeaveTime) assert.Nil(t, channelMembers[0].LeaveTime)
@@ -121,7 +117,6 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime, channelMembers[0].JoinTime) assert.Equal(t, joinTime, channelMembers[0].JoinTime)
assert.Nil(t, channelMembers[0].LeaveTime) assert.Nil(t, channelMembers[0].LeaveTime)
@@ -134,7 +129,6 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime, channelMembers[0].JoinTime) assert.Equal(t, joinTime, channelMembers[0].JoinTime)
assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime) assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime)
@@ -144,7 +138,6 @@ func testGetUsersInChannelAtChannelMemberHistory(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime, channelMembers[0].JoinTime) assert.Equal(t, joinTime, channelMembers[0].JoinTime)
assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime) assert.Equal(t, leaveTime, *channelMembers[0].LeaveTime)
@@ -167,7 +160,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
user := model.User{ user := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user = *store.Must(ss.User().Save(&user)).(*model.User) user = *store.Must(ss.User().Save(&user)).(*model.User)
@@ -200,7 +192,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime-500, channelMembers[0].JoinTime) assert.Equal(t, joinTime-500, channelMembers[0].JoinTime)
assert.Equal(t, joinTime-100, *channelMembers[0].LeaveTime) assert.Equal(t, joinTime-100, *channelMembers[0].LeaveTime)
@@ -210,7 +201,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime-100, channelMembers[0].JoinTime) assert.Equal(t, joinTime-100, channelMembers[0].JoinTime)
assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime) assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime)
@@ -220,7 +210,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime+100, channelMembers[0].JoinTime) assert.Equal(t, joinTime+100, channelMembers[0].JoinTime)
assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime) assert.Equal(t, joinTime+500, *channelMembers[0].LeaveTime)
@@ -230,7 +219,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime+100, channelMembers[0].JoinTime) assert.Equal(t, joinTime+100, channelMembers[0].JoinTime)
assert.Equal(t, leaveTime-100, *channelMembers[0].LeaveTime) assert.Equal(t, leaveTime-100, *channelMembers[0].LeaveTime)
@@ -240,7 +228,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, joinTime-100, channelMembers[0].JoinTime) assert.Equal(t, joinTime-100, channelMembers[0].JoinTime)
assert.Equal(t, leaveTime+100, *channelMembers[0].LeaveTime) assert.Equal(t, leaveTime+100, *channelMembers[0].LeaveTime)
@@ -250,7 +237,6 @@ func testGetUsersInChannelAtChannelMembers(t *testing.T, ss store.Store) {
assert.Equal(t, channel.Id, channelMembers[0].ChannelId) assert.Equal(t, channel.Id, channelMembers[0].ChannelId)
assert.Equal(t, user.Id, channelMembers[0].UserId) assert.Equal(t, user.Id, channelMembers[0].UserId)
assert.Equal(t, user.Email, channelMembers[0].UserEmail) assert.Equal(t, user.Email, channelMembers[0].UserEmail)
assert.Equal(t, user.Username, channelMembers[0].Username)
assert.Equal(t, leaveTime+100, channelMembers[0].JoinTime) assert.Equal(t, leaveTime+100, channelMembers[0].JoinTime)
assert.Equal(t, leaveTime+200, *channelMembers[0].LeaveTime) assert.Equal(t, leaveTime+200, *channelMembers[0].LeaveTime)
} }
@@ -269,14 +255,12 @@ func testPermanentDeleteBatch(t *testing.T, ss store.Store) {
user := model.User{ user := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user = *store.Must(ss.User().Save(&user)).(*model.User) user = *store.Must(ss.User().Save(&user)).(*model.User)
user2 := model.User{ user2 := model.User{
Email: model.NewId() + "@mattermost.com", Email: model.NewId() + "@mattermost.com",
Nickname: model.NewId(), Nickname: model.NewId(),
Username: model.NewId(),
} }
user2 = *store.Must(ss.User().Save(&user2)).(*model.User) user2 = *store.Must(ss.User().Save(&user2)).(*model.User)

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

@@ -341,8 +341,7 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
// and two users that are a part of that team // and two users that are a part of that team
user1 := &model.User{ user1 := &model.User{
Email: model.NewId(), Email: model.NewId(),
Username: model.NewId(),
} }
user1 = store.Must(ss.User().Save(user1)).(*model.User) user1 = store.Must(ss.User().Save(user1)).(*model.User)
store.Must(ss.Team().SaveMember(&model.TeamMember{ store.Must(ss.Team().SaveMember(&model.TeamMember{
@@ -351,8 +350,7 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
}, -1)) }, -1))
user2 := &model.User{ user2 := &model.User{
Email: model.NewId(), Email: model.NewId(),
Username: model.NewId(),
} }
user2 = store.Must(ss.User().Save(user2)).(*model.User) user2 = store.Must(ss.User().Save(user2)).(*model.User)
store.Must(ss.Team().SaveMember(&model.TeamMember{ store.Must(ss.Team().SaveMember(&model.TeamMember{
@@ -417,7 +415,6 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName) assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName)
assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId) assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId)
assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail) assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail)
assert.Equal(t, user1.Username, *messageExportMap[post1.Id].Username)
// post2 was made by user1 in channel1 and team1 // post2 was made by user1 in channel1 and team1
assert.Equal(t, post2.Id, *messageExportMap[post2.Id].PostId) assert.Equal(t, post2.Id, *messageExportMap[post2.Id].PostId)
@@ -427,7 +424,6 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName) assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName)
assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId) assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId)
assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail) assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail)
assert.Equal(t, user1.Username, *messageExportMap[post2.Id].Username)
// post3 is a DM between user1 and user2 // post3 is a DM between user1 and user2
assert.Equal(t, post3.Id, *messageExportMap[post3.Id].PostId) assert.Equal(t, post3.Id, *messageExportMap[post3.Id].PostId)
@@ -436,5 +432,4 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
assert.Equal(t, directMessageChannel.Id, *messageExportMap[post3.Id].ChannelId) assert.Equal(t, directMessageChannel.Id, *messageExportMap[post3.Id].ChannelId)
assert.Equal(t, user1.Id, *messageExportMap[post3.Id].UserId) assert.Equal(t, user1.Id, *messageExportMap[post3.Id].UserId)
assert.Equal(t, user1.Email, *messageExportMap[post3.Id].UserEmail) assert.Equal(t, user1.Email, *messageExportMap[post3.Id].UserEmail)
assert.Equal(t, user1.Username, *messageExportMap[post3.Id].Username)
} }

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

@@ -27,7 +27,7 @@ func TestPostStore(t *testing.T, ss store.Store) {
t.Run("PermDelete1Level", func(t *testing.T) { testPostStorePermDelete1Level(t, ss) }) t.Run("PermDelete1Level", func(t *testing.T) { testPostStorePermDelete1Level(t, ss) })
t.Run("PermDelete1Level2", func(t *testing.T) { testPostStorePermDelete1Level2(t, ss) }) t.Run("PermDelete1Level2", func(t *testing.T) { testPostStorePermDelete1Level2(t, ss) })
t.Run("GetWithChildren", func(t *testing.T) { testPostStoreGetWithChildren(t, ss) }) t.Run("GetWithChildren", func(t *testing.T) { testPostStoreGetWithChildren(t, ss) })
t.Run("GetPostsWithDetails", func(t *testing.T) { testPostStoreGetPostsWithDetails(t, ss) }) t.Run("GetPostsWtihDetails", func(t *testing.T) { testPostStoreGetPostsWtihDetails(t, ss) })
t.Run("GetPostsBeforeAfter", func(t *testing.T) { testPostStoreGetPostsBeforeAfter(t, ss) }) t.Run("GetPostsBeforeAfter", func(t *testing.T) { testPostStoreGetPostsBeforeAfter(t, ss) })
t.Run("GetPostsSince", func(t *testing.T) { testPostStoreGetPostsSince(t, ss) }) t.Run("GetPostsSince", func(t *testing.T) { testPostStoreGetPostsSince(t, ss) })
t.Run("Search", func(t *testing.T) { testPostStoreSearch(t, ss) }) t.Run("Search", func(t *testing.T) { testPostStoreSearch(t, ss) })
@@ -490,7 +490,7 @@ func testPostStoreGetWithChildren(t *testing.T, ss store.Store) {
} }
} }
func testPostStoreGetPostsWithDetails(t *testing.T, ss store.Store) { func testPostStoreGetPostsWtihDetails(t *testing.T, ss store.Store) {
o1 := &model.Post{} o1 := &model.Post{}
o1.ChannelId = model.NewId() o1.ChannelId = model.NewId()
o1.UserId = model.NewId() o1.UserId = model.NewId()
@@ -591,25 +591,6 @@ func testPostStoreGetPostsWithDetails(t *testing.T, ss store.Store) {
if r2.Posts[o1.Id].Message != o1.Message { if r2.Posts[o1.Id].Message != o1.Message {
t.Fatal("Missing parent") t.Fatal("Missing parent")
} }
// Run once to fill cache
<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)
o6 := &model.Post{}
o6.ChannelId = o1.ChannelId
o6.UserId = model.NewId()
o6.Message = "zz" + model.NewId() + "b"
o6 = (<-ss.Post().Save(o6)).Data.(*model.Post)
// Should only be 6 since we hit the cache
r3 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)).Data.(*model.PostList)
assert.Equal(t, 6, len(r3.Order))
ss.Post().InvalidateLastPostTimeCache(o1.ChannelId)
// Cache was invalidated, we should get all the posts
r4 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)).Data.(*model.PostList)
assert.Equal(t, 7, len(r4.Order))
} }
func testPostStoreGetPostsBeforeAfter(t *testing.T, ss store.Store) { func testPostStoreGetPostsBeforeAfter(t *testing.T, ss store.Store) {

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

@@ -1,91 +0,0 @@
{{define "globalrelay_compliance_export"}}
<style type="text/css">
body {
font-family:Arial, sans-serif;
font-size:14px;
font-weight:normal;
}
.summary-list ul {
padding: 0px;
list-style:none;
}
.summary-list li {
display: inline;
padding: 0 1em 0 0;
}
.summary-list .bold {
font-weight: bold;
}
.participants {
border-collapse:collapse;
border-spacing:0;
}
.participants td {
padding:10px 5px;
border:1px solid black;
overflow:hidden;
text-align: center;
word-break:normal;
}
.participants th {
padding:10px 5px;
border:1px solid black;
overflow:hidden;
word-break:normal;
}
.participants th,td {
vertical-align:top
}
.message-list ul {
list-style:none;
padding: 0;
}
.message-list li {
padding: 0 0 1em 0;
}
.message .sent_time {
font-weight:bold;
}
.message .username {
font-weight:bold;
}
.message .email {
font-weight: bold;
}
</style>
<h1>Mattermost Compliance Export</h1>
<h2>Conversation Summary</h2>
<div class="summary-list">
<ul>
<li><span class="bold">Channel:&nbsp;</span>{{.Props.ChannelName}}</li>
<li><span class="bold">Started:&nbsp;</span>{{.Props.Started}}</li>
<li><span class="bold">Ended:&nbsp;</span>{{.Props.Ended}}</li>
<li><span class="bold">Duration:&nbsp;</span>{{.Props.Duration}}&nbsp;Minutes</li>
</ul>
</div>
<table class="participants">
<tr>
<th class="username">Username<br></th>
<th class="email">Email</th>
<th class="joined">Joined</th>
<th class="left">Left</th>
<th class="duration">Duration</th>
<th class="messages">Messages</th>
</tr>
{{.Props.ParticipantRows}}
</table>
<h2>Messages</h2>
<div class="message-list">
<ul>
{{.Props.Messages}}
</ul>
</div>
<p>Exported on {{.Props.ExportDate}}</p>
{{end}}

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

@@ -1,8 +0,0 @@
{{define "globalrelay_compliance_export_message"}}
<li class="message">
<span class="sent_time">{{.Props.SentTime}}</span>
<span class="username">@{{.Props.Username}}</span>
<span class="email">({{.Props.Email}}):</span>
<span class="message">{{.Props.Message}}</span>
</li>
{{end}}

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

@@ -1,10 +0,0 @@
{{define "globalrelay_compliance_export_participant_row"}}
<tr>
<td class="username">@{{.Props.Username}}</td>
<td class="email">{{.Props.Email}}</td>
<td class="joined">{{.Props.Joined}}</td>
<td class="left">{{.Props.Left}}</td>
<td class="duration">{{.Props.DurationMinutes}} Minutes</td>
<td class="messages">{{.Props.NumMessages}}</td>
</tr>
{{end}}

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

@@ -4,9 +4,6 @@
package utils package utils
import ( import (
"crypto"
"crypto/rand"
"encoding/base64"
"fmt" "fmt"
"html/template" "html/template"
"net/http" "net/http"
@@ -35,25 +32,13 @@ func OriginChecker(allowedOrigins string) func(*http.Request) bool {
} }
} }
func RenderWebAppError(w http.ResponseWriter, r *http.Request, err *model.AppError, s crypto.Signer) { func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request) {
RenderWebError(w, r, err.StatusCode, url.Values{ status := http.StatusTemporaryRedirect
"message": []string{err.Message}, if err.StatusCode != http.StatusInternalServerError {
}, s) status = err.StatusCode
}
func RenderWebError(w http.ResponseWriter, r *http.Request, status int, params url.Values, s crypto.Signer) {
queryString := params.Encode()
h := crypto.SHA256
sum := h.New()
sum.Write([]byte("/error?" + queryString))
signature, err := s.Sign(rand.Reader, sum.Sum(nil), h)
if err != nil {
http.Error(w, "", http.StatusInternalServerError)
return
} }
destination := strings.TrimRight(GetSiteURL(), "/") + "/error?" + queryString + "&s=" + base64.URLEncoding.EncodeToString(signature)
destination := strings.TrimRight(GetSiteURL(), "/") + "/error?message=" + url.QueryEscape(err.Message)
if status >= 300 && status < 400 { if status >= 300 && status < 400 {
http.Redirect(w, r, destination, status) http.Redirect(w, r, destination, status)
return return

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

@@ -1,49 +0,0 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
package utils
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"encoding/asn1"
"encoding/base64"
"math/big"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRenderWebError(t *testing.T) {
r := httptest.NewRequest("GET", "http://foo", nil)
w := httptest.NewRecorder()
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)
RenderWebError(w, r, http.StatusTemporaryRedirect, url.Values{
"foo": []string{"bar"},
}, key)
resp := w.Result()
location, err := url.Parse(resp.Header.Get("Location"))
require.NoError(t, err)
require.NotEmpty(t, location.Query().Get("s"))
type ecdsaSignature struct {
R, S *big.Int
}
var rs ecdsaSignature
s, err := base64.URLEncoding.DecodeString(location.Query().Get("s"))
require.NoError(t, err)
_, err = asn1.Unmarshal(s, &rs)
require.NoError(t, err)
assert.Equal(t, "bar", location.Query().Get("foo"))
h := sha256.Sum256([]byte("/error?foo=bar"))
assert.True(t, ecdsa.Verify(&key.PublicKey, h[:], rs.R, rs.S))
}

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

@@ -7,7 +7,7 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
) )
func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*model.Role { func DefaultRolesBasedOnConfig(cfg *model.Config) map[string]*model.Role {
roles := make(map[string]*model.Role) roles := make(map[string]*model.Role)
for id, role := range model.DefaultRoles { for id, role := range model.DefaultRoles {
copy := &model.Role{} copy := &model.Role{}
@@ -15,7 +15,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
roles[id] = copy roles[id] = copy
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPublicChannelCreation { switch *cfg.TeamSettings.RestrictPublicChannelCreation {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -35,7 +35,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPublicChannelManagement { switch *cfg.TeamSettings.RestrictPublicChannelManagement {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -64,7 +64,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPublicChannelDeletion { switch *cfg.TeamSettings.RestrictPublicChannelDeletion {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -93,7 +93,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPrivateChannelCreation { switch *cfg.TeamSettings.RestrictPrivateChannelCreation {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -113,7 +113,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPrivateChannelManagement { switch *cfg.TeamSettings.RestrictPrivateChannelManagement {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -142,7 +142,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPrivateChannelDeletion { switch *cfg.TeamSettings.RestrictPrivateChannelDeletion {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.TEAM_USER_ROLE_ID].Permissions = append( roles[model.TEAM_USER_ROLE_ID].Permissions = append(
@@ -172,7 +172,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
} }
// Restrict permissions for Private Channel Manage Members // Restrict permissions for Private Channel Manage Members
if isLicensed { if IsLicensed() {
switch *cfg.TeamSettings.RestrictPrivateChannelManageMembers { switch *cfg.TeamSettings.RestrictPrivateChannelManageMembers {
case model.PERMISSIONS_ALL: case model.PERMISSIONS_ALL:
roles[model.CHANNEL_USER_ROLE_ID].Permissions = append( roles[model.CHANNEL_USER_ROLE_ID].Permissions = append(
@@ -214,7 +214,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
} }
// Grant permissions for inviting and adding users to a team. // Grant permissions for inviting and adding users to a team.
if isLicensed { if IsLicensed() {
if *cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_TEAM_ADMIN { if *cfg.TeamSettings.RestrictTeamInvite == model.PERMISSIONS_TEAM_ADMIN {
roles[model.TEAM_ADMIN_ROLE_ID].Permissions = append( roles[model.TEAM_ADMIN_ROLE_ID].Permissions = append(
roles[model.TEAM_ADMIN_ROLE_ID].Permissions, roles[model.TEAM_ADMIN_ROLE_ID].Permissions,
@@ -236,7 +236,7 @@ func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) map[string]*m
) )
} }
if isLicensed { if IsLicensed() {
switch *cfg.ServiceSettings.RestrictPostDelete { switch *cfg.ServiceSettings.RestrictPostDelete {
case model.PERMISSIONS_DELETE_POST_ALL: case model.PERMISSIONS_DELETE_POST_ALL:
roles[model.CHANNEL_USER_ROLE_ID].Permissions = append( roles[model.CHANNEL_USER_ROLE_ID].Permissions = append(

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

@@ -342,7 +342,7 @@ func LoadConfig(fileName string) (config *model.Config, configPath string, appEr
return config, configPath, nil return config, configPath, nil
} }
func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.License) map[string]string { func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]string {
props := make(map[string]string) props := make(map[string]string)
props["Version"] = model.CurrentVersion props["Version"] = model.CurrentVersion
@@ -459,17 +459,18 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
hasImageProxy := c.ServiceSettings.ImageProxyType != nil && *c.ServiceSettings.ImageProxyType != "" && c.ServiceSettings.ImageProxyURL != nil && *c.ServiceSettings.ImageProxyURL != "" hasImageProxy := c.ServiceSettings.ImageProxyType != nil && *c.ServiceSettings.ImageProxyType != "" && c.ServiceSettings.ImageProxyURL != nil && *c.ServiceSettings.ImageProxyURL != ""
props["HasImageProxy"] = strconv.FormatBool(hasImageProxy) props["HasImageProxy"] = strconv.FormatBool(hasImageProxy)
if license != nil { if IsLicensed() {
License := License()
props["ExperimentalTownSquareIsReadOnly"] = strconv.FormatBool(*c.TeamSettings.ExperimentalTownSquareIsReadOnly) props["ExperimentalTownSquareIsReadOnly"] = strconv.FormatBool(*c.TeamSettings.ExperimentalTownSquareIsReadOnly)
props["ExperimentalEnableAuthenticationTransfer"] = strconv.FormatBool(*c.ServiceSettings.ExperimentalEnableAuthenticationTransfer) props["ExperimentalEnableAuthenticationTransfer"] = strconv.FormatBool(*c.ServiceSettings.ExperimentalEnableAuthenticationTransfer)
if *license.Features.CustomBrand { if *License.Features.CustomBrand {
props["EnableCustomBrand"] = strconv.FormatBool(*c.TeamSettings.EnableCustomBrand) props["EnableCustomBrand"] = strconv.FormatBool(*c.TeamSettings.EnableCustomBrand)
props["CustomBrandText"] = *c.TeamSettings.CustomBrandText props["CustomBrandText"] = *c.TeamSettings.CustomBrandText
props["CustomDescriptionText"] = *c.TeamSettings.CustomDescriptionText props["CustomDescriptionText"] = *c.TeamSettings.CustomDescriptionText
} }
if *license.Features.LDAP { if *License.Features.LDAP {
props["EnableLdap"] = strconv.FormatBool(*c.LdapSettings.Enable) props["EnableLdap"] = strconv.FormatBool(*c.LdapSettings.Enable)
props["LdapLoginFieldName"] = *c.LdapSettings.LoginFieldName props["LdapLoginFieldName"] = *c.LdapSettings.LoginFieldName
props["LdapNicknameAttributeSet"] = strconv.FormatBool(*c.LdapSettings.NicknameAttribute != "") props["LdapNicknameAttributeSet"] = strconv.FormatBool(*c.LdapSettings.NicknameAttribute != "")
@@ -480,16 +481,16 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["LdapLoginButtonTextColor"] = *c.LdapSettings.LoginButtonTextColor props["LdapLoginButtonTextColor"] = *c.LdapSettings.LoginButtonTextColor
} }
if *license.Features.MFA { if *License.Features.MFA {
props["EnableMultifactorAuthentication"] = strconv.FormatBool(*c.ServiceSettings.EnableMultifactorAuthentication) props["EnableMultifactorAuthentication"] = strconv.FormatBool(*c.ServiceSettings.EnableMultifactorAuthentication)
props["EnforceMultifactorAuthentication"] = strconv.FormatBool(*c.ServiceSettings.EnforceMultifactorAuthentication) props["EnforceMultifactorAuthentication"] = strconv.FormatBool(*c.ServiceSettings.EnforceMultifactorAuthentication)
} }
if *license.Features.Compliance { if *License.Features.Compliance {
props["EnableCompliance"] = strconv.FormatBool(*c.ComplianceSettings.Enable) props["EnableCompliance"] = strconv.FormatBool(*c.ComplianceSettings.Enable)
} }
if *license.Features.SAML { if *License.Features.SAML {
props["EnableSaml"] = strconv.FormatBool(*c.SamlSettings.Enable) props["EnableSaml"] = strconv.FormatBool(*c.SamlSettings.Enable)
props["SamlLoginButtonText"] = *c.SamlSettings.LoginButtonText props["SamlLoginButtonText"] = *c.SamlSettings.LoginButtonText
props["SamlFirstNameAttributeSet"] = strconv.FormatBool(*c.SamlSettings.FirstNameAttribute != "") props["SamlFirstNameAttributeSet"] = strconv.FormatBool(*c.SamlSettings.FirstNameAttribute != "")
@@ -500,23 +501,23 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["SamlLoginButtonTextColor"] = *c.SamlSettings.LoginButtonTextColor props["SamlLoginButtonTextColor"] = *c.SamlSettings.LoginButtonTextColor
} }
if *license.Features.Cluster { if *License.Features.Cluster {
props["EnableCluster"] = strconv.FormatBool(*c.ClusterSettings.Enable) props["EnableCluster"] = strconv.FormatBool(*c.ClusterSettings.Enable)
} }
if *license.Features.Cluster { if *License.Features.Cluster {
props["EnableMetrics"] = strconv.FormatBool(*c.MetricsSettings.Enable) props["EnableMetrics"] = strconv.FormatBool(*c.MetricsSettings.Enable)
} }
if *license.Features.GoogleOAuth { if *License.Features.GoogleOAuth {
props["EnableSignUpWithGoogle"] = strconv.FormatBool(c.GoogleSettings.Enable) props["EnableSignUpWithGoogle"] = strconv.FormatBool(c.GoogleSettings.Enable)
} }
if *license.Features.Office365OAuth { if *License.Features.Office365OAuth {
props["EnableSignUpWithOffice365"] = strconv.FormatBool(c.Office365Settings.Enable) props["EnableSignUpWithOffice365"] = strconv.FormatBool(c.Office365Settings.Enable)
} }
if *license.Features.PasswordRequirements { if *License.Features.PasswordRequirements {
props["PasswordMinimumLength"] = fmt.Sprintf("%v", *c.PasswordSettings.MinimumLength) props["PasswordMinimumLength"] = fmt.Sprintf("%v", *c.PasswordSettings.MinimumLength)
props["PasswordRequireLowercase"] = strconv.FormatBool(*c.PasswordSettings.Lowercase) props["PasswordRequireLowercase"] = strconv.FormatBool(*c.PasswordSettings.Lowercase)
props["PasswordRequireUppercase"] = strconv.FormatBool(*c.PasswordSettings.Uppercase) props["PasswordRequireUppercase"] = strconv.FormatBool(*c.PasswordSettings.Uppercase)
@@ -524,7 +525,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["PasswordRequireSymbol"] = strconv.FormatBool(*c.PasswordSettings.Symbol) props["PasswordRequireSymbol"] = strconv.FormatBool(*c.PasswordSettings.Symbol)
} }
if *license.Features.Announcement { if *License.Features.Announcement {
props["EnableBanner"] = strconv.FormatBool(*c.AnnouncementSettings.EnableBanner) props["EnableBanner"] = strconv.FormatBool(*c.AnnouncementSettings.EnableBanner)
props["BannerText"] = *c.AnnouncementSettings.BannerText props["BannerText"] = *c.AnnouncementSettings.BannerText
props["BannerColor"] = *c.AnnouncementSettings.BannerColor props["BannerColor"] = *c.AnnouncementSettings.BannerColor
@@ -532,14 +533,14 @@ func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.L
props["AllowBannerDismissal"] = strconv.FormatBool(*c.AnnouncementSettings.AllowBannerDismissal) props["AllowBannerDismissal"] = strconv.FormatBool(*c.AnnouncementSettings.AllowBannerDismissal)
} }
if *license.Features.ThemeManagement { if *License.Features.ThemeManagement {
props["EnableThemeSelection"] = strconv.FormatBool(*c.ThemeSettings.EnableThemeSelection) props["EnableThemeSelection"] = strconv.FormatBool(*c.ThemeSettings.EnableThemeSelection)
props["DefaultTheme"] = *c.ThemeSettings.DefaultTheme props["DefaultTheme"] = *c.ThemeSettings.DefaultTheme
props["AllowCustomThemes"] = strconv.FormatBool(*c.ThemeSettings.AllowCustomThemes) props["AllowCustomThemes"] = strconv.FormatBool(*c.ThemeSettings.AllowCustomThemes)
props["AllowedThemes"] = strings.Join(c.ThemeSettings.AllowedThemes, ",") props["AllowedThemes"] = strings.Join(c.ThemeSettings.AllowedThemes, ",")
} }
if *license.Features.DataRetention { if *License.Features.DataRetention {
props["DataRetentionEnableMessageDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableMessageDeletion) props["DataRetentionEnableMessageDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableMessageDeletion)
props["DataRetentionMessageRetentionDays"] = strconv.FormatInt(int64(*c.DataRetentionSettings.MessageRetentionDays), 10) props["DataRetentionMessageRetentionDays"] = strconv.FormatInt(int64(*c.DataRetentionSettings.MessageRetentionDays), 10)
props["DataRetentionEnableFileDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableFileDeletion) props["DataRetentionEnableFileDeletion"] = strconv.FormatBool(*c.DataRetentionSettings.EnableFileDeletion)

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

@@ -197,7 +197,7 @@ func TestGetClientConfig(t *testing.T) {
cfg, _, err := LoadConfig("config.json") cfg, _, err := LoadConfig("config.json")
require.Nil(t, err) require.Nil(t, err)
configMap := GenerateClientConfig(cfg, "", nil) configMap := GenerateClientConfig(cfg, "")
if configMap["EmailNotificationContentsType"] != *cfg.EmailSettings.EmailNotificationContentsType { if configMap["EmailNotificationContentsType"] != *cfg.EmailSettings.EmailNotificationContentsType {
t.Fatal("EmailSettings.EmailNotificationContentsType not exposed to client config") t.Fatal("EmailSettings.EmailNotificationContentsType not exposed to client config")
} }

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

@@ -22,7 +22,7 @@ type FileBackend interface {
RemoveDirectory(path string) *model.AppError RemoveDirectory(path string) *model.AppError
} }
func NewFileBackend(settings *model.FileSettings, enableComplianceFeatures bool) (FileBackend, *model.AppError) { func NewFileBackend(settings *model.FileSettings) (FileBackend, *model.AppError) {
switch *settings.DriverName { switch *settings.DriverName {
case model.IMAGE_DRIVER_S3: case model.IMAGE_DRIVER_S3:
return &S3FileBackend{ return &S3FileBackend{
@@ -33,7 +33,7 @@ func NewFileBackend(settings *model.FileSettings, enableComplianceFeatures bool)
signV2: settings.AmazonS3SignV2 != nil && *settings.AmazonS3SignV2, signV2: settings.AmazonS3SignV2 != nil && *settings.AmazonS3SignV2,
region: settings.AmazonS3Region, region: settings.AmazonS3Region,
bucket: settings.AmazonS3Bucket, bucket: settings.AmazonS3Bucket,
encrypt: settings.AmazonS3SSE != nil && *settings.AmazonS3SSE && enableComplianceFeatures, encrypt: settings.AmazonS3SSE != nil && *settings.AmazonS3SSE && IsLicensed() && *License().Features.Compliance,
trace: settings.AmazonS3Trace != nil && *settings.AmazonS3Trace, trace: settings.AmazonS3Trace != nil && *settings.AmazonS3Trace,
}, nil }, nil
case model.IMAGE_DRIVER_LOCAL: case model.IMAGE_DRIVER_LOCAL:

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

@@ -63,7 +63,7 @@ func TestS3FileBackendTestSuite(t *testing.T) {
func (s *FileBackendTestSuite) SetupTest() { func (s *FileBackendTestSuite) SetupTest() {
TranslationsPreInit() TranslationsPreInit()
backend, err := NewFileBackend(&s.settings, true) backend, err := NewFileBackend(&s.settings)
require.Nil(s.T(), err) require.Nil(s.T(), err)
s.backend = backend s.backend = backend
} }

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

@@ -23,7 +23,7 @@ type HTMLTemplateWatcher struct {
func NewHTMLTemplateWatcher(directory string) (*HTMLTemplateWatcher, error) { func NewHTMLTemplateWatcher(directory string) (*HTMLTemplateWatcher, error) {
templatesDir, _ := FindDir(directory) templatesDir, _ := FindDir(directory)
l4g.Debug("Parsing server templates at %v", templatesDir) l4g.Debug(T("api.api.init.parsing_templates.debug"), templatesDir)
ret := &HTMLTemplateWatcher{ ret := &HTMLTemplateWatcher{
stop: make(chan struct{}), stop: make(chan struct{}),
@@ -55,15 +55,15 @@ func NewHTMLTemplateWatcher(directory string) (*HTMLTemplateWatcher, error) {
return return
case event := <-watcher.Events: case event := <-watcher.Events:
if event.Op&fsnotify.Write == fsnotify.Write { if event.Op&fsnotify.Write == fsnotify.Write {
l4g.Info("Re-parsing templates because of modified file %v", event.Name) l4g.Info(T("web.reparse_templates.info"), event.Name)
if htmlTemplates, err := template.ParseGlob(templatesDir + "*.html"); err != nil { if htmlTemplates, err := template.ParseGlob(templatesDir + "*.html"); err != nil {
l4g.Error("Failed to parse templates %v", err) l4g.Error(T("web.parsing_templates.error"), err)
} else { } else {
ret.templates.Store(htmlTemplates) ret.templates.Store(htmlTemplates)
} }
} }
case err := <-watcher.Errors: case err := <-watcher.Errors:
l4g.Error("Failed in directory watcher %s", err) l4g.Error(T("web.dir_fail.error"), err)
} }
} }
}() }()

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

@@ -4,7 +4,6 @@
package utils package utils
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@@ -38,12 +37,6 @@ type JSONMessageInbucket struct {
Text string Text string
HTML string `json:"Html"` HTML string `json:"Html"`
} }
Attachments []struct {
Filename string
ContentType string `json:"content-type"`
DownloadLink string `json:"download-link"`
Bytes []byte `json:"-"`
}
} }
func ParseEmail(email string) string { func ParseEmail(email string) string {
@@ -96,54 +89,21 @@ func GetMessageFromMailbox(email, id string) (results JSONMessageInbucket, err e
var record JSONMessageInbucket var record JSONMessageInbucket
url := fmt.Sprintf("%s%s%s/%s", getInbucketHost(), INBUCKET_API, parsedEmail, id) url := fmt.Sprintf("%s%s%s/%s", getInbucketHost(), INBUCKET_API, parsedEmail, id)
emailResponse, err := get(url) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return record, err return record, err
} }
defer emailResponse.Body.Close()
err = json.NewDecoder(emailResponse.Body).Decode(&record)
// download attachments
if record.Attachments != nil && len(record.Attachments) > 0 {
for i := range record.Attachments {
if bytes, err := downloadAttachment(record.Attachments[i].DownloadLink); err != nil {
return record, err
} else {
record.Attachments[i].Bytes = make([]byte, len(bytes))
copy(record.Attachments[i].Bytes, bytes)
}
}
}
return record, err
}
func downloadAttachment(url string) ([]byte, error) {
attachmentResponse, err := get(url)
if err != nil {
return nil, err
}
defer attachmentResponse.Body.Close()
buf := new(bytes.Buffer)
io.Copy(buf, attachmentResponse.Body)
return buf.Bytes(), nil
}
func get(url string) (*http.Response, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{} client := &http.Client{}
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
return nil, err return record, err
} }
defer resp.Body.Close()
return resp, nil err = json.NewDecoder(resp.Body).Decode(&record)
return record, err
} }
func DeleteMailBox(email string) (err error) { func DeleteMailBox(email string) (err error) {

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

@@ -5,21 +5,28 @@ package utils
import ( import (
"crypto" "crypto"
"crypto/md5"
"crypto/rsa" "crypto/rsa"
"crypto/sha512" "crypto/sha512"
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/pem" "encoding/pem"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync/atomic"
l4g "github.com/alecthomas/log4go" l4g "github.com/alecthomas/log4go"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
) )
var isLicensedInt32 int32
var licenseValue atomic.Value
var clientLicenseValue atomic.Value
var publicKey []byte = []byte(`-----BEGIN PUBLIC KEY----- var publicKey []byte = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyZmShlU8Z8HdG0IWSZ8r MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyZmShlU8Z8HdG0IWSZ8r
tSyzyxrXkJjsFUf0Ke7bm/TLtIggRdqOcUF3XEWqQk5RGD5vuq7Rlg1zZqMEBk8N tSyzyxrXkJjsFUf0Ke7bm/TLtIggRdqOcUF3XEWqQk5RGD5vuq7Rlg1zZqMEBk8N
@@ -30,6 +37,92 @@ a0v85XL6i9ote2P+fLZ3wX9EoioHzgdgB7arOxY50QRJO7OyCqpKFKv6lRWTXuSt
hwIDAQAB hwIDAQAB
-----END PUBLIC KEY-----`) -----END PUBLIC KEY-----`)
func init() {
SetLicense(nil)
}
func IsLicensed() bool {
return atomic.LoadInt32(&isLicensedInt32) == 1
}
func SetIsLicensed(v bool) {
if v {
atomic.StoreInt32(&isLicensedInt32, 1)
} else {
atomic.StoreInt32(&isLicensedInt32, 0)
}
}
func License() *model.License {
return licenseValue.Load().(*model.License)
}
func SetClientLicense(m map[string]string) {
clientLicenseValue.Store(m)
}
func ClientLicense() map[string]string {
return clientLicenseValue.Load().(map[string]string)
}
func LoadLicense(licenseBytes []byte) {
if success, licenseStr := ValidateLicense(licenseBytes); success {
license := model.LicenseFromJson(strings.NewReader(licenseStr))
SetLicense(license)
return
}
l4g.Warn(T("utils.license.load_license.invalid.warn"))
}
var licenseListeners = map[string]func(){}
func AddLicenseListener(listener func()) string {
id := model.NewId()
licenseListeners[id] = listener
return id
}
func RemoveLicenseListener(id string) {
delete(licenseListeners, id)
}
func SetLicense(license *model.License) bool {
defer func() {
for _, listener := range licenseListeners {
listener()
}
}()
if license == nil {
SetIsLicensed(false)
license = &model.License{
Features: new(model.Features),
}
license.Features.SetDefaults()
licenseValue.Store(license)
SetClientLicense(map[string]string{"IsLicensed": "false"})
return false
} else {
license.Features.SetDefaults()
if !license.IsExpired() {
licenseValue.Store(license)
SetIsLicensed(true)
clientLicenseValue.Store(getClientLicense(license))
return true
}
return false
}
}
func RemoveLicense() {
SetLicense(nil)
}
func ValidateLicense(signed []byte) (bool, string) { func ValidateLicense(signed []byte) (bool, string) {
decoded := make([]byte, base64.StdEncoding.DecodedLen(len(signed))) decoded := make([]byte, base64.StdEncoding.DecodedLen(len(signed)))
@@ -120,12 +213,12 @@ func GetLicenseFileLocation(fileLocation string) string {
} }
} }
func GetClientLicense(l *model.License) map[string]string { func getClientLicense(l *model.License) map[string]string {
props := make(map[string]string) props := make(map[string]string)
props["IsLicensed"] = strconv.FormatBool(l != nil) props["IsLicensed"] = strconv.FormatBool(IsLicensed())
if l != nil { if IsLicensed() {
props["Id"] = l.Id props["Id"] = l.Id
props["Users"] = strconv.Itoa(*l.Features.Users) props["Users"] = strconv.Itoa(*l.Features.Users)
props["LDAP"] = strconv.FormatBool(*l.Features.LDAP) props["LDAP"] = strconv.FormatBool(*l.Features.LDAP)
@@ -155,3 +248,39 @@ func GetClientLicense(l *model.License) map[string]string {
return props return props
} }
func GetClientLicenseEtag(useSanitized bool) string {
value := ""
lic := ClientLicense()
if useSanitized {
lic = GetSanitizedClientLicense()
}
for k, v := range lic {
value += fmt.Sprintf("%s:%s;", k, v)
}
return model.Etag(fmt.Sprintf("%x", md5.Sum([]byte(value))))
}
func GetSanitizedClientLicense() map[string]string {
sanitizedLicense := make(map[string]string)
for k, v := range ClientLicense() {
sanitizedLicense[k] = v
}
if IsLicensed() {
delete(sanitizedLicense, "Id")
delete(sanitizedLicense, "Name")
delete(sanitizedLicense, "Email")
delete(sanitizedLicense, "PhoneNumber")
delete(sanitizedLicense, "IssuedAt")
delete(sanitizedLicense, "StartsAt")
delete(sanitizedLicense, "ExpiresAt")
}
return sanitizedLicense
}

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

@@ -5,20 +5,87 @@ package utils
import ( import (
"testing" "testing"
"github.com/mattermost/mattermost-server/model"
) )
func TestSetLicense(t *testing.T) {
l1 := &model.License{}
l1.Features = &model.Features{}
l1.Customer = &model.Customer{}
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
if ok := SetLicense(l1); !ok {
t.Fatal("license should have worked")
}
l2 := &model.License{}
l2.Features = &model.Features{}
l2.Customer = &model.Customer{}
l2.StartsAt = model.GetMillis() - 1000
l2.ExpiresAt = model.GetMillis() - 100
if ok := SetLicense(l2); ok {
t.Fatal("license should have failed")
}
l3 := &model.License{}
l3.Features = &model.Features{}
l3.Customer = &model.Customer{}
l3.StartsAt = model.GetMillis() + 10000
l3.ExpiresAt = model.GetMillis() + 100000
if ok := SetLicense(l3); !ok {
t.Fatal("license should have passed")
}
}
func TestValidateLicense(t *testing.T) { func TestValidateLicense(t *testing.T) {
b1 := []byte("junk") b1 := []byte("junk")
if ok, _ := ValidateLicense(b1); ok { if ok, _ := ValidateLicense(b1); ok {
t.Fatal("should have failed - bad license") t.Fatal("should have failed - bad license")
} }
LoadLicense(b1)
b2 := []byte("junkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunk") b2 := []byte("junkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunk")
if ok, _ := ValidateLicense(b2); ok { if ok, _ := ValidateLicense(b2); ok {
t.Fatal("should have failed - bad license") t.Fatal("should have failed - bad license")
} }
} }
func TestClientLicenseEtag(t *testing.T) {
etag1 := GetClientLicenseEtag(false)
SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "true"})
etag2 := GetClientLicenseEtag(false)
if etag1 == etag2 {
t.Fatal("etags should not match")
}
SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "false"})
etag3 := GetClientLicenseEtag(false)
if etag2 == etag3 {
t.Fatal("etags should not match")
}
}
func TestGetSanitizedClientLicense(t *testing.T) {
l1 := &model.License{}
l1.Features = &model.Features{}
l1.Customer = &model.Customer{}
l1.Customer.Name = "TestName"
l1.StartsAt = model.GetMillis() - 1000
l1.ExpiresAt = model.GetMillis() + 100000
SetLicense(l1)
m := GetSanitizedClientLicense()
if _, ok := m["Name"]; ok {
t.Fatal("should have been sanatized")
}
}
func TestGetLicenseFileLocation(t *testing.T) { func TestGetLicenseFileLocation(t *testing.T) {
fileName := GetLicenseFileLocation("") fileName := GetLicenseFileLocation("")
if len(fileName) == 0 { if len(fileName) == 0 {

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

@@ -15,8 +15,6 @@ import (
"net/http" "net/http"
"io"
l4g "github.com/alecthomas/log4go" l4g "github.com/alecthomas/log4go"
"github.com/mattermost/html2text" "github.com/mattermost/html2text"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
@@ -105,73 +103,37 @@ func TestConnection(config *model.Config) {
defer c.Close() defer c.Close()
} }
func SendMailUsingConfig(to, subject, htmlBody string, config *model.Config, enableComplianceFeatures bool) *model.AppError { func SendMailUsingConfig(to, subject, htmlBody string, config *model.Config) *model.AppError {
fromMail := mail.Address{Name: config.EmailSettings.FeedbackName, Address: config.EmailSettings.FeedbackEmail}
return sendMail(to, to, fromMail, subject, htmlBody, nil, nil, config, enableComplianceFeatures)
}
// allows for sending an email with attachments and differing MIME/SMTP recipients
func SendMailUsingConfigAdvanced(mimeTo, smtpTo string, from mail.Address, subject, htmlBody string, attachments []*model.FileInfo, mimeHeaders map[string]string, config *model.Config, enableComplianceFeatures bool) *model.AppError {
return sendMail(mimeTo, smtpTo, from, subject, htmlBody, attachments, mimeHeaders, config, enableComplianceFeatures)
}
func sendMail(mimeTo, smtpTo string, from mail.Address, subject, htmlBody string, attachments []*model.FileInfo, mimeHeaders map[string]string, config *model.Config, enableComplianceFeatures bool) *model.AppError {
if !config.EmailSettings.SendEmailNotifications || len(config.EmailSettings.SMTPServer) == 0 { if !config.EmailSettings.SendEmailNotifications || len(config.EmailSettings.SMTPServer) == 0 {
return nil return nil
} }
l4g.Debug(T("utils.mail.send_mail.sending.debug"), mimeTo, subject) l4g.Debug(T("utils.mail.send_mail.sending.debug"), to, subject)
htmlMessage := "\r\n<html><body>" + htmlBody + "</body></html>" htmlMessage := "\r\n<html><body>" + htmlBody + "</body></html>"
fromMail := mail.Address{Name: config.EmailSettings.FeedbackName, Address: config.EmailSettings.FeedbackEmail}
txtBody, err := html2text.FromString(htmlBody) txtBody, err := html2text.FromString(htmlBody)
if err != nil { if err != nil {
l4g.Warn(err) l4g.Warn(err)
txtBody = "" txtBody = ""
} }
headers := map[string][]string{ m := gomail.NewMessage(gomail.SetCharset("UTF-8"))
"From": {from.String()}, m.SetHeaders(map[string][]string{
"To": {mimeTo}, "From": {fromMail.String()},
"To": {to},
"Subject": {encodeRFC2047Word(subject)}, "Subject": {encodeRFC2047Word(subject)},
"Content-Transfer-Encoding": {"8bit"}, "Content-Transfer-Encoding": {"8bit"},
"Auto-Submitted": {"auto-generated"}, "Auto-Submitted": {"auto-generated"},
"Precedence": {"bulk"}, "Precedence": {"bulk"},
} })
if mimeHeaders != nil {
for k, v := range mimeHeaders {
headers[k] = []string{encodeRFC2047Word(v)}
}
}
m := gomail.NewMessage(gomail.SetCharset("UTF-8"))
m.SetHeaders(headers)
m.SetDateHeader("Date", time.Now()) m.SetDateHeader("Date", time.Now())
m.SetBody("text/plain", txtBody) m.SetBody("text/plain", txtBody)
m.AddAlternative("text/html", htmlMessage) m.AddAlternative("text/html", htmlMessage)
if attachments != nil {
fileBackend, err := NewFileBackend(&config.FileSettings, enableComplianceFeatures)
if err != nil {
return err
}
for _, fileInfo := range attachments {
m.Attach(fileInfo.Name, gomail.SetCopyFunc(func(writer io.Writer) error {
bytes, err := fileBackend.ReadFile(fileInfo.Path)
if err != nil {
return err
}
if _, err := writer.Write(bytes); err != nil {
return model.NewAppError("SendMail", "utils.mail.sendMail.attachments.write_error", nil, err.Error(), http.StatusInternalServerError)
}
return nil
}))
}
}
conn, err1 := connectToSMTPServer(config) conn, err1 := connectToSMTPServer(config)
if err1 != nil { if err1 != nil {
return err1 return err1
@@ -185,11 +147,11 @@ func sendMail(mimeTo, smtpTo string, from mail.Address, subject, htmlBody string
defer c.Quit() defer c.Quit()
defer c.Close() defer c.Close()
if err := c.Mail(from.Address); err != nil { if err := c.Mail(fromMail.Address); err != nil {
return model.NewAppError("SendMail", "utils.mail.send_mail.from_address.app_error", nil, err.Error(), http.StatusInternalServerError) return model.NewAppError("SendMail", "utils.mail.send_mail.from_address.app_error", nil, err.Error(), http.StatusInternalServerError)
} }
if err := c.Rcpt(smtpTo); err != nil { if err := c.Rcpt(to); err != nil {
return model.NewAppError("SendMail", "utils.mail.send_mail.to_address.app_error", nil, err.Error(), http.StatusInternalServerError) return model.NewAppError("SendMail", "utils.mail.send_mail.to_address.app_error", nil, err.Error(), http.StatusInternalServerError)
} }

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

@@ -7,10 +7,6 @@ import (
"strings" "strings"
"testing" "testing"
"net/mail"
"github.com/mattermost/mattermost-server/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -43,18 +39,18 @@ func TestSendMailUsingConfig(t *testing.T) {
require.Nil(t, err) require.Nil(t, err)
T = GetUserTranslations("en") T = GetUserTranslations("en")
var emailTo = "test@example.com" var emailTo string = "test@example.com"
var emailSubject = "Testing this email" var emailSubject string = "Testing this email"
var emailBody = "This is a test from autobot" var emailBody string = "This is a test from autobot"
//Delete all the messages before check the sample email //Delete all the messages before check the sample email
DeleteMailBox(emailTo) DeleteMailBox(emailTo)
if err := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg, true); err != nil { if err := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg); err != nil {
t.Log(err) t.Log(err)
t.Fatal("Should connect to the STMP Server") t.Fatal("Should connect to the STMP Server")
} else { } else {
//Check if the email was send to the right email address //Check if the email was send to the rigth email address
var resultsMailbox JSONMessageHeaderInbucket var resultsMailbox JSONMessageHeaderInbucket
err := RetryInbucket(5, func() error { err := RetryInbucket(5, func() error {
var err error var err error
@@ -79,78 +75,3 @@ func TestSendMailUsingConfig(t *testing.T) {
} }
} }
} }
func TestSendMailUsingConfigAdvanced(t *testing.T) {
cfg, _, err := LoadConfig("config.json")
require.Nil(t, err)
T = GetUserTranslations("en")
var mimeTo = "test@example.com"
var smtpTo = "test2@example.com"
var from = mail.Address{Name: "Nobody", Address: "nobody@mattermost.com"}
var emailSubject = "Testing this email"
var emailBody = "This is a test from autobot"
//Delete all the messages before check the sample email
DeleteMailBox(smtpTo)
// create a file that will be attached to the email
fileBackend, err := NewFileBackend(&cfg.FileSettings, true)
assert.Nil(t, err)
fileContents := []byte("hello world")
fileName := "file.txt"
assert.Nil(t, fileBackend.WriteFile(fileContents, fileName))
defer fileBackend.RemoveFile(fileName)
attachments := make([]*model.FileInfo, 1)
attachments[0] = &model.FileInfo{
Name: fileName,
Path: fileName,
}
headers := make(map[string]string)
headers["TestHeader"] = "TestValue"
if err := SendMailUsingConfigAdvanced(mimeTo, smtpTo, from, emailSubject, emailBody, attachments, headers, cfg, true); err != nil {
t.Log(err)
t.Fatal("Should connect to the STMP Server")
} else {
//Check if the email was send to the right email address
var resultsMailbox JSONMessageHeaderInbucket
err := RetryInbucket(5, func() error {
var err error
resultsMailbox, err = GetMailBox(smtpTo)
return err
})
if err != nil {
t.Log(err)
t.Fatal("No emails found for address " + smtpTo)
}
if err == nil && len(resultsMailbox) > 0 {
if !strings.ContainsAny(resultsMailbox[0].To[0], smtpTo) {
t.Fatal("Wrong To recipient")
} else {
if resultsEmail, err := GetMessageFromMailbox(smtpTo, resultsMailbox[0].ID); err == nil {
if !strings.Contains(resultsEmail.Body.Text, emailBody) {
t.Log(resultsEmail.Body.Text)
t.Fatal("Received message")
}
// verify that the To header of the email message is set to the MIME recipient, even though we got it out of the SMTP recipient's email inbox
assert.Equal(t, mimeTo, resultsEmail.Header["To"][0])
// verify that the MIME from address is correct - unfortunately, we can't verify the SMTP from address
assert.Equal(t, from.String(), resultsEmail.Header["From"][0])
// check that the custom mime headers came through - header case seems to get mutated
assert.Equal(t, "TestValue", resultsEmail.Header["Testheader"][0])
// ensure that the attachment was successfully sent
assert.Len(t, resultsEmail.Attachments, 1)
assert.Equal(t, fileName, resultsEmail.Attachments[0].Filename)
assert.Equal(t, fileContents, resultsEmail.Attachments[0].Bytes)
}
}
}
}
}

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

@@ -94,7 +94,7 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) {
} }
if api.IsApiCall(r) { if api.IsApiCall(r) {
api.Handle404(c.App, w, r) api.Handle404(w, r)
return return
} }

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

@@ -44,10 +44,7 @@ func Setup() *app.App {
} }
prevListenAddress := *a.Config().ServiceSettings.ListenAddress prevListenAddress := *a.Config().ServiceSettings.ListenAddress
a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
serverErr := a.StartServer() a.StartServer()
if serverErr != nil {
panic(serverErr)
}
a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) a.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
api4.Init(a, a.Srv.Router, false) api4.Init(a, a.Srv.Router, false)
api3 := api.Init(a, a.Srv.Router) api3 := api.Init(a, a.Srv.Router)