Skip to content

Commit

Permalink
update policy document creation when Statement is nil
Browse files Browse the repository at this point in the history
  • Loading branch information
anGie44 committed Mar 31, 2022
1 parent bd206d4 commit 8ff1deb
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 12 deletions.
33 changes: 21 additions & 12 deletions aws_policy_equivalence.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,24 @@ type intermediatePolicyDocument struct {
func (intermediate *intermediatePolicyDocument) document() (*policyDocument, error) {
var statements []*policyStatement

switch s := intermediate.Statements.(type) {
case []interface{}:
if err := mapstructure.Decode(s, &statements); err != nil {
return nil, fmt.Errorf("Error parsing statement: %s", err)
}
case map[string]interface{}:
var singleStatement *policyStatement
if err := mapstructure.Decode(s, &singleStatement); err != nil {
return nil, fmt.Errorf("Error parsing statement: %s", err)
// Decode only non-nil statements to prevent irreversible result when setting values
// in Terraform state.
// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/22944
if intermediate.Statements != nil {
switch s := intermediate.Statements.(type) {
case []interface{}:
if err := mapstructure.Decode(s, &statements); err != nil {
return nil, fmt.Errorf("Error parsing statement: %s", err)
}
case map[string]interface{}:
var singleStatement *policyStatement
if err := mapstructure.Decode(s, &singleStatement); err != nil {
return nil, fmt.Errorf("Error parsing statement: %s", err)
}
statements = append(statements, singleStatement)
default:
return nil, errors.New("Unknown error parsing statement")
}
statements = append(statements, singleStatement)
default:
return nil, errors.New("Unknown error parsing statement")
}

document := &policyDocument{
Expand All @@ -93,6 +98,10 @@ type policyDocument struct {
}

func (doc *policyDocument) equals(other *policyDocument) bool {
// Prevent panic
if doc == nil {
return other == nil
}
// Check the basic fields of the document
if doc.Version != other.Version {
return false
Expand Down
68 changes: 68 additions & 0 deletions aws_policy_equivalence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package awspolicy
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

import (
"encoding/json"
"testing"
)

Expand Down Expand Up @@ -1581,3 +1582,70 @@ func TestStringValueSlicesEqualIgnoreOrder(t *testing.T) {
}
}
}

func TestIntermediatePolicyDocument(t *testing.T) {
cases := []struct {
name string
inputPolicy string
expectedPolicyDocument *policyDocument
err bool
}{
{
name: "Invalid Policy With Version and Null Statement",
inputPolicy: `{
"Version": "2012-10-17",
"Statement": "null"
}`,
err: true,
},
{
name: "Policy With Version and Null Statement",
inputPolicy: `{
"Version": "2012-10-17",
"Statement": null
}`,
expectedPolicyDocument: &policyDocument{
Version: "2012-10-17",
Statements: nil,
},
},
{
name: "Basic Policy",
inputPolicy: policyTest1,
expectedPolicyDocument: &policyDocument{
Version: "2012-10-17",
Statements: []*policyStatement{
{
Sid: "",
Effect: "Allow",
Principals: map[string]interface{}{
"Service": "spotfleet.amazonaws.com",
},
Actions: "sts:AssumeRole",
},
},
},
},
}

for _, tc := range cases {
policy1intermediate := &intermediatePolicyDocument{}
err := json.Unmarshal([]byte(tc.inputPolicy), policy1intermediate)
if err != nil {
t.Fatalf("Error unmarshaling policy: %s", err)
}

actual, err := policy1intermediate.document()

if !tc.err && err != nil {
t.Fatalf("Unexpected error: %s", err)
}
if tc.err && err == nil {
t.Fatal("Expected error, none produced")
}

if !actual.equals(tc.expectedPolicyDocument) {
t.Fatalf("Bad: %s\n Expected: %v\n Got: %v\n", tc.name, tc.expectedPolicyDocument, actual)
}
}
}

0 comments on commit 8ff1deb

Please sign in to comment.