diff --git a/base/rbac/rbac.go b/base/rbac/rbac.go index 86ccea1a8..bd9d56a74 100644 --- a/base/rbac/rbac.go +++ b/base/rbac/rbac.go @@ -1,5 +1,9 @@ package rbac +import ( + "encoding/json" +) + type AccessPagination struct { Data []Access `json:"data"` } @@ -13,9 +17,11 @@ type ResourceDefinition struct { AttributeFilter AttributeFilter `json:"attributeFilter,omitempty"` } +type AttributeFilterValue []*string + type AttributeFilter struct { - Key string `json:"key"` - Value []*string `json:"value"` + Key string `json:"key"` + Value AttributeFilterValue `json:"value"` } type inventoryGroup struct { @@ -24,3 +30,33 @@ type inventoryGroup struct { } type InventoryGroup []inventoryGroup + +func (a *AttributeFilterValue) UnmarshalJSON(data []byte) error { + var ( + array []*string + value *string + err error + ) + + if err = json.Unmarshal(data, &array); err != nil { + // parsing of AttributeFilter Value into []*string failed + // try to parse it as *string + if err = json.Unmarshal(data, &value); err != nil { + // fail, the value is neither []*string nor *string + return err + } + if value != nil { + // according to RBAC team, value is a single string value + // not comma delimited strings, multiple values are always in array + array = append(array, value) + } + } + if array == nil && value == nil { + // in this case we got `"value": null` + // we should apply the permission to systems with no inventory groups + array = append(array, value) + } + + *a = array + return nil +} diff --git a/base/rbac/rbac_test.go b/base/rbac/rbac_test.go new file mode 100644 index 000000000..44fdd3967 --- /dev/null +++ b/base/rbac/rbac_test.go @@ -0,0 +1,64 @@ +package rbac + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParsing(t *testing.T) { + data := []byte(` + { + "resourceDefinitions": [ + {"attributeFilter": { + "key": "single_string", + "value": "string" + }}, + {"attributeFilter": { + "key": "comma_separated", + "value": "comma,separated" + }}, + {"attributeFilter": { + "key": "null", + "value": null + }}, + {"attributeFilter": { + "key": "string_array", + "value": ["string", "array"] + }}, + {"attributeFilter": { + "key": "string_array_with_null", + "value": ["string", "array", null] + }}, + {"attributeFilter": { + "key": "null_array", + "value": [null] + }}, + {"attributeFilter": { + "key": "empty_array", + "value": [] + }} + ] + } + `) + stringS := "string" + commaS := "comma,separated" + arrayS := "array" + + expected := []ResourceDefinition{ + {AttributeFilter: AttributeFilter{Key: "single_string", Value: []*string{&stringS}}}, + {AttributeFilter: AttributeFilter{Key: "comma_separated", Value: []*string{&commaS}}}, + {AttributeFilter: AttributeFilter{Key: "null", Value: []*string{nil}}}, + {AttributeFilter: AttributeFilter{Key: "string_array", Value: []*string{&stringS, &arrayS}}}, + {AttributeFilter: AttributeFilter{Key: "string_array_with_null", Value: []*string{&stringS, &arrayS, nil}}}, + {AttributeFilter: AttributeFilter{Key: "null_array", Value: []*string{nil}}}, + {AttributeFilter: AttributeFilter{Key: "empty_array", Value: []*string{}}}, + } + + var v Access + err := json.Unmarshal(data, &v) + if assert.NoError(t, err) { + assert.Equal(t, expected, v.ResourceDefinitions) + } +}