Premium SKU (#30396)
* Added premium SKU * removed duplicate enterprise license check functions * Added license check on API layer * lint fix * lint fix * refactured signature: * test: Add comprehensive tests for license tier check functions * fixed test * text update * optimised license checks * fixedf test * Updated license valid function * webapp license checks * handling prekium SKU in webappp: * added plugin api method and general refactoring * Updated tests --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
21ca303b5e
Коммит
a9f09cadc2
@@ -23,8 +23,19 @@ const (
|
||||
LicenseShortSkuE20 = "E20"
|
||||
LicenseShortSkuProfessional = "professional"
|
||||
LicenseShortSkuEnterprise = "enterprise"
|
||||
LicenseShortSkuPremium = "premium"
|
||||
|
||||
ProfessionalTier = 10
|
||||
EnterpriseTier = 20
|
||||
PremiumTier = 30
|
||||
)
|
||||
|
||||
var LicenseToLicenseTier = map[string]int{
|
||||
LicenseShortSkuProfessional: ProfessionalTier,
|
||||
LicenseShortSkuEnterprise: EnterpriseTier,
|
||||
LicenseShortSkuPremium: PremiumTier,
|
||||
}
|
||||
|
||||
const (
|
||||
LicenseUpForRenewalEmailSent = "LicenseUpForRenewalEmailSent"
|
||||
)
|
||||
@@ -356,8 +367,7 @@ func (l *License) IsSanctionedTrial() bool {
|
||||
func (l *License) HasEnterpriseMarketplacePlugins() bool {
|
||||
return *l.Features.EnterprisePlugins ||
|
||||
l.SkuShortName == LicenseShortSkuE20 ||
|
||||
l.SkuShortName == LicenseShortSkuProfessional ||
|
||||
l.SkuShortName == LicenseShortSkuEnterprise
|
||||
MinimumProfessionalLicense(l)
|
||||
}
|
||||
|
||||
func (l *License) HasRemoteClusterService() bool {
|
||||
@@ -371,8 +381,7 @@ func (l *License) HasRemoteClusterService() bool {
|
||||
}
|
||||
|
||||
return (l.Features != nil && l.Features.RemoteClusterService != nil && *l.Features.RemoteClusterService) ||
|
||||
l.SkuShortName == LicenseShortSkuProfessional ||
|
||||
l.SkuShortName == LicenseShortSkuEnterprise
|
||||
MinimumProfessionalLicense(l)
|
||||
}
|
||||
|
||||
func (l *License) HasSharedChannels() bool {
|
||||
@@ -381,13 +390,7 @@ func (l *License) HasSharedChannels() bool {
|
||||
}
|
||||
|
||||
return (l.Features != nil && l.Features.SharedChannels != nil && *l.Features.SharedChannels) ||
|
||||
l.SkuShortName == LicenseShortSkuProfessional ||
|
||||
l.SkuShortName == LicenseShortSkuEnterprise
|
||||
}
|
||||
|
||||
// IsE20OrEnterprise returns true when the license is for E20 or Enterprise.
|
||||
func (l *License) IsE20OrEnterprise() bool {
|
||||
return l.SkuShortName == LicenseShortSkuE20 || l.SkuShortName == LicenseShortSkuEnterprise
|
||||
MinimumProfessionalLicense(l)
|
||||
}
|
||||
|
||||
// NewTestLicense returns a license that expires in the future and has the given features.
|
||||
@@ -459,9 +462,19 @@ func (lr *LicenseRecord) PreSave() {
|
||||
lr.CreateAt = GetMillis()
|
||||
}
|
||||
|
||||
func MinimumProfessionalProvidedLicense(license *License) *AppError {
|
||||
if license == nil || (license.SkuShortName != LicenseShortSkuProfessional && license.SkuShortName != LicenseShortSkuEnterprise) {
|
||||
return NewAppError("", NoTranslation, nil, "license is neither professional nor enterprise", http.StatusNotImplemented)
|
||||
}
|
||||
return nil
|
||||
// MinimumProfessionalLicense returns true if the provided license is at least a professional license.
|
||||
// Higher tier licenses also satisfy the condition.
|
||||
func MinimumProfessionalLicense(license *License) bool {
|
||||
return license != nil && LicenseToLicenseTier[license.SkuShortName] >= ProfessionalTier
|
||||
}
|
||||
|
||||
// MinimumEnterpriseLicense returns true if the provided license is at least a enterprise license.
|
||||
// Higher tier licenses also satisfy the condition.
|
||||
func MinimumEnterpriseLicense(license *License) bool {
|
||||
return license != nil && LicenseToLicenseTier[license.SkuShortName] >= EnterpriseTier
|
||||
}
|
||||
|
||||
// MinimumPremiumLicense returns true if the provided license is at least a premium license.
|
||||
func MinimumPremiumLicense(license *License) bool {
|
||||
return license != nil && LicenseToLicenseTier[license.SkuShortName] >= PremiumTier
|
||||
}
|
||||
|
||||
@@ -485,3 +485,189 @@ func TestLicenseHasSharedChannels(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimumProfessionalLicense(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
license *License
|
||||
expectedValue bool
|
||||
}{
|
||||
{
|
||||
"nil license",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"professional license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuProfessional,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"enterprise license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuEnterprise,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"premium license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuPremium,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"E10 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE10,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"E20 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE20,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unknown license",
|
||||
&License{
|
||||
SkuShortName: "unknown",
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
assert.Equal(t, testCase.expectedValue, MinimumProfessionalLicense(testCase.license))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimumEnterpriseLicense(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
license *License
|
||||
expectedValue bool
|
||||
}{
|
||||
{
|
||||
"nil license",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"professional license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuProfessional,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"enterprise license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuEnterprise,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"premium license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuPremium,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"E10 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE10,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"E20 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE20,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unknown license",
|
||||
&License{
|
||||
SkuShortName: "unknown",
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
assert.Equal(t, testCase.expectedValue, MinimumEnterpriseLicense(testCase.license))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinimumPremiumLicense(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
license *License
|
||||
expectedValue bool
|
||||
}{
|
||||
{
|
||||
"nil license",
|
||||
nil,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"professional license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuProfessional,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"enterprise license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuEnterprise,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"premium license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuPremium,
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"E10 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE10,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"E20 license",
|
||||
&License{
|
||||
SkuShortName: LicenseShortSkuE20,
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"unknown license",
|
||||
&License{
|
||||
SkuShortName: "unknown",
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
assert.Equal(t, testCase.expectedValue, MinimumPremiumLicense(testCase.license))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,6 @@ import (
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
)
|
||||
|
||||
const (
|
||||
e10 = "E10"
|
||||
e20 = "E20"
|
||||
professional = "professional"
|
||||
enterprise = "enterprise"
|
||||
)
|
||||
|
||||
// IsEnterpriseLicensedOrDevelopment returns true when the server is licensed with any Mattermost
|
||||
// Enterprise License, or has `EnableDeveloper` and `EnableTesting` configuration settings
|
||||
// enabled signaling a non-production, developer mode.
|
||||
@@ -30,7 +23,7 @@ func isValidSkuShortName(license *model.License) bool {
|
||||
}
|
||||
|
||||
switch license.SkuShortName {
|
||||
case e10, e20, professional, enterprise:
|
||||
case model.LicenseShortSkuE10, model.LicenseShortSkuE20, model.LicenseShortSkuProfessional, model.LicenseShortSkuEnterprise, model.LicenseShortSkuPremium:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -41,9 +34,7 @@ func isValidSkuShortName(license *model.License) bool {
|
||||
// Enterprise E10 License or a Mattermost Professional License, or has `EnableDeveloper` and
|
||||
// `EnableTesting` configuration settings enabled, signaling a non-production, developer mode.
|
||||
func IsE10LicensedOrDevelopment(config *model.Config, license *model.License) bool {
|
||||
if license != nil &&
|
||||
(license.SkuShortName == e10 || license.SkuShortName == professional ||
|
||||
license.SkuShortName == e20 || license.SkuShortName == enterprise) {
|
||||
if model.MinimumProfessionalLicense(license) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -65,7 +56,7 @@ func IsE10LicensedOrDevelopment(config *model.Config, license *model.License) bo
|
||||
// Enterprise E20 License or a Mattermost Enterprise License, or has `EnableDeveloper` and
|
||||
// `EnableTesting` configuration settings enabled, signaling a non-production, developer mode.
|
||||
func IsE20LicensedOrDevelopment(config *model.Config, license *model.License) bool {
|
||||
if license != nil && (license.SkuShortName == e20 || license.SkuShortName == enterprise) {
|
||||
if model.MinimumEnterpriseLicense(license) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -83,6 +74,16 @@ func IsE20LicensedOrDevelopment(config *model.Config, license *model.License) bo
|
||||
return IsConfiguredForDevelopment(config)
|
||||
}
|
||||
|
||||
// IsPremiumLicensedOrDevelopment returns true when the server is licensed with a Mattermost
|
||||
// Premium License, or has `EnableDeveloper` and `EnableTesting` configuration settings
|
||||
func IsPremiumLicensedOrDevelopment(config *model.Config, license *model.License) bool {
|
||||
if license != nil && license.SkuShortName == model.LicenseShortSkuPremium {
|
||||
return true
|
||||
}
|
||||
|
||||
return IsConfiguredForDevelopment(config)
|
||||
}
|
||||
|
||||
// IsConfiguredForDevelopment returns true when the server has `EnableDeveloper` and `EnableTesting`
|
||||
// configuration settings enabled, signaling a non-production, developer mode.
|
||||
func IsConfiguredForDevelopment(config *model.Config) bool {
|
||||
|
||||
@@ -133,19 +133,6 @@ func TestIsE20LicensedOrDevelopment(t *testing.T) {
|
||||
Features: &model.Features{FutureFeatures: bToP(true)},
|
||||
}))
|
||||
})
|
||||
t.Run("license with E20 SKU name, disabled future features", func(t *testing.T) {
|
||||
assert.True(t, IsE20LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{FutureFeatures: bToP(false)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E20 SKU name, enabled future features", func(t *testing.T) {
|
||||
assert.True(t, IsE20LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{FutureFeatures: bToP(true)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with enterprise SKU name, disabled future features", func(t *testing.T) {
|
||||
assert.True(t, IsE20LicensedOrDevelopment(nil, &model.License{
|
||||
@@ -229,20 +216,6 @@ func TestIsE10LicensedOrDevelopment(t *testing.T) {
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("license with E10 SKU name, disabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E10",
|
||||
Features: &model.Features{LDAP: bToP(false)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E10 SKU name, enabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E10",
|
||||
Features: &model.Features{LDAP: bToP(true)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with professional SKU name, disabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "professional",
|
||||
@@ -256,19 +229,6 @@ func TestIsE10LicensedOrDevelopment(t *testing.T) {
|
||||
Features: &model.Features{LDAP: bToP(true)},
|
||||
}))
|
||||
})
|
||||
t.Run("license with E20 SKU name, disabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{LDAP: bToP(false)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E20 SKU name, enabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{LDAP: bToP(true)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with enterprise SKU name, disabled LDAP", func(t *testing.T) {
|
||||
assert.True(t, IsE10LicensedOrDevelopment(nil, &model.License{
|
||||
@@ -325,6 +285,88 @@ func TestIsValidSKUShortName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsPremiumOrDevelopment(t *testing.T) {
|
||||
t.Run("nil license features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{}))
|
||||
})
|
||||
|
||||
t.Run("nil future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{Features: &model.Features{}}))
|
||||
})
|
||||
|
||||
t.Run("disabled future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{Features: &model.Features{
|
||||
FutureFeatures: bToP(false),
|
||||
}}))
|
||||
})
|
||||
|
||||
t.Run("should have no affect of future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{Features: &model.Features{
|
||||
FutureFeatures: bToP(true),
|
||||
}}))
|
||||
})
|
||||
|
||||
t.Run("no license, no config", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, nil))
|
||||
})
|
||||
|
||||
t.Run("no license, nil config", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(
|
||||
&model.Config{ServiceSettings: model.ServiceSettings{EnableDeveloper: nil, EnableTesting: nil}},
|
||||
nil,
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("no license, only developer mode", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(
|
||||
&model.Config{ServiceSettings: model.ServiceSettings{EnableDeveloper: bToP(true), EnableTesting: bToP(false)}},
|
||||
nil,
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("no license, only testing mode", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(
|
||||
&model.Config{ServiceSettings: model.ServiceSettings{EnableDeveloper: bToP(false), EnableTesting: bToP(true)}},
|
||||
nil,
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("no license, developer and testing mode", func(t *testing.T) {
|
||||
assert.True(t, IsPremiumLicensedOrDevelopment(
|
||||
&model.Config{ServiceSettings: model.ServiceSettings{EnableDeveloper: bToP(true), EnableTesting: bToP(true)}},
|
||||
nil,
|
||||
))
|
||||
})
|
||||
|
||||
t.Run("license with E10 SKU name, disabled future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E10",
|
||||
Features: &model.Features{FutureFeatures: bToP(false)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E10 SKU name, enabled future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E10",
|
||||
Features: &model.Features{FutureFeatures: bToP(true)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E20 SKU name, disabled future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{FutureFeatures: bToP(false)},
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("license with E20 SKU name, enabled future features", func(t *testing.T) {
|
||||
assert.False(t, IsPremiumLicensedOrDevelopment(nil, &model.License{
|
||||
SkuShortName: "E20",
|
||||
Features: &model.Features{FutureFeatures: bToP(true)},
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
func bToP(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user