exercise4 demonstrates how to extend CEL with custom functions. Declare a `contains` member function on map types that returns a boolean indicating whether the map contains the key-value pair.
()
| 154 | // Declare a `contains` member function on map types that returns a boolean |
| 155 | // indicating whether the map contains the key-value pair. |
| 156 | func exercise4() { |
| 157 | fmt.Println("=== Exercise 4: Customization ===\n") |
| 158 | // Determine whether an optional claim is set to the proper value. The custom |
| 159 | // map.contains(key, value) function is used as an alternative to: |
| 160 | // key in map && map[key] == value |
| 161 | |
| 162 | // Useful components of the type-signature for 'contains'. |
| 163 | typeParamA := cel.TypeParamType("A") |
| 164 | typeParamB := cel.TypeParamType("B") |
| 165 | mapAB := cel.MapType(typeParamA, typeParamB) |
| 166 | |
| 167 | // Env declaration. |
| 168 | env, _ := cel.NewEnv( |
| 169 | cel.Types(&rpcpb.AttributeContext_Request{}), |
| 170 | // Declare the request. |
| 171 | cel.Variable("request", |
| 172 | cel.ObjectType("google.rpc.context.AttributeContext.Request"), |
| 173 | ), |
| 174 | // Declare the custom contains function and its implementation. |
| 175 | cel.Function("contains", |
| 176 | cel.MemberOverload("map_contains_key_value", |
| 177 | []*cel.Type{mapAB, typeParamA, typeParamB}, |
| 178 | cel.BoolType, |
| 179 | cel.FunctionBinding(mapContainsKeyValue)), |
| 180 | ), |
| 181 | ) |
| 182 | ast := compile(env, |
| 183 | `request.auth.claims.contains('group', 'admin')`, |
| 184 | cel.BoolType) |
| 185 | |
| 186 | // Construct the program plan. |
| 187 | // Output: false |
| 188 | program, err := env.Program(ast) |
| 189 | if err != nil { |
| 190 | glog.Exit(err) |
| 191 | } |
| 192 | |
| 193 | eval(program, request(auth("user:me@acme.co", emptyClaims), time.Now())) |
| 194 | claims := map[string]string{"group": "admin"} |
| 195 | eval(program, request(auth("user:me@acme.co", claims), time.Now())) |
| 196 | fmt.Println() |
| 197 | } |
| 198 | |
| 199 | // exercise5 covers how to build complex objects as CEL literals. |
| 200 | // |
no test coverage detected