model/config: filtering should work with structs too (#29663)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
9e01424b15
Коммит
5e7e441623
@@ -3689,7 +3689,7 @@ func (o *Config) Clone() *Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *Config) ToJSONFiltered(tagType, tagValue string) ([]byte, error) {
|
func (o *Config) ToJSONFiltered(tagType, tagValue string) ([]byte, error) {
|
||||||
filteredConfigMap := structToMapFilteredByTag(*o, tagType, tagValue)
|
filteredConfigMap := configToMapFilteredByTag(*o, tagType, tagValue)
|
||||||
for key, value := range filteredConfigMap {
|
for key, value := range filteredConfigMap {
|
||||||
v, ok := value.(map[string]any)
|
v, ok := value.(map[string]any)
|
||||||
if ok && len(v) == 0 {
|
if ok && len(v) == 0 {
|
||||||
@@ -4614,8 +4614,8 @@ func FilterConfig(cfg *Config, opts ConfigFilterOptions) (map[string]any, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := range opts.TagFilters {
|
for i := range opts.TagFilters {
|
||||||
filteredCfg = structToMapFilteredByTag(filteredCfg, opts.TagFilters[i].TagType, opts.TagFilters[i].TagName)
|
filteredCfg = configToMapFilteredByTag(filteredCfg, opts.TagFilters[i].TagType, opts.TagFilters[i].TagName)
|
||||||
filteredDefaultCfg = structToMapFilteredByTag(defaultCfg, opts.TagFilters[i].TagType, opts.TagFilters[i].TagName)
|
filteredDefaultCfg = configToMapFilteredByTag(filteredDefaultCfg, opts.TagFilters[i].TagType, opts.TagFilters[i].TagName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.RemoveDefaults {
|
if opts.RemoveDefaults {
|
||||||
@@ -4636,8 +4636,26 @@ func FilterConfig(cfg *Config, opts ConfigFilterOptions) (map[string]any, error)
|
|||||||
return filteredCfg, nil
|
return filteredCfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// structToMapFilteredByTag converts a struct into a map removing those fields that has the tag passed
|
// configToMapFilteredByTag converts a struct into a map removing those fields that has the tag passed
|
||||||
// as argument
|
// as argument
|
||||||
|
// t shall be either a Config struct value or a map[string]any
|
||||||
|
func configToMapFilteredByTag(t any, typeOfTag, filterTag string) map[string]any {
|
||||||
|
switch t.(type) {
|
||||||
|
case map[string]any:
|
||||||
|
var tc *Config
|
||||||
|
b, err := json.Marshal(t)
|
||||||
|
if err != nil {
|
||||||
|
// since this is an internal function, we can panic here
|
||||||
|
// because it should never happen
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
json.Unmarshal(b, &tc)
|
||||||
|
t = *tc
|
||||||
|
}
|
||||||
|
|
||||||
|
return structToMapFilteredByTag(t, typeOfTag, filterTag)
|
||||||
|
}
|
||||||
|
|
||||||
func structToMapFilteredByTag(t any, typeOfTag, filterTag string) map[string]any {
|
func structToMapFilteredByTag(t any, typeOfTag, filterTag string) map[string]any {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
@@ -4688,6 +4706,11 @@ func structToMapFilteredByTag(t any, typeOfTag, filterTag string) map[string]any
|
|||||||
// removeEmptyMapsAndSlices removes all the empty maps and slices from a map
|
// removeEmptyMapsAndSlices removes all the empty maps and slices from a map
|
||||||
func removeEmptyMapsAndSlices(m map[string]any) {
|
func removeEmptyMapsAndSlices(m map[string]any) {
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
|
if v == nil {
|
||||||
|
delete(m, k)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
switch vt := v.(type) {
|
switch vt := v.(type) {
|
||||||
case map[string]any:
|
case map[string]any:
|
||||||
removeEmptyMapsAndSlices(vt)
|
removeEmptyMapsAndSlices(vt)
|
||||||
|
|||||||
@@ -1559,7 +1559,7 @@ func TestConfigFilteredByTag(t *testing.T) {
|
|||||||
c := Config{}
|
c := Config{}
|
||||||
c.SetDefaults()
|
c.SetDefaults()
|
||||||
|
|
||||||
cfgMap := structToMapFilteredByTag(c, ConfigAccessTagType, ConfigAccessTagCloudRestrictable)
|
cfgMap := configToMapFilteredByTag(c, ConfigAccessTagType, ConfigAccessTagCloudRestrictable)
|
||||||
|
|
||||||
// Remove entire sections but the map is still there
|
// Remove entire sections but the map is still there
|
||||||
clusterSettings, ok := cfgMap["SqlSettings"].(map[string]any)
|
clusterSettings, ok := cfgMap["SqlSettings"].(map[string]any)
|
||||||
@@ -2088,4 +2088,63 @@ func TestFilterConfig(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1.0, m["PluginSettings"].(map[string]any)["Plugins"].(map[string]any)["com.mattermost.plugin-a"].(map[string]any)["setting"])
|
require.Equal(t, 1.0, m["PluginSettings"].(map[string]any)["Plugins"].(map[string]any)["com.mattermost.plugin-a"].(map[string]any)["setting"])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("should be able to filter specific tag", func(t *testing.T) {
|
||||||
|
cfg := &Config{}
|
||||||
|
cfg.SetDefaults()
|
||||||
|
|
||||||
|
m, err := FilterConfig(cfg, ConfigFilterOptions{
|
||||||
|
GetConfigOptions: GetConfigOptions{},
|
||||||
|
TagFilters: []FilterTag{
|
||||||
|
{
|
||||||
|
TagType: ConfigAccessTagType,
|
||||||
|
TagName: ConfigAccessTagCloudRestrictable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, m)
|
||||||
|
|
||||||
|
fileSettings, ok := m["FileSettings"]
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
enableFileAttachments, ok := fileSettings.(map[string]any)["EnableFileAttachments"]
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, true, enableFileAttachments)
|
||||||
|
|
||||||
|
// All fields of SqlSettings are ConfigAccessTagCloudRestrictable
|
||||||
|
_, ok = m["SqlSettings"]
|
||||||
|
require.False(t, ok)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("should be able to filter multiple tags", func(t *testing.T) {
|
||||||
|
cfg := &Config{}
|
||||||
|
cfg.SetDefaults()
|
||||||
|
|
||||||
|
m, err := FilterConfig(cfg, ConfigFilterOptions{
|
||||||
|
GetConfigOptions: GetConfigOptions{},
|
||||||
|
TagFilters: []FilterTag{
|
||||||
|
{
|
||||||
|
TagType: ConfigAccessTagType,
|
||||||
|
TagName: "site_file_sharing_and_downloads",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TagType: ConfigAccessTagType,
|
||||||
|
TagName: ConfigAccessTagCloudRestrictable,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, m)
|
||||||
|
|
||||||
|
fileSettings, ok := m["FileSettings"]
|
||||||
|
require.True(t, ok)
|
||||||
|
// EnableFileAttachments has "site_file_sharing_and_downloads" tag
|
||||||
|
_, ok = fileSettings.(map[string]any)["EnableFileAttachments"]
|
||||||
|
require.False(t, ok)
|
||||||
|
|
||||||
|
// All fields of SqlSettings are ConfigAccessTagCloudRestrictable
|
||||||
|
_, ok = m["SqlSettings"]
|
||||||
|
require.False(t, ok)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user