[#28] iam: Fix converters

Handle resource without object as bucket name instead of bucket with any object

Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
Denis Kirillov 2023-12-11 14:43:47 +03:00 committed by Evgenii Stratonikov
parent 3b107e9413
commit 1d07331f5d
4 changed files with 56 additions and 5 deletions

View file

@ -256,7 +256,7 @@ func parseResourceAsS3ARN(resource string) (bucket string, object string, err er
s3Resource := strings.TrimPrefix(resource, s3ResourcePrefix)
sepIndex := strings.Index(s3Resource, "/")
if sepIndex < 0 {
return s3Resource, Wildcard, nil
return s3Resource, "", nil
}
bucket = s3Resource[:sepIndex]

View file

@ -177,7 +177,7 @@ func formNativeResourceNamesAndConditions(names []string, resolver NativeResolve
}
resource := fmt.Sprintf(native.ResourceFormatRootContainerObjects, cnrID)
if obj == Wildcard {
if obj == Wildcard || obj == "" {
combined = append(combined, resource)
continue
}

View file

@ -149,7 +149,7 @@ func formS3ResourceNames(names []string) ([]string, error) {
return nil, err
}
if bkt == Wildcard {
if bkt == Wildcard || obj == "" {
res[i] = bkt
continue
}

View file

@ -1072,6 +1072,57 @@ func TestComplexS3Conditions(t *testing.T) {
}
}
func TestS3BucketResource(t *testing.T) {
namespace := "ns"
bktName1, bktName2 := "bucket1", "bucket2"
chainName := chain.Name("name")
mockResolver := newMockUserResolver([]string{}, []string{bktName1})
p := Policy{
Version: "2012-10-17",
Statement: []Statement{
{
Principal: map[PrincipalType][]string{Wildcard: nil},
Effect: DenyEffect,
Action: []string{"s3:HeadBucket"},
Resource: []string{"arn:aws:s3:::" + bktName1},
},
{
Principal: map[PrincipalType][]string{Wildcard: nil},
Effect: AllowEffect,
Action: []string{"*"},
Resource: []string{"arn:aws:s3:::*"},
},
},
}
s3Chain, err := ConvertToS3Chain(p, mockResolver)
require.NoError(t, err)
s := inmemory.NewInMemory()
_, _, err = s.MorphRuleChainStorage().AddMorphRuleChain(chainName, engine.NamespaceTarget(namespace), s3Chain)
require.NoError(t, err)
// check we match just "bucket1" resource
req := testutil.NewRequest("HeadBucket", testutil.NewResource(bktName1, nil), nil)
status, _, err := s.IsAllowed(chainName, engine.NewRequestTargetWithNamespace(namespace), req)
require.NoError(t, err)
require.Equal(t, chain.AccessDenied.String(), status.String())
// check we match just "bucket2" resource
req = testutil.NewRequest("HeadBucket", testutil.NewResource(bktName2, nil), nil)
status, _, err = s.IsAllowed(chainName, engine.NewRequestTargetWithNamespace(namespace), req)
require.NoError(t, err)
require.Equal(t, chain.Allow.String(), status.String())
// check we also match "bucket2/object" resource
req = testutil.NewRequest("PutObject", testutil.NewResource(bktName2+"/object", nil), nil)
status, _, err = s.IsAllowed(chainName, engine.NewRequestTargetWithNamespace(namespace), req)
require.NoError(t, err)
require.Equal(t, chain.Allow.String(), status.String())
}
func TestWildcardConverters(t *testing.T) {
policy := `{"Version":"2012-10-17","Statement":{"Effect":"Allow", "Principal": "*", "Action":"*","Resource":"*"}}`
@ -1223,7 +1274,7 @@ func TestResourceParsing(t *testing.T) {
{
resource: "arn:aws:s3:::bkt",
expectedBucket: "bkt",
expectedObject: "*",
expectedObject: "",
},
{
resource: "arn:aws:s3:::bkt/",
@ -1233,7 +1284,7 @@ func TestResourceParsing(t *testing.T) {
{
resource: "arn:aws:s3:::*",
expectedBucket: "*",
expectedObject: "*",
expectedObject: "",
},
{
resource: "*",