MM-33905 -always add FeatureFlags to config (#17163)
* always add FeatureFlags to config * update const to TitleCase * gofmt * update method to use 'access:all' * update method to use 'access:all' * fix lint * gofmt * added comments * update name of access tag for any * fix bad save Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
ec5f099313
Коммит
2cb82965b0
@@ -22,8 +22,10 @@ var permissionMap map[string]*model.Permission
|
|||||||
|
|
||||||
type filterType string
|
type filterType string
|
||||||
|
|
||||||
const filterTypeWrite filterType = "write"
|
const (
|
||||||
const filterTypeRead filterType = "read"
|
FilterTypeWrite filterType = "write"
|
||||||
|
FilterTypeRead filterType = "read"
|
||||||
|
)
|
||||||
|
|
||||||
func (api *API) InitConfig() {
|
func (api *API) InitConfig() {
|
||||||
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiSessionRequired(getConfig)).Methods("GET")
|
api.BaseRoutes.ApiRoot.Handle("/config", api.ApiSessionRequired(getConfig)).Methods("GET")
|
||||||
@@ -36,8 +38,8 @@ func (api *API) InitConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
writeFilter = makeFilterConfigByPermission(filterTypeWrite)
|
writeFilter = makeFilterConfigByPermission(FilterTypeWrite)
|
||||||
readFilter = makeFilterConfigByPermission(filterTypeRead)
|
readFilter = makeFilterConfigByPermission(FilterTypeRead)
|
||||||
permissionMap = map[string]*model.Permission{}
|
permissionMap = map[string]*model.Permission{}
|
||||||
for _, p := range model.AllPermissions {
|
for _, p := range model.AllPermissions {
|
||||||
permissionMap[p.Id] = p
|
permissionMap[p.Id] = p
|
||||||
@@ -301,7 +303,7 @@ func makeFilterConfigByPermission(accessType filterType) func(c *Context, struct
|
|||||||
}
|
}
|
||||||
// ConfigAccessTagWriteRestrictable trumps all other permissions
|
// ConfigAccessTagWriteRestrictable trumps all other permissions
|
||||||
if tagValue == model.ConfigAccessTagWriteRestrictable || tagValue == model.ConfigAccessTagCloudRestrictable {
|
if tagValue == model.ConfigAccessTagWriteRestrictable || tagValue == model.ConfigAccessTagCloudRestrictable {
|
||||||
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin && accessType == filterTypeWrite {
|
if *c.App.Config().ExperimentalSettings.RestrictSystemAdmin && accessType == FilterTypeWrite {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@@ -320,6 +322,11 @@ func makeFilterConfigByPermission(accessType filterType) func(c *Context, struct
|
|||||||
if tagValue == model.ConfigAccessTagCloudRestrictable {
|
if tagValue == model.ConfigAccessTagCloudRestrictable {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if tagValue == model.ConfigAccessTagAnySysConsoleRead && accessType == FilterTypeRead &&
|
||||||
|
c.App.SessionHasPermissionToAny(*c.App.Session(), model.SysconsoleReadPermissions) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
permissionID := fmt.Sprintf("sysconsole_%s_%s", accessType, tagValue)
|
permissionID := fmt.Sprintf("sysconsole_%s_%s", accessType, tagValue)
|
||||||
if permission, ok := permissionMap[permissionID]; ok {
|
if permission, ok := permissionMap[permissionID]; ok {
|
||||||
if c.App.SessionHasPermissionTo(*c.App.Session(), permission) {
|
if c.App.SessionHasPermissionTo(*c.App.Session(), permission) {
|
||||||
|
|||||||
@@ -90,6 +90,32 @@ func TestGetConfigWithAccessTag(t *testing.T) {
|
|||||||
t.Run("Can read value with permission", func(t *testing.T) {
|
t.Run("Can read value with permission", func(t *testing.T) {
|
||||||
assert.Equal(t, mockVaryByHeader, cfg.RateLimitSettings.VaryByHeader)
|
assert.Equal(t, mockVaryByHeader, cfg.RateLimitSettings.VaryByHeader)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("Contains Feature Flags", func(t *testing.T) {
|
||||||
|
assert.NotNil(t, cfg.FeatureFlags)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetConfigAnyFlagsAccess(t *testing.T) {
|
||||||
|
th := Setup(t)
|
||||||
|
defer th.TearDown()
|
||||||
|
|
||||||
|
th.Client.Login(th.BasicUser.Username, th.BasicUser.Password)
|
||||||
|
cfg, resp := th.Client.GetConfig()
|
||||||
|
|
||||||
|
t.Run("Check permissions error with no sysconsole read permission", func(t *testing.T) {
|
||||||
|
CheckForbiddenStatus(t, resp)
|
||||||
|
})
|
||||||
|
|
||||||
|
// add read sysconsole environment config
|
||||||
|
th.AddPermissionToRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, model.SYSTEM_USER_ROLE_ID)
|
||||||
|
defer th.RemovePermissionFromRole(model.PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id, model.SYSTEM_USER_ROLE_ID)
|
||||||
|
|
||||||
|
cfg, resp = th.Client.GetConfig()
|
||||||
|
CheckNoError(t, resp)
|
||||||
|
t.Run("Can read value with permission", func(t *testing.T) {
|
||||||
|
assert.NotNil(t, cfg.FeatureFlags)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReloadConfig(t *testing.T) {
|
func TestReloadConfig(t *testing.T) {
|
||||||
|
|||||||
@@ -3050,6 +3050,9 @@ const ConfigAccessTagType = "access"
|
|||||||
const ConfigAccessTagWriteRestrictable = "write_restrictable"
|
const ConfigAccessTagWriteRestrictable = "write_restrictable"
|
||||||
const ConfigAccessTagCloudRestrictable = "cloud_restrictable"
|
const ConfigAccessTagCloudRestrictable = "cloud_restrictable"
|
||||||
|
|
||||||
|
// Allows read access if any PERMISSION_SYSCONSOLE_READ_* is allowed
|
||||||
|
const ConfigAccessTagAnySysConsoleRead = "*_read"
|
||||||
|
|
||||||
// Config fields support the 'access' tag with the following values corresponding to the suffix of the associated
|
// Config fields support the 'access' tag with the following values corresponding to the suffix of the associated
|
||||||
// PERMISSION_SYSCONSOLE_*_* permission Id: 'about', 'reporting', 'user_management_users',
|
// PERMISSION_SYSCONSOLE_*_* permission Id: 'about', 'reporting', 'user_management_users',
|
||||||
// 'user_management_groups', 'user_management_teams', 'user_management_channels',
|
// 'user_management_groups', 'user_management_teams', 'user_management_channels',
|
||||||
@@ -3057,6 +3060,8 @@ const ConfigAccessTagCloudRestrictable = "cloud_restrictable"
|
|||||||
// 'integrations', 'compliance', 'plugins', and 'experimental'. They grant read and/or write access to the config field
|
// 'integrations', 'compliance', 'plugins', and 'experimental'. They grant read and/or write access to the config field
|
||||||
// to roles without PERMISSION_MANAGE_SYSTEM.
|
// to roles without PERMISSION_MANAGE_SYSTEM.
|
||||||
//
|
//
|
||||||
|
// The 'access' tag '*_read' checks for any SYSCONSOLE read permission and grants access if any read permission is allowed.
|
||||||
|
//
|
||||||
// By default config values can be written with PERMISSION_MANAGE_SYSTEM, but if ExperimentalSettings.RestrictSystemAdmin is true
|
// By default config values can be written with PERMISSION_MANAGE_SYSTEM, but if ExperimentalSettings.RestrictSystemAdmin is true
|
||||||
// and the access tag contains the value 'write_restrictable', then even PERMISSION_MANAGE_SYSTEM does not grant write access.
|
// and the access tag contains the value 'write_restrictable', then even PERMISSION_MANAGE_SYSTEM does not grant write access.
|
||||||
//
|
//
|
||||||
@@ -3119,7 +3124,7 @@ type Config struct {
|
|||||||
GuestAccountsSettings GuestAccountsSettings
|
GuestAccountsSettings GuestAccountsSettings
|
||||||
ImageProxySettings ImageProxySettings
|
ImageProxySettings ImageProxySettings
|
||||||
CloudSettings CloudSettings // telemetry: none
|
CloudSettings CloudSettings // telemetry: none
|
||||||
FeatureFlags *FeatureFlags `json:",omitempty"` // telemetry: none
|
FeatureFlags *FeatureFlags `access:"*_read" json:",omitempty"` // telemetry: none
|
||||||
ImportSettings ImportSettings // telemetry: none
|
ImportSettings ImportSettings // telemetry: none
|
||||||
ExportSettings ExportSettings
|
ExportSettings ExportSettings
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user