mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-26 21:27:40 -05:00
[MM-69229] Promote CloudIPFiltering: remove the feature flag (#37150)
The CloudIPFiltering flag (default false, shipped v9.4) gated the
cloud-only IP filtering admin feature. The feature stays cloud-only
independent of the flag:
- Server: ensureIPFilteringInterface still requires license.IsCloud()
and MinimumEnterpriseLicense, so non-cloud servers continue to get
501 Not Implemented. Added not-cloud coverage to applyIPFilters and
getMyIP to match the existing getIPFilters case.
- Webapp: the admin console section now gates on a Cloud license +
Enterprise tier (it.licensedForFeature('Cloud')) instead of the flag,
preserving cloud-only visibility.
Drops the struct field, its SetDefaults entry, the e2e default_config
mirror, the admin_sidebar test fixtures, and the flag-toggling test
cases.
This commit is contained in:
@@ -767,7 +767,6 @@ const defaultServerConfig: AdminConfig = {
|
||||
EnableExportDirectDownload: false,
|
||||
MoveThreadsEnabled: false,
|
||||
StreamlinedMarketplace: true,
|
||||
CloudIPFiltering: false,
|
||||
ConsumePostHook: false,
|
||||
CloudAnnualRenewals: false,
|
||||
CloudDedicatedExportUI: false,
|
||||
|
||||
@@ -21,8 +21,7 @@ func (api *API) InitIPFiltering() {
|
||||
|
||||
func ensureIPFilteringInterface(c *Context, where string) (einterfaces.IPFilteringInterface, bool) {
|
||||
license := c.App.License()
|
||||
ipFilteringFeatureFlag := c.App.Config().FeatureFlags.CloudIPFiltering
|
||||
if c.App.IPFiltering() == nil || !ipFilteringFeatureFlag || license == nil || !license.IsCloud() || !model.MinimumEnterpriseLicense(license) {
|
||||
if c.App.IPFiltering() == nil || license == nil || !license.IsCloud() || !model.MinimumEnterpriseLicense(license) {
|
||||
c.Err = model.NewAppError(where, "api.context.ip_filtering.not_available.app_error", nil, "", http.StatusNotImplemented)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ package api4
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
@@ -30,7 +29,6 @@ func Test_getIPFilters(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("No license returns 501", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -48,27 +46,7 @@ func Test_getIPFilters(t *testing.T) {
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("No feature flag returns 501", func(t *testing.T) {
|
||||
os.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "false")
|
||||
defer os.Unsetenv("MM_FEATUREFLAGS_CLOUDIPFILTERING")
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
th.App.Srv().IPFiltering = ipFiltering
|
||||
|
||||
th.App.Srv().SetLicense(lic)
|
||||
|
||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
ipFilters, r, err := th.Client.GetIPFilters(context.Background())
|
||||
require.Error(t, err)
|
||||
require.Nil(t, ipFilters)
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Feature flag and license but no permission", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
t.Run("License but no permission", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -85,8 +63,7 @@ func Test_getIPFilters(t *testing.T) {
|
||||
require.Equal(t, 403, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Feature flag and license and permission", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
t.Run("License and permission", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -109,8 +86,7 @@ func Test_getIPFilters(t *testing.T) {
|
||||
require.Equal(t, 200, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Feature flag and license and permission but not cloud returns 503", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
t.Run("License and permission but not cloud returns 501", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -149,7 +125,6 @@ func Test_applyIPFilters(t *testing.T) {
|
||||
|
||||
// Initialize the allowedRanges variable
|
||||
t.Run("No license returns 501", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -167,16 +142,14 @@ func Test_applyIPFilters(t *testing.T) {
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("License but no feature flag returns 501", func(t *testing.T) {
|
||||
os.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "false")
|
||||
defer os.Unsetenv("MM_FEATUREFLAGS_CLOUDIPFILTERING")
|
||||
t.Run("License and permission but not cloud returns 501", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
th.App.Srv().IPFiltering = ipFiltering
|
||||
th.App.Srv().SetLicense(lic)
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
||||
|
||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||
_, _, err := th.Client.Login(context.Background(), th.SystemAdminUser.Email, th.SystemAdminUser.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
ipFilters, r, err := th.Client.ApplyIPFilters(context.Background(), allowedRanges)
|
||||
@@ -185,8 +158,7 @@ func Test_applyIPFilters(t *testing.T) {
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("feature flag and license but no permission", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
t.Run("License but no permission", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||
@@ -202,8 +174,7 @@ func Test_applyIPFilters(t *testing.T) {
|
||||
require.Equal(t, 403, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Feature flag and license and permission", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
t.Run("License and permission", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
th.App.Srv().SetLicense(lic)
|
||||
@@ -250,7 +221,6 @@ func Test_getMyIP(t *testing.T) {
|
||||
ExpiresAt: model.GetMillis() + 100000,
|
||||
}
|
||||
t.Run("No license returns 501", func(t *testing.T) {
|
||||
t.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "true")
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
@@ -268,9 +238,23 @@ func Test_getMyIP(t *testing.T) {
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Licensed, but no feature flag returns 501", func(t *testing.T) {
|
||||
os.Setenv("MM_FEATUREFLAGS_CLOUDIPFILTERING", "false")
|
||||
defer os.Unsetenv("MM_FEATUREFLAGS_CLOUDIPFILTERING")
|
||||
t.Run("Licensed but not cloud returns 501", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
ipFiltering := &mocks.IPFilteringInterface{}
|
||||
th.App.Srv().IPFiltering = ipFiltering
|
||||
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuEnterprise))
|
||||
|
||||
myIP, r, err := th.Client.GetMyIP(context.Background())
|
||||
require.Error(t, err)
|
||||
require.Nil(t, myIP)
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Licensed and cloud returns 200", func(t *testing.T) {
|
||||
th := Setup(t).InitBasic(t)
|
||||
|
||||
_, _, err := th.Client.Login(context.Background(), th.BasicUser.Email, th.BasicUser.Password)
|
||||
@@ -281,8 +265,8 @@ func Test_getMyIP(t *testing.T) {
|
||||
th.App.Srv().SetLicense(lic)
|
||||
|
||||
myIP, r, err := th.Client.GetMyIP(context.Background())
|
||||
require.Error(t, err)
|
||||
require.Nil(t, myIP)
|
||||
require.Equal(t, 501, r.StatusCode)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, myIP)
|
||||
require.Equal(t, 200, r.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -47,9 +47,7 @@ type FeatureFlags struct {
|
||||
|
||||
StreamlinedMarketplace bool
|
||||
|
||||
CloudIPFiltering bool
|
||||
ConsumePostHook bool
|
||||
|
||||
ConsumePostHook bool
|
||||
CloudAnnualRenewals bool
|
||||
CloudDedicatedExportUI bool
|
||||
|
||||
@@ -172,7 +170,6 @@ func (f *FeatureFlags) SetDefaults() {
|
||||
f.EnableExportDirectDownload = false
|
||||
f.MoveThreadsEnabled = false
|
||||
f.StreamlinedMarketplace = true
|
||||
f.CloudIPFiltering = false
|
||||
f.ConsumePostHook = false
|
||||
f.CloudAnnualRenewals = false
|
||||
f.CloudDedicatedExportUI = false
|
||||
|
||||
@@ -4294,7 +4294,7 @@ const AdminDefinition: AdminDefinitionType = {
|
||||
ip_filtering: {
|
||||
url: 'site_config/ip_filtering',
|
||||
title: adminDefinitionMessages.ip_filtering_title,
|
||||
isHidden: it.not(it.all(it.configIsTrue('FeatureFlags', 'CloudIPFiltering'), it.minLicenseTier(LicenseSkus.Enterprise))),
|
||||
isHidden: it.not(it.all(it.licensedForFeature('Cloud'), it.minLicenseTier(LicenseSkus.Enterprise))),
|
||||
isDisabled: it.not(it.userHasWritePermissionOnResource(RESOURCE_KEYS.SITE.IP_FILTERING)),
|
||||
searchableStrings: [adminDefinitionMessages.ip_filtering_title],
|
||||
schema: {
|
||||
|
||||
@@ -401,7 +401,6 @@ describe('components/AdminSidebar', () => {
|
||||
AttributeBasedAccessControl: true,
|
||||
CustomProfileAttributes: true,
|
||||
CloudDedicatedExportUI: true,
|
||||
CloudIPFiltering: true,
|
||||
ExperimentalAuditSettingsSystemConsoleUI: true,
|
||||
},
|
||||
},
|
||||
@@ -537,7 +536,6 @@ describe('components/AdminSidebar', () => {
|
||||
AttributeBasedAccessControl: true,
|
||||
CustomProfileAttributes: true,
|
||||
CloudDedicatedExportUI: true,
|
||||
CloudIPFiltering: true,
|
||||
ExperimentalAuditSettingsSystemConsoleUI: true,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user