From 14db8602a582d6ca57006fa9114fe799151bc801 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 19 Nov 2021 16:57:49 -0500 Subject: [PATCH] Convert boolean and numeric values to strings for value comparison. --- aws_policy_equivalence.go | 24 ++++-- aws_policy_equivalence_test.go | 148 ++++++++++++++++++++++++++++++++- 2 files changed, 165 insertions(+), 7 deletions(-) diff --git a/aws_policy_equivalence.go b/aws_policy_equivalence.go index 73e3856..a80aba8 100644 --- a/aws_policy_equivalence.go +++ b/aws_policy_equivalence.go @@ -12,6 +12,7 @@ import ( "fmt" "reflect" "regexp" + "strconv" "strings" "github.com/mitchellh/mapstructure" @@ -377,17 +378,30 @@ func newAWSStringSet(members interface{}) awsStringSet { return awsStringSet{single} } + if single, ok := members.(bool); ok { + return awsStringSet{strconv.FormatBool(single)} + } + + if single, ok := members.(float64); ok { + return awsStringSet{strconv.FormatFloat(single, 'f', -1, 64)} + } + if multiple, ok := members.([]interface{}); ok { if len(multiple) == 0 { return awsStringSet{} } - actions := make([]string, len(multiple)) - for i, action := range multiple { - if _, ok := action.(string); !ok { + var actions []string + for _, action := range multiple { + switch action := action.(type) { + case string: + actions = append(actions, action) + case bool: + actions = append(actions, strconv.FormatBool(action)) + case float64: + actions = append(actions, strconv.FormatFloat(action, 'f', -1, 64)) + default: return nil } - - actions[i] = action.(string) } return awsStringSet(actions) } diff --git a/aws_policy_equivalence_test.go b/aws_policy_equivalence_test.go index dd9c6b7..18f2f89 100644 --- a/aws_policy_equivalence_test.go +++ b/aws_policy_equivalence_test.go @@ -298,6 +298,24 @@ func TestPolicyEquivalence(t *testing.T) { policy2: policyTest33, equivalent: false, }, + { + name: "Boolean condition with and without quotes on single value", + policy1: policyTest34a, + policy2: policyTest34b, + equivalent: true, + }, + { + name: "Numeric condition with and without quotes on single value", + policy1: policyTest35a, + policy2: policyTest35b, + equivalent: true, + }, + { + name: "Numeric condition with and without quotes on array of values", + policy1: policyTest36a, + policy2: policyTest36b, + equivalent: true, + }, } for _, tc := range cases { @@ -1292,7 +1310,7 @@ const policyTest32 = `{ "Action": [ "s3:PutObject" ], - "Resource": 42 + "Resource": {} } ] }` @@ -1306,7 +1324,133 @@ const policyTest33 = `{ "Action": [ "s3:PutObject" ], - "Resource": [42] + "Resource": [[42]] } ] }` + +const policyTest34a = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "Bool": { + "aws:MultiFactorAuthPresent": true + } + } + } + ] + }` + +const policyTest34b = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "Bool": { + "aws:MultiFactorAuthPresent": "true" + } + } + } + ] + }` + +const policyTest35a = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "NumericLessThanEquals": { + "aws:MultiFactorAuthAge": 100 + } + } + } + ] + }` + +const policyTest35b = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "NumericLessThanEquals": { + "aws:MultiFactorAuthAge": "100" + } + } + } + ] + }` + +const policyTest36a = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "NumericEquals": { + "aws:MultiFactorAuthAge": [100.01, 200.2] + } + } + } + ] + }` + +const policyTest36b = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "statement1", + "Effect": "Allow", + "Action": [ + "s3:PutObject" + ], + "Resource": [ + "arn:aws:s3:::examplebucket/*" + ], + "Condition": { + "NumericEquals": { + "aws:MultiFactorAuthAge": ["100.01", "200.2"] + } + } + } + ] + }`