package iam import ( "encoding/json" "testing" "github.com/stretchr/testify/require" ) func TestUnmarshalIAMPolicy(t *testing.T) { t.Run("simple fields", func(t *testing.T) { policy := `{ "Version": "2012-10-17", "Id": "PutObjPolicy", "Statement": { "Sid": "DenyObjectsThatAreNotSSEKMS", "Principal": "*", "Effect": "Deny", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "Null": { "s3:x-amz-server-side-encryption-aws-kms-key-id": "true" } } } }` expected := Policy{ Version: "2012-10-17", ID: "PutObjPolicy", Statement: []Statement{{ SID: "DenyObjectsThatAreNotSSEKMS", Principal: map[string][]string{ "*": nil, }, Effect: DenyEffect, Action: []string{"s3:PutObject"}, Resource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"}, Conditions: map[string]Condition{ "Null": { "s3:x-amz-server-side-encryption-aws-kms-key-id": {"true"}, }, }, }}, } var p Policy err := json.Unmarshal([]byte(policy), &p) require.NoError(t, err) require.Equal(t, expected, p) }) t.Run("complex fields", func(t *testing.T) { policy := `{ "Version": "2012-10-17", "Statement": [{ "Principal":{ "AWS":[ "arn:aws:iam::111122223333:user/JohnDoe" ] }, "Effect": "Allow", "Action": [ "s3:PutObject" ], "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ], "Condition": { "StringEquals": { "s3:RequestObjectTag/Department": ["Finance"] } } }] }` expected := Policy{ Version: "2012-10-17", Statement: []Statement{{ Principal: map[string][]string{ "AWS": {"arn:aws:iam::111122223333:user/JohnDoe"}, }, Effect: AllowEffect, Action: []string{"s3:PutObject"}, Resource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"}, Conditions: map[string]Condition{ "StringEquals": { "s3:RequestObjectTag/Department": {"Finance"}, }, }, }}, } var p Policy err := json.Unmarshal([]byte(policy), &p) require.NoError(t, err) require.Equal(t, expected, p) raw, err := json.Marshal(expected) require.NoError(t, err) require.JSONEq(t, policy, string(raw)) }) t.Run("check principal AWS", func(t *testing.T) { policy := `{ "Statement": [{ "Principal":{ "AWS":"arn:aws:iam::111122223333:user/JohnDoe" } }] }` expected := Policy{ Statement: []Statement{{ Principal: map[string][]string{ "AWS": {"arn:aws:iam::111122223333:user/JohnDoe"}, }, }}, } var p Policy err := json.Unmarshal([]byte(policy), &p) require.NoError(t, err) require.Equal(t, expected, p) }) t.Run("native example", func(t *testing.T) { policy := ` { "Version": "xyz", "Statement": [ { "Effect": "Allow", "Action": [ "native:*", "s3:PutObject", "s3:GetObject" ], "Resource": ["*"], "Principal": {"FrostFS": ["did:frostfs:039e3ee771a223361fe7862f532e9511b57baaae3c3e2622682e99d0e660f7671"]}, "Condition": {"StringEquals": {"native::object::attribute": "iamuser-admin"}} } ] }` var p Policy err := json.Unmarshal([]byte(policy), &p) require.NoError(t, err) }) t.Run("condition array", func(t *testing.T) { policy := ` { "Statement": [{ "Condition": {"StringLike": {"ec2:InstanceType": ["t1.*", "t2.*", "m3.*"]}} }] }` expected := Policy{ Statement: []Statement{{ Conditions: map[string]Condition{ "StringLike": {"ec2:InstanceType": {"t1.*", "t2.*", "m3.*"}}, }, }}, } var p Policy err := json.Unmarshal([]byte(policy), &p) require.NoError(t, err) require.Equal(t, expected, p) }) }