policy-engine/iam/converter_test.go
Denis Kirillov 63ecf63a08 [#11] iam: Support 'NotPrincipal', 'NotAction', 'NotResource'
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2023-11-02 14:55:48 +03:00

306 lines
8.6 KiB
Go

package iam
import (
"testing"
policyengine "git.frostfs.info/TrueCloudLab/policy-engine"
"github.com/stretchr/testify/require"
)
func TestConverters(t *testing.T) {
t.Run("valid policy", func(t *testing.T) {
p := Policy{
Version: "2012-10-17",
Statement: []Statement{{
Principal: map[PrincipalType][]string{
AWSPrincipalType: {"arn:aws:iam::111122223333:user/JohnDoe"},
},
Effect: AllowEffect,
Action: []string{"s3:PutObject"},
Resource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"},
Conditions: map[string]Condition{
CondStringEquals: {
"s3:RequestObjectTag/Department": {"Finance"},
},
},
}},
}
expected := &policyengine.Chain{Rules: []policyengine.Rule{
{
Status: policyengine.Allow,
Actions: policyengine.Actions{Names: p.Statement[0].Action},
Resources: policyengine.Resources{Names: p.Statement[0].Resource},
Any: true,
Condition: []policyengine.Condition{
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: RequestOwnerProperty,
Value: "arn:aws:iam::111122223333:user/JohnDoe",
},
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: "s3:RequestObjectTag/Department",
Value: "Finance",
},
},
},
}}
chain, err := p.ToChain()
require.NoError(t, err)
require.Equal(t, expected, chain)
})
t.Run("valid inverted policy", func(t *testing.T) {
p := Policy{
Version: "2012-10-17",
Statement: []Statement{{
NotPrincipal: map[PrincipalType][]string{
AWSPrincipalType: {"arn:aws:iam::111122223333:user/JohnDoe"},
},
Effect: DenyEffect,
NotAction: []string{"s3:PutObject"},
NotResource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"},
}},
}
expected := &policyengine.Chain{Rules: []policyengine.Rule{
{
Status: policyengine.AccessDenied,
Actions: policyengine.Actions{Inverted: true, Names: p.Statement[0].NotAction},
Resources: policyengine.Resources{Inverted: true, Names: p.Statement[0].NotResource},
Any: true,
Condition: []policyengine.Condition{
{
Op: policyengine.CondStringNotEquals,
Object: policyengine.ObjectRequest,
Key: RequestOwnerProperty,
Value: "arn:aws:iam::111122223333:user/JohnDoe",
},
},
},
}}
chain, err := p.ToChain()
require.NoError(t, err)
require.Equal(t, expected, chain)
})
t.Run("invalid policy (unsupported principal type)", func(t *testing.T) {
p := Policy{
Version: "2012-10-17",
Statement: []Statement{{
Principal: map[PrincipalType][]string{
"dummy": {"arn:aws:iam::111122223333:user/JohnDoe"},
},
Effect: AllowEffect,
Action: []string{"s3:PutObject"},
Resource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"},
}},
}
_, err := p.ToChain()
require.Error(t, err)
})
t.Run("invalid policy (missing resource)", func(t *testing.T) {
p := Policy{
Version: "2012-10-17",
Statement: []Statement{{
Principal: map[PrincipalType][]string{
AWSPrincipalType: {"arn:aws:iam::111122223333:user/JohnDoe"},
},
Effect: AllowEffect,
Action: []string{"s3:PutObject"},
}},
}
_, err := p.ToChain()
require.Error(t, err)
})
t.Run("check policy conditions", func(t *testing.T) {
p := Policy{
Version: "2012-10-17",
Statement: []Statement{{
Principal: map[PrincipalType][]string{Wildcard: nil},
Effect: AllowEffect,
Action: []string{"s3:PutObject"},
Resource: []string{"arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"},
Conditions: Conditions{
CondStringEquals: {"key1": {"val0", "val1"}},
CondStringNotEquals: {"key2": {"val2"}},
CondStringEqualsIgnoreCase: {"key3": {"val3"}},
CondStringNotEqualsIgnoreCase: {"key4": {"val4"}},
CondStringLike: {"key5": {"val5"}},
CondStringNotLike: {"key6": {"val6"}},
CondDateEquals: {"key7": {"2006-01-02T15:04:05+07:00"}},
CondDateNotEquals: {"key8": {"2006-01-02T15:04:05Z"}},
CondDateLessThan: {"key9": {"2006-01-02T15:04:05+06:00"}},
CondDateLessThanEquals: {"key10": {"2006-01-02T15:04:05+03:00"}},
CondDateGreaterThan: {"key11": {"2006-01-02T15:04:05-01:00"}},
CondDateGreaterThanEquals: {"key12": {"2006-01-02T15:04:05-03:00"}},
CondBool: {"key13": {"True"}},
CondIPAddress: {"key14": {"val14"}},
CondNotIPAddress: {"key15": {"val15"}},
CondArnEquals: {"key16": {"val16"}},
CondArnLike: {"key17": {"val17"}},
CondArnNotEquals: {"key18": {"val18"}},
CondArnNotLike: {"key19": {"val19"}},
},
}},
}
expected := &policyengine.Chain{Rules: []policyengine.Rule{
{
Status: policyengine.Allow,
Actions: policyengine.Actions{Names: p.Statement[0].Action},
Resources: policyengine.Resources{Names: p.Statement[0].Resource},
Any: true,
Condition: []policyengine.Condition{
{
Op: policyengine.CondStringLike,
Object: policyengine.ObjectRequest,
Key: RequestOwnerProperty,
Value: "*",
},
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: "key1",
Value: "val0",
},
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: "key1",
Value: "val1",
},
{
Op: policyengine.CondStringNotEquals,
Object: policyengine.ObjectRequest,
Key: "key2",
Value: "val2",
},
{
Op: policyengine.CondStringEqualsIgnoreCase,
Object: policyengine.ObjectRequest,
Key: "key3",
Value: "val3",
},
{
Op: policyengine.CondStringNotEqualsIgnoreCase,
Object: policyengine.ObjectRequest,
Key: "key4",
Value: "val4",
},
{
Op: policyengine.CondStringLike,
Object: policyengine.ObjectRequest,
Key: "key5",
Value: "val5",
},
{
Op: policyengine.CondStringNotLike,
Object: policyengine.ObjectRequest,
Key: "key6",
Value: "val6",
},
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: "key7",
Value: "1136189045",
},
{
Op: policyengine.CondStringNotEquals,
Object: policyengine.ObjectRequest,
Key: "key8",
Value: "1136214245",
},
{
Op: policyengine.CondStringLessThan,
Object: policyengine.ObjectRequest,
Key: "key9",
Value: "1136192645",
},
{
Op: policyengine.CondStringLessThanEquals,
Object: policyengine.ObjectRequest,
Key: "key10",
Value: "1136203445",
},
{
Op: policyengine.CondStringGreaterThan,
Object: policyengine.ObjectRequest,
Key: "key11",
Value: "1136217845",
},
{
Op: policyengine.CondStringGreaterThanEquals,
Object: policyengine.ObjectRequest,
Key: "key12",
Value: "1136225045",
},
{
Op: policyengine.CondStringEqualsIgnoreCase,
Object: policyengine.ObjectRequest,
Key: "key13",
Value: "True",
},
{
Op: policyengine.CondStringLike,
Object: policyengine.ObjectRequest,
Key: "key14",
Value: "val14",
},
{
Op: policyengine.CondStringNotLike,
Object: policyengine.ObjectRequest,
Key: "key15",
Value: "val15",
},
{
Op: policyengine.CondStringEquals,
Object: policyengine.ObjectRequest,
Key: "key16",
Value: "val16",
},
{
Op: policyengine.CondStringLike,
Object: policyengine.ObjectRequest,
Key: "key17",
Value: "val17",
},
{
Op: policyengine.CondStringNotEquals,
Object: policyengine.ObjectRequest,
Key: "key18",
Value: "val18",
},
{
Op: policyengine.CondStringNotLike,
Object: policyengine.ObjectRequest,
Key: "key19",
Value: "val19",
},
},
},
}}
chain, err := p.ToChain()
require.NoError(t, err)
for i, rule := range chain.Rules {
expectedRule := expected.Rules[i]
require.Equal(t, expectedRule.Actions, rule.Actions)
require.Equal(t, expectedRule.Any, rule.Any)
require.Equal(t, expectedRule.Resources, rule.Resources)
require.Equal(t, expectedRule.Status, rule.Status)
require.ElementsMatch(t, expectedRule.Condition, rule.Condition)
}
})
}