-
Notifications
You must be signed in to change notification settings - Fork 162
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1588 from snyk/fea/add_aws_s3_account_public_acce…
…ss_block add support for aws s3 account public access block
- Loading branch information
Showing
44 changed files
with
4,620 additions
and
72 deletions.
There are no files selected for viewing
41 changes: 40 additions & 1 deletion
41
enumeration/remote/aws/client/mock_AwsClientFactoryInterface.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
enumeration/remote/aws/repository/mock_S3ControlRepository.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package repository | ||
|
||
import ( | ||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/s3control" | ||
"github.com/snyk/driftctl/enumeration/remote/aws/client" | ||
"github.com/snyk/driftctl/enumeration/remote/cache" | ||
) | ||
|
||
type S3ControlRepository interface { | ||
DescribeAccountPublicAccessBlock(accountID string) (*s3control.PublicAccessBlockConfiguration, error) | ||
} | ||
|
||
type s3ControlRepository struct { | ||
clientFactory client.AwsClientFactoryInterface | ||
cache cache.Cache | ||
} | ||
|
||
func NewS3ControlRepository(factory client.AwsClientFactoryInterface, c cache.Cache) *s3ControlRepository { | ||
return &s3ControlRepository{ | ||
clientFactory: factory, | ||
cache: c, | ||
} | ||
} | ||
|
||
func (s *s3ControlRepository) DescribeAccountPublicAccessBlock(accountID string) (*s3control.PublicAccessBlockConfiguration, error) { | ||
cacheKey := "S3DescribeAccountPublicAccessBlock" | ||
if v := s.cache.Get(cacheKey); v != nil { | ||
return v.(*s3control.PublicAccessBlockConfiguration), nil | ||
} | ||
out, err := s.clientFactory.GetS3ControlClient(nil).GetPublicAccessBlock(&s3control.GetPublicAccessBlockInput{ | ||
AccountId: aws.String(accountID), | ||
}) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
result := out.PublicAccessBlockConfiguration | ||
|
||
s.cache.Put(cacheKey, result) | ||
return result, nil | ||
} |
92 changes: 92 additions & 0 deletions
92
enumeration/remote/aws/repository/s3control_repository_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package repository | ||
|
||
import ( | ||
"strings" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/service/s3control" | ||
"github.com/snyk/driftctl/enumeration/remote/aws/client" | ||
"github.com/snyk/driftctl/enumeration/remote/cache" | ||
"github.com/stretchr/testify/mock" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/awserr" | ||
"github.com/r3labs/diff/v2" | ||
awstest "github.com/snyk/driftctl/test/aws" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func Test_s3ControlRepository_DescribeAccountPublicAccessBlock(t *testing.T) { | ||
accountID := "123456" | ||
|
||
tests := []struct { | ||
name string | ||
mocks func(client *awstest.MockFakeS3Control) | ||
want *s3control.PublicAccessBlockConfiguration | ||
wantErr error | ||
}{ | ||
{ | ||
name: "describe account public accessblock", | ||
mocks: func(client *awstest.MockFakeS3Control) { | ||
client.On("GetPublicAccessBlock", mock.Anything).Return( | ||
&s3control.GetPublicAccessBlockOutput{ | ||
PublicAccessBlockConfiguration: &s3control.PublicAccessBlockConfiguration{ | ||
BlockPublicAcls: aws.Bool(false), | ||
BlockPublicPolicy: aws.Bool(true), | ||
IgnorePublicAcls: aws.Bool(false), | ||
RestrictPublicBuckets: aws.Bool(true), | ||
}, | ||
}, | ||
nil, | ||
).Once() | ||
}, | ||
want: &s3control.PublicAccessBlockConfiguration{ | ||
BlockPublicAcls: aws.Bool(false), | ||
BlockPublicPolicy: aws.Bool(true), | ||
IgnorePublicAcls: aws.Bool(false), | ||
RestrictPublicBuckets: aws.Bool(true), | ||
}, | ||
}, | ||
{ | ||
name: "Error detting account public accessblock", | ||
mocks: func(client *awstest.MockFakeS3Control) { | ||
client.On("GetPublicAccessBlock", mock.Anything).Return( | ||
nil, | ||
awserr.NewRequestFailure(nil, 403, ""), | ||
).Once() | ||
}, | ||
want: nil, | ||
wantErr: awserr.NewRequestFailure(nil, 403, ""), | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
store := cache.New(1) | ||
mockedClient := &awstest.MockFakeS3Control{} | ||
tt.mocks(mockedClient) | ||
factory := client.MockAwsClientFactoryInterface{} | ||
factory.On("GetS3ControlClient", (*aws.Config)(nil)).Return(mockedClient).Once() | ||
r := NewS3ControlRepository(&factory, store) | ||
got, err := r.DescribeAccountPublicAccessBlock(accountID) | ||
factory.AssertExpectations(t) | ||
assert.Equal(t, tt.wantErr, err) | ||
|
||
if err == nil { | ||
// Check that results were cached | ||
cachedData, err := r.DescribeAccountPublicAccessBlock(accountID) | ||
assert.NoError(t, err) | ||
assert.Equal(t, got, cachedData) | ||
assert.IsType(t, &s3control.PublicAccessBlockConfiguration{}, store.Get("S3DescribeAccountPublicAccessBlock")) | ||
} | ||
|
||
changelog, err := diff.Diff(got, tt.want) | ||
assert.Nil(t, err) | ||
if len(changelog) > 0 { | ||
for _, change := range changelog { | ||
t.Errorf("%s: %s -> %s", strings.Join(change.Path, "."), change.From, change.To) | ||
} | ||
t.Fail() | ||
} | ||
}) | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
enumeration/remote/aws/s3_account_public_access_block_enumerator.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package aws | ||
|
||
import ( | ||
awssdk "github.com/aws/aws-sdk-go/aws" | ||
"github.com/snyk/driftctl/enumeration/alerter" | ||
"github.com/snyk/driftctl/enumeration/remote/aws/repository" | ||
remoteerror "github.com/snyk/driftctl/enumeration/remote/error" | ||
"github.com/snyk/driftctl/enumeration/resource" | ||
"github.com/snyk/driftctl/enumeration/resource/aws" | ||
) | ||
|
||
type S3AccountPublicAccessBlockEnumerator struct { | ||
repository repository.S3ControlRepository | ||
factory resource.ResourceFactory | ||
accountID string | ||
alerter alerter.AlerterInterface | ||
} | ||
|
||
func NewS3AccountPublicAccessBlockEnumerator(repo repository.S3ControlRepository, factory resource.ResourceFactory, accountId string, alerter alerter.AlerterInterface) *S3AccountPublicAccessBlockEnumerator { | ||
return &S3AccountPublicAccessBlockEnumerator{ | ||
repository: repo, | ||
factory: factory, | ||
accountID: accountId, | ||
alerter: alerter, | ||
} | ||
} | ||
|
||
func (e *S3AccountPublicAccessBlockEnumerator) SupportedType() resource.ResourceType { | ||
return aws.AwsS3AccountPublicAccessBlock | ||
} | ||
|
||
func (e *S3AccountPublicAccessBlockEnumerator) Enumerate() ([]*resource.Resource, error) { | ||
accountPublicAccessBlock, err := e.repository.DescribeAccountPublicAccessBlock(e.accountID) | ||
if err != nil { | ||
return nil, remoteerror.NewResourceListingError(err, string(e.SupportedType())) | ||
} | ||
|
||
results := make([]*resource.Resource, 0, 1) | ||
|
||
results = append( | ||
results, | ||
e.factory.CreateAbstractResource( | ||
string(e.SupportedType()), | ||
e.accountID, | ||
map[string]interface{}{ | ||
"block_public_acls": awssdk.BoolValue(accountPublicAccessBlock.BlockPublicAcls), | ||
"block_public_policy": awssdk.BoolValue(accountPublicAccessBlock.BlockPublicPolicy), | ||
"ignore_public_acls": awssdk.BoolValue(accountPublicAccessBlock.IgnorePublicAcls), | ||
"restrict_public_buckets": awssdk.BoolValue(accountPublicAccessBlock.RestrictPublicBuckets), | ||
}, | ||
), | ||
) | ||
|
||
return results, err | ||
} |
Oops, something went wrong.