Skip to content

Commit

Permalink
Merge pull request #7 from hashicorp/f-optional-quotation-marks-for-b…
Browse files Browse the repository at this point in the history
…oolean-and-numeric

Convert boolean and numeric values to strings for value comparison
  • Loading branch information
ewbankkit authored Dec 6, 2021
2 parents 054f6be + c7eb438 commit 853611c
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 17 deletions.
36 changes: 21 additions & 15 deletions aws_policy_equivalence.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"reflect"
"regexp"
"sort"
"strconv"
"strings"

"github.com/aws/aws-sdk-go/aws/arn"
Expand Down Expand Up @@ -381,26 +382,31 @@ func newStringSet(members interface{}) stringSet {
return stringSet{}
}

if single, ok := members.(string); ok {
return stringSet{single}
}

if multiple, ok := members.([]interface{}); ok {
if len(multiple) == 0 {
return stringSet{}
}
actions := make([]string, len(multiple))
for i, action := range multiple {
if _, ok := action.(string); !ok {
switch v := members.(type) {
case string:
return stringSet{v}
case bool:
return stringSet{strconv.FormatBool(v)}
case float64:
return stringSet{strconv.FormatFloat(v, 'f', -1, 64)}
case []interface{}:
var actions []string
for _, action := range v {
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 stringSet(actions)
default:
return nil
}

return nil
}

func newPrincipalStringSet(members interface{}) principalStringSet {
Expand Down
148 changes: 146 additions & 2 deletions aws_policy_equivalence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,24 @@ func TestPolicyEquivalence(t *testing.T) {
policy2: policyTest34c,
equivalent: false,
},
{
name: "Boolean condition with and without quotes on single value",
policy1: policyTest35a,
policy2: policyTest35b,
equivalent: true,
},
{
name: "Numeric condition with and without quotes on single value",
policy1: policyTest36a,
policy2: policyTest36b,
equivalent: true,
},
{
name: "Numeric condition with and without quotes on array of values",
policy1: policyTest37a,
policy2: policyTest37b,
equivalent: true,
},
}

for _, tc := range cases {
Expand Down Expand Up @@ -1255,7 +1273,7 @@ const policyTest32 = `{
"Action": [
"s3:PutObject"
],
"Resource": 42
"Resource": {}
}
]
}`
Expand All @@ -1269,7 +1287,7 @@ const policyTest33 = `{
"Action": [
"s3:PutObject"
],
"Resource": [42]
"Resource": [[42]]
}
]
}`
Expand Down Expand Up @@ -1340,6 +1358,132 @@ const policyTest34c = `{
]
}`

const policyTest35a = `{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": true
}
}
}
]
}`

const policyTest35b = `{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}`

const policyTest36a = `{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"NumericLessThanEquals": {
"aws:MultiFactorAuthAge": 100
}
}
}
]
}`

const policyTest36b = `{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::examplebucket/*"
],
"Condition": {
"NumericLessThanEquals": {
"aws:MultiFactorAuthAge": "100"
}
}
}
]
}`

const policyTest37a = `{
"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 policyTest37b = `{
"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"]
}
}
}
]
}`

func TestStringValueSlicesEqualIgnoreOrder(t *testing.T) {
equal := []interface{}{
[]interface{}{
Expand Down

0 comments on commit 853611c

Please sign in to comment.