Merge branch 'release-4.7' into rm-willnorris-proxy-support
Этот коммит содержится в:
4
Makefile
4
Makefile
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
54
app/app.go
54
app/app.go
@@ -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) {
|
||||||
|
|||||||
107
app/license.go
107
app/license.go
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
54
app/post.go
54
app/post.go
@@ -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)
|
||||||
|
|||||||
36
i18n/en.json
36
i18n/en.json
@@ -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
Обычный файл
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(©)
|
b, err := json.Marshal(©)
|
||||||
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: </span>{{.Props.ChannelName}}</li>
|
|
||||||
<li><span class="bold">Started: </span>{{.Props.Started}}</li>
|
|
||||||
<li><span class="bold">Ended: </span>{{.Props.Ended}}</li>
|
|
||||||
<li><span class="bold">Duration: </span>{{.Props.Duration}} 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}}
|
|
||||||
25
utils/api.go
25
utils/api.go
@@ -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) {
|
||||||
|
|||||||
135
utils/license.go
135
utils/license.go
@@ -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)
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user