diff --git a/cmd/enforce.go b/cmd/enforce.go index 5ae8d0c..059bb94 100644 --- a/cmd/enforce.go +++ b/cmd/enforce.go @@ -48,6 +48,21 @@ func handleEnforceResult(cmd *cobra.Command, res bool, explain []string, err err encoder.Encode(response) } +// createStructWithValue creates a struct with a single field and value. +func createStructWithValue(fieldName string, value interface{}) interface{} { + caser := cases.Title(language.English) + structType := reflect.StructOf([]reflect.StructField{ + { + Name: caser.String(fieldName), + Type: reflect.TypeOf(value), + }, + }) + + structValue := reflect.New(structType).Elem() + structValue.Field(0).Set(reflect.ValueOf(value)) + return structValue.Interface() +} + // Function to parse parameters and execute policy check. func executeEnforce(cmd *cobra.Command, args []string, isEnforceEx bool) { modelPath, _ := cmd.Flags().GetString("model") @@ -58,8 +73,8 @@ func executeEnforce(cmd *cobra.Command, args []string, isEnforceEx bool) { panic(err) } - // Define regex pattern to match format like {field: value}. - paramRegex := regexp.MustCompile(`{\s*"?(\w+)"?\s*:\s*(\d+)\s*}`) + // Define regex pattern to match format like {field: value} or {field: "value"}. + paramRegex := regexp.MustCompile(`{\s*"?(\w+)"?\s*:\s*(?:"?([^"{}]+)"?)\s*}`) params := make([]interface{}, len(args)) for i, v := range args { @@ -68,24 +83,13 @@ func executeEnforce(cmd *cobra.Command, args []string, isEnforceEx bool) { fieldName := matches[1] valueStr := matches[2] - // Convert value to integer. + // Try to convert value to integer first. if val, err := strconv.Atoi(valueStr); err == nil { - // Dynamically create struct type. - caser := cases.Title(language.English) - structType := reflect.StructOf([]reflect.StructField{ - { - Name: caser.String(fieldName), - Type: reflect.TypeOf(0), - }, - }) - - // Create struct instance and set value. - structValue := reflect.New(structType).Elem() - structValue.Field(0).SetInt(int64(val)) - - params[i] = structValue.Interface() - continue + params[i] = createStructWithValue(fieldName, val) + } else { + params[i] = createStructWithValue(fieldName, valueStr) } + continue } params[i] = v } diff --git a/cmd/enforce_test.go b/cmd/enforce_test.go index 3be9f76..8bdf4d2 100644 --- a/cmd/enforce_test.go +++ b/cmd/enforce_test.go @@ -47,4 +47,8 @@ func Test_enforceExCmd(t *testing.T) { abacArgs := []string{"enforceEx", "-m", "../test/abac_rule_model.conf", "-p", "../test/abac_rule_policy.csv"} assertExecuteCommand(t, rootCmd, "{\"allow\":true,\"explain\":[\"r.sub.Age > 18\",\"/data1\",\"read\"]}\n", append(abacArgs, "{\"Age\":30}", "/data1", "read")...) assertExecuteCommand(t, rootCmd, "{\"allow\":false,\"explain\":[]}\n", append(abacArgs, "{\"Age\":15}", "/data1", "read")...) + + abacArgs = []string{"enforceEx", "-m", "../test/abac_model.conf", "-p", "../test/abac_policy.csv"} + assertExecuteCommand(t, rootCmd, "{\"allow\":true,\"explain\":[]}\n", append(abacArgs, "alice", "{\"Owner\":\"alice\"}")...) + assertExecuteCommand(t, rootCmd, "{\"allow\":false,\"explain\":[]}\n", append(abacArgs, "alice", "{\"Owner\":\"bob\"}")...) } diff --git a/test/abac_model.conf b/test/abac_model.conf new file mode 100644 index 0000000..4198fd7 --- /dev/null +++ b/test/abac_model.conf @@ -0,0 +1,11 @@ +[request_definition] +r = sub, obj + +[policy_definition] +p = sub, obj + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = r.sub == r.obj.Owner \ No newline at end of file diff --git a/test/abac_policy.csv b/test/abac_policy.csv new file mode 100644 index 0000000..e69de29