Remove license globals entirely (#8229)
* remove license globals entirely * fix infinite recursion * test fix
Этот коммит содержится в:
@@ -118,9 +118,10 @@ 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 {
|
||||||
utils.License().Features.SetDefaults()
|
th.App.SetLicense(model.NewTestLicense())
|
||||||
|
} else {
|
||||||
|
th.App.SetLicense(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return th
|
return th
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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() {
|
||||||
@@ -83,7 +82,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 := utils.GetClientLicenseEtag(useSanitizedLicense)
|
etag := c.App.GetClientLicenseEtag(useSanitizedLicense)
|
||||||
if c.HandleEtag(etag, "Get Client License Config", w, r) {
|
if c.HandleEtag(etag, "Get Client License Config", w, r) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -91,9 +90,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 = utils.ClientLicense()
|
clientLicense = c.App.ClientLicense()
|
||||||
} else {
|
} else {
|
||||||
clientLicense = utils.GetSanitizedClientLicense()
|
clientLicense = c.App.GetSanitizedClientLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
|
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mattermost/mattermost-server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetLicenceConfig(t *testing.T) {
|
func TestGetLicenceConfig(t *testing.T) {
|
||||||
@@ -32,7 +30,7 @@ func TestGetLicenceConfig(t *testing.T) {
|
|||||||
t.Fatal("cache should be empty")
|
t.Fatal("cache should be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SetClientLicense(map[string]string{"IsLicensed": "true"})
|
th.App.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)
|
||||||
@@ -40,7 +38,7 @@ func TestGetLicenceConfig(t *testing.T) {
|
|||||||
t.Fatal("result should not be empty")
|
t.Fatal("result should not be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SetClientLicense(map[string]string{"SomeFeature": "true", "IsLicensed": "true"})
|
th.App.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)
|
||||||
@@ -48,6 +46,6 @@ func TestGetLicenceConfig(t *testing.T) {
|
|||||||
t.Fatal("result should not be empty")
|
t.Fatal("result should not be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SetClientLicense(map[string]string{"IsLicensed": "false"})
|
th.App.SetClientLicense(map[string]string{"IsLicensed": "false"})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = utils.ClientLicense()
|
il.LicenseCfg = c.App.ClientLicense()
|
||||||
} else {
|
} else {
|
||||||
il.LicenseCfg = utils.GetSanitizedClientLicense()
|
il.LicenseCfg = c.App.GetSanitizedClientLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write([]byte(il.ToJson()))
|
w.Write([]byte(il.ToJson()))
|
||||||
|
|||||||
@@ -125,9 +125,10 @@ 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 {
|
||||||
utils.License().Features.SetDefaults()
|
th.App.SetLicense(model.NewTestLicense())
|
||||||
|
} else {
|
||||||
|
th.App.SetLicense(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
th.Client = th.CreateClient()
|
th.Client = th.CreateClient()
|
||||||
|
|||||||
@@ -18,14 +18,7 @@ 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}
|
||||||
|
|
||||||
@@ -42,12 +35,10 @@ 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)
|
||||||
@@ -86,14 +77,7 @@ 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",
|
||||||
@@ -172,7 +156,6 @@ 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)
|
||||||
|
|
||||||
@@ -199,15 +182,8 @@ 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"}}
|
||||||
|
|
||||||
@@ -251,7 +227,6 @@ 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)
|
||||||
@@ -272,15 +247,8 @@ 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"}}
|
||||||
|
|
||||||
@@ -320,7 +288,6 @@ 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)
|
||||||
@@ -347,15 +314,8 @@ 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"}}
|
||||||
|
|
||||||
@@ -395,7 +355,6 @@ 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)
|
||||||
@@ -422,15 +381,8 @@ 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"}}
|
||||||
|
|
||||||
@@ -465,7 +417,6 @@ 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)
|
||||||
|
|
||||||
@@ -490,15 +441,8 @@ 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"}}
|
||||||
|
|
||||||
@@ -537,7 +481,6 @@ 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)
|
||||||
|
|
||||||
@@ -622,12 +565,7 @@ 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"}}
|
||||||
|
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ func getClientLicense(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
etag := utils.GetClientLicenseEtag(true)
|
etag := c.App.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 = utils.ClientLicense()
|
clientLicense = c.App.ClientLicense()
|
||||||
} else {
|
} else {
|
||||||
clientLicense = utils.GetSanitizedClientLicense()
|
clientLicense = c.App.GetSanitizedClientLicense()
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
|
w.Header().Set(model.HEADER_ETAG_SERVER, etag)
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ 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)
|
||||||
if err := utils.SendMailUsingConfig(user.Email, T("api.admin.test_email.subject"), T("api.admin.test_email.body"), cfg); err != nil {
|
license := a.License()
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
app/app.go
24
app/app.go
@@ -59,6 +59,10 @@ 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
|
||||||
@@ -88,18 +92,16 @@ func New(options ...Option) (*App, error) {
|
|||||||
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()?")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this once utils global license state is eliminated
|
|
||||||
utils.SetLicense(nil)
|
|
||||||
|
|
||||||
app := &App{
|
app := &App{
|
||||||
goroutineExitSignal: make(chan struct{}, 1),
|
goroutineExitSignal: make(chan struct{}, 1),
|
||||||
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(){},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
@@ -123,9 +125,9 @@ func New(options ...Option) (*App, error) {
|
|||||||
app.configListenerId = app.AddConfigListener(func(_, _ *model.Config) {
|
app.configListenerId = app.AddConfigListener(func(_, _ *model.Config) {
|
||||||
app.configOrLicenseListener()
|
app.configOrLicenseListener()
|
||||||
})
|
})
|
||||||
app.licenseListenerId = utils.AddLicenseListener(app.configOrLicenseListener)
|
app.licenseListenerId = app.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"))
|
||||||
|
|
||||||
@@ -166,7 +168,7 @@ func New(options ...Option) (*App, 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() {
|
||||||
@@ -188,7 +190,7 @@ func (a *App) Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a.RemoveConfigListener(a.configListenerId)
|
a.RemoveConfigListener(a.configListenerId)
|
||||||
utils.RemoveLicenseListener(a.licenseListenerId)
|
a.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()
|
||||||
|
|||||||
@@ -106,9 +106,10 @@ 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 {
|
||||||
utils.License().Features.SetDefaults()
|
th.App.SetLicense(model.NewTestLicense())
|
||||||
|
} else {
|
||||||
|
th.App.SetLicense(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return th
|
return th
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ func (a *App) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) regenerateClientConfig() {
|
func (a *App) regenerateClientConfig() {
|
||||||
a.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId())
|
a.clientConfig = utils.GenerateClientConfig(a.Config(), a.DiagnosticId(), a.License())
|
||||||
if key := a.AsymmetricSigningKey(); key != nil {
|
if key := a.AsymmetricSigningKey(); key != nil {
|
||||||
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
der, _ := x509.MarshalPKIXPublicKey(&key.PublicKey)
|
||||||
a.clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
a.clientConfig["AsymmetricSigningPublicKey"] = base64.StdEncoding.EncodeToString(der)
|
||||||
|
|||||||
@@ -316,5 +316,6 @@ 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 {
|
||||||
return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config())
|
license := a.License()
|
||||||
|
return utils.SendMailUsingConfig(to, subject, htmlBody, a.Config(), license != nil && *license.Features.Compliance)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
|
func (a *App) FileBackend() (utils.FileBackend, *model.AppError) {
|
||||||
return utils.NewFileBackend(&a.Config().FileSettings)
|
license := a.License()
|
||||||
|
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) {
|
||||||
|
|||||||
105
app/license.go
105
app/license.go
@@ -4,16 +4,19 @@
|
|||||||
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() {
|
||||||
utils.RemoveLicense()
|
a.SetLicense(nil)
|
||||||
|
|
||||||
licenseId := ""
|
licenseId := ""
|
||||||
if result := <-a.Srv.Store.System().Get(); result.Err == nil {
|
if result := <-a.Srv.Store.System().Get(); result.Err == nil {
|
||||||
@@ -36,7 +39,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)
|
||||||
utils.LoadLicense([]byte(record.Bytes))
|
a.ValidateAndSetLicenseBytes([]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"))
|
||||||
@@ -104,33 +107,113 @@ func (a *App) SaveLicense(licenseBytes []byte) (*model.License, *model.AppError)
|
|||||||
|
|
||||||
// License returns the currently active license or nil if the application is unlicensed.
|
// License returns the currently active license or nil if the application is unlicensed.
|
||||||
func (a *App) License() *model.License {
|
func (a *App) License() *model.License {
|
||||||
if utils.IsLicensed() {
|
license, _ := a.licenseValue.Load().(*model.License)
|
||||||
return utils.License()
|
return license
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) SetLicense(license *model.License) bool {
|
func (a *App) SetLicense(license *model.License) bool {
|
||||||
ok := utils.SetLicense(license)
|
defer func() {
|
||||||
a.SetDefaultRolesBasedOnConfig()
|
a.setDefaultRolesBasedOnConfig()
|
||||||
return ok
|
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 {
|
||||||
utils.RemoveLicense()
|
if license, _ := a.licenseValue.Load().(*model.License); license == nil {
|
||||||
|
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,8 +4,9 @@
|
|||||||
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) {
|
||||||
@@ -37,3 +38,75 @@ 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ func (a *App) Role(id string) *model.Role {
|
|||||||
return a.roles[id]
|
return a.roles[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the roles based on the app config and the global license check. You may need to invoke
|
func (a *App) setDefaultRolesBasedOnConfig() {
|
||||||
// this when license changes are made.
|
a.roles = utils.DefaultRolesBasedOnConfig(a.Config(), a.License() != nil)
|
||||||
func (a *App) SetDefaultRolesBasedOnConfig() {
|
|
||||||
a.roles = utils.DefaultRolesBasedOnConfig(a.Config())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ 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) {
|
||||||
@@ -111,7 +110,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
|
||||||
*utils.License().Features.Compliance = false
|
th.App.SetLicense(nil)
|
||||||
|
|
||||||
session = &model.Session{
|
session = &model.Session{
|
||||||
UserId: model.NewId(),
|
UserId: model.NewId(),
|
||||||
@@ -125,7 +124,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)
|
||||||
|
|
||||||
*utils.License().Features.Compliance = true
|
th.App.SetLicense(model.NewTestLicense("compliance"))
|
||||||
|
|
||||||
// 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 })
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func jobserverCmdF(cmd *cobra.Command, args []string) {
|
|||||||
defer l4g.Close()
|
defer l4g.Close()
|
||||||
defer a.Shutdown()
|
defer a.Shutdown()
|
||||||
|
|
||||||
a.Jobs.LoadLicense()
|
a.LoadLicense()
|
||||||
|
|
||||||
// Run jobs
|
// Run jobs
|
||||||
l4g.Info("Starting Mattermost job server")
|
l4g.Info("Starting Mattermost job server")
|
||||||
|
|||||||
@@ -4,12 +4,9 @@
|
|||||||
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 {
|
||||||
@@ -50,36 +47,6 @@ 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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
// 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()
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/mattermost/mattermost-server/model"
|
"github.com/mattermost/mattermost-server/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DefaultRolesBasedOnConfig(cfg *model.Config) map[string]*model.Role {
|
func DefaultRolesBasedOnConfig(cfg *model.Config, isLicensed bool) 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) map[string]*model.Role {
|
|||||||
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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]*model.Role {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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) map[string]*model.Role {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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) map[string]*model.Role {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
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) map[string]string {
|
func GenerateClientConfig(c *model.Config, diagnosticId string, license *model.License) map[string]string {
|
||||||
props := make(map[string]string)
|
props := make(map[string]string)
|
||||||
|
|
||||||
props["Version"] = model.CurrentVersion
|
props["Version"] = model.CurrentVersion
|
||||||
@@ -456,18 +456,17 @@ func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]strin
|
|||||||
|
|
||||||
props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable)
|
props["PluginsEnabled"] = strconv.FormatBool(*c.PluginSettings.Enable)
|
||||||
|
|
||||||
if IsLicensed() {
|
if license != nil {
|
||||||
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 != "")
|
||||||
@@ -478,16 +477,16 @@ func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]strin
|
|||||||
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 != "")
|
||||||
@@ -498,23 +497,23 @@ func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]strin
|
|||||||
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)
|
||||||
@@ -522,7 +521,7 @@ func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]strin
|
|||||||
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
|
||||||
@@ -530,14 +529,14 @@ func GenerateClientConfig(c *model.Config, diagnosticId string) map[string]strin
|
|||||||
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, "")
|
configMap := GenerateClientConfig(cfg, "", nil)
|
||||||
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) (FileBackend, *model.AppError) {
|
func NewFileBackend(settings *model.FileSettings, enableComplianceFeatures bool) (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) (FileBackend, *model.AppError)
|
|||||||
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 && IsLicensed() && *License().Features.Compliance,
|
encrypt: settings.AmazonS3SSE != nil && *settings.AmazonS3SSE && enableComplianceFeatures,
|
||||||
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)
|
backend, err := NewFileBackend(&s.settings, true)
|
||||||
require.Nil(s.T(), err)
|
require.Nil(s.T(), err)
|
||||||
s.backend = backend
|
s.backend = backend
|
||||||
}
|
}
|
||||||
|
|||||||
135
utils/license.go
135
utils/license.go
@@ -5,28 +5,21 @@ 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
|
||||||
@@ -37,92 +30,6 @@ 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)))
|
||||||
|
|
||||||
@@ -213,12 +120,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(IsLicensed())
|
props["IsLicensed"] = strconv.FormatBool(l != nil)
|
||||||
|
|
||||||
if IsLicensed() {
|
if l != nil {
|
||||||
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)
|
||||||
@@ -248,39 +155,3 @@ 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,87 +5,20 @@ 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 {
|
||||||
|
|||||||
@@ -105,17 +105,17 @@ func TestConnection(config *model.Config) {
|
|||||||
defer c.Close()
|
defer c.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendMailUsingConfig(to, subject, htmlBody string, config *model.Config) *model.AppError {
|
func SendMailUsingConfig(to, subject, htmlBody string, config *model.Config, enableComplianceFeatures bool) *model.AppError {
|
||||||
fromMail := mail.Address{Name: config.EmailSettings.FeedbackName, Address: config.EmailSettings.FeedbackEmail}
|
fromMail := mail.Address{Name: config.EmailSettings.FeedbackName, Address: config.EmailSettings.FeedbackEmail}
|
||||||
return sendMail(to, to, fromMail, subject, htmlBody, nil, nil, config)
|
return sendMail(to, to, fromMail, subject, htmlBody, nil, nil, config, enableComplianceFeatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
// allows for sending an email with attachments and differing MIME/SMTP recipients
|
// 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) *model.AppError {
|
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)
|
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) *model.AppError {
|
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
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ func sendMail(mimeTo, smtpTo string, from mail.Address, subject, htmlBody string
|
|||||||
m.AddAlternative("text/html", htmlMessage)
|
m.AddAlternative("text/html", htmlMessage)
|
||||||
|
|
||||||
if attachments != nil {
|
if attachments != nil {
|
||||||
fileBackend, err := NewFileBackend(&config.FileSettings)
|
fileBackend, err := NewFileBackend(&config.FileSettings, enableComplianceFeatures)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ func TestSendMailUsingConfig(t *testing.T) {
|
|||||||
//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); err != nil {
|
if err := SendMailUsingConfig(emailTo, emailSubject, emailBody, cfg, true); 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 {
|
||||||
@@ -95,7 +95,7 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) {
|
|||||||
DeleteMailBox(smtpTo)
|
DeleteMailBox(smtpTo)
|
||||||
|
|
||||||
// create a file that will be attached to the email
|
// create a file that will be attached to the email
|
||||||
fileBackend, err := NewFileBackend(&cfg.FileSettings)
|
fileBackend, err := NewFileBackend(&cfg.FileSettings, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
fileContents := []byte("hello world")
|
fileContents := []byte("hello world")
|
||||||
fileName := "file.txt"
|
fileName := "file.txt"
|
||||||
@@ -111,7 +111,7 @@ func TestSendMailUsingConfigAdvanced(t *testing.T) {
|
|||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
headers["TestHeader"] = "TestValue"
|
headers["TestHeader"] = "TestValue"
|
||||||
|
|
||||||
if err := SendMailUsingConfigAdvanced(mimeTo, smtpTo, from, emailSubject, emailBody, attachments, headers, cfg); err != nil {
|
if err := SendMailUsingConfigAdvanced(mimeTo, smtpTo, from, emailSubject, emailBody, attachments, headers, cfg, true); 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 {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user