Welcome to the go-policy-enforcer
library! This document provides a
comprehensive guide to the built-in operators, design principles, and
the steps to extend the library with custom operators. By understanding
and contributing to the operators, you can help improve the policy engine’s
flexibility and applicability.
Before diving into operators, ensure you have the project set up locally:
-
Clone the repository:
git clone https://github.com/kmesiab/go-policy-enforcer.git
-
Install dependencies and build the project:
go mod tidy go build
The go-policy-enforcer
library includes several predefined operators for
evaluating policy rule conditions. Below is a breakdown of each:
Equality Operators:
==
: Checks if two values are equal (reflect.DeepEqual
).!=
: Checks if two values are not equal.
Comparison Operators:
>
: Verifies if the left value is greater than the right.<
: Checks if the left value is less than the right.>=
: Determines if the left value is greater than or equal to the right.<=
: Ensures the left value is less than or equal to the right.
Membership Operators:
in
: Validates if a value is present within a slice.not in
: Confirms a value is absent from a slice.
These operators offer flexibility in policy enforcement, supporting a wide range of comparisons across data types.
The operator framework in go-policy-enforcer
is built around key principles:
- Extensibility: Operators are function-based, allowing easy extension.
- Simplicity: Using function pointers for operator definitions simplifies the extension process.
- Reusability: Operators use Go’s type assertion and reflection, handling various data types and making them versatile.
Here is an overview of the core files associated with operators to guide new contributors:
-operators.go
: Contains predefined operators and their implementations.
-operators_map.go
: Maintains the mapping between operator keys and their
functions. This is where new operators are registered.
-custom_operators/
: Directory for custom operator implementations. Each
operator should be in its own file.
-operators_test.go
: Contains comprehensive test cases for validating
operator behavior and integration.
To extend the operator functionality, follow these steps to create and register a custom operator.
Create a new file in the custom_operators
folder and implement your operator
function to match the PolicyCheckOperator
signature.
package custom_operators
// Example of a custom operator function
var CustomOperator = func(leftVal, rightVal any) bool {
// Your custom logic here
return false // Placeholder logic
}
Add the custom operator to PolicyCheckOperatorMap
in operators_map.go
. This
links the operator’s string representation to its function:
"custom": custom_operators.CustomOperator,
Once registered, you can use the custom operator within policy JSON files with the specified key:
{
"field": "exampleField",
"operator": "custom",
"value": "exampleValue"
}
To maintain quality and consistency in custom operators:
- Follow Established Patterns: Use the structure of existing operators for consistency.
- Thorough Testing: Test custom operators under various scenarios in a
custom test file, including:
- Valid input cases
- Edge cases and boundary conditions
- Type assertion failures
- Nil value handling
- Error Handling: Implement robust error handling:
- Validate input types using type assertions
- Handle nil values appropriately
- Consider returning error values for invalid inputs
- Document Behavior: Include comments detailing:
- Purpose and use cases
- Expected input types and constraints
- Error handling behavior
- Example usage in policies