New custom StringPairsEqual condition rejects valid input
ericalandouglas opened this issue · comments
When using the most recent version of ladon (which includes the new StringPairsEqualCondition) in a fork of Hydra, the warden was incorrectly denying requests when given valid contexts.
A sample policy to be tested against:
{
"description": "Allow account admins full access to account resources.",
"subjects": [
"account-admin"
],
"effect": "allow",
"resources": [
"rn:accounts:<[A-z0-9_-]+(:.+)?>"
],
"actions": [
"create", "read", "update", "delete"
],
"conditions": {
"account-ids": {
"type": "StringPairsEqualCondition"
}
}
}
A sample context to test against:
{
"resource": "rn:accounts:1",
"action": "read",
"subject": "<SUBJECT_WITH_ABOVE_POLICY>",
"context": {
"account-ids": [
["1", "1"]
]
}
}
I'm wondering if this can be recreated by others. I believe the following line is failing to coerce properly, https://github.com/ory/ladon/blob/master/condition_string_pairs_equal.go#L11.
I am currently using the following implementation for this condition's Fufills
function:
func (c *StringPairsEqualCondition) Fulfills(value interface{}, _ *Request) bool {
pairs, PairsOk := value.([]interface{})
if PairsOk {
for _, v := range pairs {
pair, PairOk := v.([]interface{})
if !PairOk || (len(pair) != 2) {
return false
}
a, AOk := pair[0].(string)
b, BOk := pair[1].(string)
if !AOk || !BOk || (a != b) {
return false
}
}
return true
}
return false
}
It seems Hydra was able to process the type coercion []interface{}
but not [][]interface{}
. I originally had a similar implementation to the above function's but I had to rework the type coercing to get tests to pass. Now Hydra seems upset :(
Not sure if this is because Hydra is doing something with the input or if it is ladon specific so I created the issue here.
hm that looks weird, does it work with
pairs, PairsOk := value.([][]string)
?
The only thing hydra is doing is decode the JSON data, that should work with nested arrays
I don't believe the coercion value.([][]string)
is working either. That is a little strange since its just JSON decoded.
When using the reflect
package, and the reflect.TypeOf
function on the input value
, the type []interface{}
is returned. Is this just the mechanism of the library doing the JSON decoding?
I'll open a new branch with a coercion in the condition that will work with []interface{}
. I'll update tests to respect the new implementation.
PR #54 addresses this issue and should respect the []interface{}
type.