예제 #1
0
    def setUp(self) -> None:
        self.owner = Address.from_string(f"cx{'0'*40}")

        db = Mock(spec=IconScoreDatabase)
        db.configure_mock(address=f"cx{'0'*40}")
        IconScoreContextUtil.get_owner = Mock(return_value=self.owner)

        self.governance = Governance(db)
예제 #2
0
 def setup_method(self):
     """ Initialise Test Suite """
     self.mock_template = {
         'Resources': {
             'Bucket': {
                 'Type': 'AWS::S3::Bucket',
                 'Properties': {
                     'BucketName': 'test-bucket-name'
                 }
             }
         }
     }
     self.mock_governance = Gov()
예제 #3
0
def deploy_governed_template_handler(event, context):
    """ Lambda handler to handles the deployment
    of governed CloudFormation Templates

    Args:
        event (dict): event details from request
        context (dict): context of the lambda function

    Returns:
        response (dict): response built from handler
    """

    payload = event['Payload']
    env = event['Env']
    cf_builder = CF_BUILDER()
    s3_cf = S3_CF(payload=payload)
    s3_cf.set_template()
    resource = s3_cf.get_template()

    if 'Description' in event:
        cf_builder.set_description(event['Description'])
    cf_builder.set_resources(resource_type='S3Bucket', resource=resource)
    template = cf_builder.get_template()

    governance = Governance()
    governance.set_template(template=template)
    governance.get_resources()
    governance.validate()

    template = governance.get_template()

    if s3_cf.get_bucketname()['ResponseCode'] == 200:
        stackname = 's3-{}'.format(s3_cf.get_bucketname()['Message'])
        create_cloudformation(stack=stackname,
                              template=template,
                              region=env['region'])

    response = {}
    response['Test'] = 'Deploy Governance Lambda Handler'
    response['Template'] = template
    response['Env'] = env

    return response
예제 #4
0
def validate_governed_payload_handler(event, context):
    """ Lambda handler to validate a payload, construct a
    CloudFormation template and apply governance checks

    Args:
        event (dict): event details from request
        context (dict): context of the lambda function

    Returns:
        response (dict): response built from handler
    """

    payload = event['Payload']
    env = event['Env']
    cf_builder = CF_BUILDER()
    s3_cf = S3_CF(payload=payload)
    s3_cf.set_template()
    resource = s3_cf.get_template()

    if 'Description' in event:
        cf_builder.set_description(event['Description'])
    cf_builder.set_resources(resource_type='S3Bucket', resource=resource)
    template = cf_builder.get_template()

    governance = Governance()
    governance.set_template(template=template)
    governance.get_resources()
    governance.validate()

    template = governance.get_template()

    response = {}
    response['Test'] = 'Validation Governance Lambda Handler'
    response['Template'] = template
    response['Env'] = env

    return response
예제 #5
0
class TestUnitGovernance(unittest.TestCase):
    @patch_several(PATCHER_ARRAY_DB, PATCHER_DICT_DB, PATCHER_VAR_DB,
                   PATCHER_NP_ARRAY_DB, PATCHER_NP_DICT_DB)
    def setUp(self) -> None:
        self.owner = Address.from_string(f"cx{'0'*40}")

        db = Mock(spec=IconScoreDatabase)
        db.configure_mock(address=f"cx{'0'*40}")
        IconScoreContextUtil.get_owner = Mock(return_value=self.owner)

        self.governance = Governance(db)

    @patch_several(PATCHER_VALIDATE_TEXT_PROPOSAL,
                   PATCHER_VALIDATE_REVISION_PROPOSAL,
                   PATCHER_VALIDATE_MALICIOUS_SCORE_PROPOSAL,
                   PATCHER_VALIDATE_PREP_DISQUALIFICATION_PROPOSAL,
                   PATCHER_VALIDATE_STEP_PRICE_PROPOSAL,
                   PATCHER_VALIDATE_IREP_PROPOSAL)
    def test_validate_network_proposal(self):
        for invalid_vote_type in (6, 7, -1, 1000):
            tmp_value = {}
            self.assertFalse(
                self.governance._validate_network_proposal(
                    invalid_vote_type, tmp_value))

        value_of_type_0 = {"value": "text"}
        value_of_type_1 = {"code": hex(0), "name": "1.1.0"}
        value_of_type_2 = {"address": str(create_address()), "type": hex(0)}
        value_of_type_3 = {"address": str(create_address())}
        value_of_type_4 = {"value": hex(0)}
        value_of_type_5 = {"value": hex(0)}

        return_value = self.governance._validate_network_proposal(
            0, value_of_type_0)
        assert self.governance._validate_text_proposal.called and return_value

        return_value = self.governance._validate_network_proposal(
            1, value_of_type_1)
        assert self.governance._validate_revision_proposal.called and return_value

        return_value = self.governance._validate_network_proposal(
            2, value_of_type_2)
        assert self.governance._validate_malicious_score_proposal.called and return_value

        return_value = self.governance._validate_network_proposal(
            3, value_of_type_3)
        assert self.governance._validate_prep_disqualification_proposal.called and return_value

        return_value = self.governance._validate_network_proposal(
            4, value_of_type_4)
        assert self.governance._validate_step_price_proposal.called and return_value

        return_value = self.governance._validate_network_proposal(
            5, value_of_type_5)
        assert self.governance._validate_irep_proposal.called and return_value

    def test_validate_text_proposal(self):
        value_of_type_0 = {"value": "text"}
        assert self.governance._validate_text_proposal(value_of_type_0)

    def test_validate_revision_proposal(self):
        value_of_type_1 = {"code": hex(0), "name": "1.1.0"}
        assert self.governance._validate_revision_proposal(value_of_type_1)

    @patch('governance.governance.Address.is_contract', return_value=True)
    def test_validate_malicious_score_proposal(self, is_contract):
        value_of_type_2 = {
            "address": str(create_address(AddressPrefix.CONTRACT)),
            "type": hex(0)
        }
        assert self.governance._validate_malicious_score_proposal(
            value_of_type_2)

    def test_validate_prep_disqualification_proposal(self):
        main_prep = [
            Prep(create_address(), 0) for _ in range(COUNT_OF_MAIN_PREPS)
        ]
        sub_prep = [
            Prep(create_address(), 0) for _ in range(COUNT_OF_MAIN_PREPS, 100)
        ]

        with patch('governance.governance.get_main_prep_info',
                   return_value=(main_prep, None)):
            with patch('governance.governance.get_sub_prep_info',
                       return_value=(sub_prep, None)):
                value_of_type_3 = {"address": str(main_prep[0].address)}
                assert self.governance._validate_prep_disqualification_proposal(
                    value_of_type_3)
                value_of_type_3 = {"address": str(sub_prep[0].address)}
                assert self.governance._validate_prep_disqualification_proposal(
                    value_of_type_3)
                value_of_type_3 = {"address": str(create_address())}
                assert not self.governance._validate_prep_disqualification_proposal(
                    value_of_type_3)

    @patch('governance.governance.Governance.get_icon_network_value',
           return_value=STEP_PRICE)
    def test_validate_step_price_proposal(self, get_icon_network_value):
        TestCase = namedtuple("TestCase", "step_price, result")
        tests = [
            TestCase(STEP_PRICE + 1, True),
            TestCase(STEP_PRICE - 1, True),
            TestCase(STEP_PRICE * 125 // 100, True),
            TestCase(STEP_PRICE * 126 // 100, False),
            TestCase(STEP_PRICE * 75 // 100, True),
            TestCase(STEP_PRICE * 74 // 100, False),
        ]

        for test in tests:
            value_of_type_4 = {"value": hex(test.step_price)}
            assert test.result == self.governance._validate_step_price_proposal(
                value_of_type_4)
            value_of_type_4 = {"value": str(test.step_price)}
            assert test.result == self.governance._validate_step_price_proposal(
                value_of_type_4)

    @patch('governance.governance.Governance.validate_irep', return_value=True)
    def test_validate_irep_proposal(self, validate_irep):
        value_of_type_5 = {"value": hex(10)}
        assert self.governance._validate_irep_proposal(value_of_type_5)
예제 #6
0
class TestGovernance:
    """ Test Suite for the Governance Class """
    def setup_method(self):
        """ Initialise Test Suite """
        self.mock_template = {
            'Resources': {
                'Bucket': {
                    'Type': 'AWS::S3::Bucket',
                    'Properties': {
                        'BucketName': 'test-bucket-name'
                    }
                }
            }
        }
        self.mock_governance = Gov()

    def test_template_empty_if_not_set(self):
        """ Test Success: Template is empty if not set """
        sut = self.mock_governance.get_template()
        assert sut == {}

    def test_resources_empty_if_not_set(self):
        """ Test Success: Resources is empty if not set """
        test_template = {}
        expected = {}
        self.mock_governance.set_template(template=test_template)
        sut = self.mock_governance.get_resources()
        assert sut == expected

    def test_resources_empty_if_type_not_valid(self):
        """ Test Failure: Resources is empty if type is not valid """
        test_template = {
            'Resources': {
                'Bucket': {
                    'Type': 'AWS::IAM::Role',
                    'Properties': {
                        'RoleName': 'test-iam-role'
                    }
                }
            }
        }
        expected = {}
        self.mock_governance.set_template(template=test_template)
        sut = self.mock_governance.get_resources()
        assert sut == expected

    def test_set_get_template(self):
        """ Test Success: Set and get template """
        self.mock_governance.set_template(template=self.mock_template)
        sut = self.mock_governance.get_template()
        assert sut == self.mock_template

    def test_set_get_template_sets_resources(self):
        """ Test Success: Setting template sets resources correctly """
        expected_resources = {
            'AWS::S3::Bucket': {
                'BucketName': 'test-bucket-name'
            }
        }
        self.mock_governance.set_template(template=self.mock_template)
        sut = self.mock_governance.get_resources()
        assert sut == expected_resources

    def test_validate_does_not_change_template_with_invalid_type(self):
        """ Test Failure: Validate does not change original template if 
        type is invalid  
        """
        expected_template = {
            'Resources': {
                'Bucket': {
                    'Type': 'AWS::IAM::Role',
                    'Properties': {
                        'RoleName': 'test-iam-role'
                    }
                }
            }
        }
        self.mock_governance.set_template(template=expected_template)
        self.mock_governance.validate()
        sut = self.mock_governance.get_template()
        assert sut == expected_template

    def test_validate_does_change_template_with_valid_type(self):
        """ Test Success: Validate changes original template if type valid """
        expected_template = {
            'Resources': {
                'Bucket': {
                    'Type': 'AWS::S3::Bucket',
                    'Properties': {
                        'BucketName': 'test-bucket-name'
                    }
                }
            }
        }
        self.mock_governance.set_template(template=self.mock_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = self.mock_governance.get_template()
        assert sut != expected_template
예제 #7
0
class TestS3_Gov:
    """ Test Suite for the S3 Governance Class """
    def setup_method(self):
        """ Initialise Test Suite """
        self.mock_template = {
            'Resources': {
                'Bucket': {
                    'Type': 'AWS::S3::Bucket',
                    'Properties': {
                        'BucketName': 'test-bucket-name'
                    }
                }
            }
        }
        self.mock_governance = Gov()

    def test_read_governance_rules(self):
        """ Test Success: Rules are set from file """
        expected_type = 'AWS::S3::Bucket'
        self.mock_governance.set_template(template=self.mock_template)
        self.mock_governance.get_resources()
        resources = self.mock_governance.get_resources()
        mock_s3_gov = S3_Gov(res_type=expected_type,
                             res_property=resources[expected_type])
        rules = mock_s3_gov.get_rules()
        assert 'BucketEncryption' in rules
        assert 'VersioningConfiguration' in rules
        assert 'PublicAccessBlockConfiguration' in rules
        assert 'AccessControl' in rules

    def test_bucket_encryption_validates_no_encryption(self):
        """ Test Success: Validates no encryption and sets mandatory encryption """
        test_template = deepcopy(self.mock_template)
        expected_mandatory = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            }]
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'BucketEncryption']
        assert sut == expected_mandatory
        assert test_template != self.mock_template

    def test_bucket_encryption_validates_incorrect_encryption(self):
        """ Test Failure: Validates incorrect encryption and sets mandatory encryption """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['BucketEncryption'] = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'Test': 'test'
                }
            }]
        }
        expected_mandatory = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            }]
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'BucketEncryption']
        assert sut == expected_mandatory

    def test_bucket_encryption_validates_bucket_encryption_mandatory(self):
        """ Test Success: Validates mandatory encryption """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['BucketEncryption'] = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            }]
        }
        expected_mandatory = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'AES256'
                }
            }]
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'BucketEncryption']
        assert sut == expected_mandatory

    def test_bucket_encryption_validates_bucket_encrpytion_accepted(self):
        """ Test Success: Validates accepted encryption """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['BucketEncryption'] = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'aws:kms',
                    'KMSMasterKeyID': '13056591-9cca-457d-84d0-d262c4c370f0'
                }
            }]
        }
        expected_accepted = {
            'ServerSideEncryptionConfiguration': [{
                'ServerSideEncryptionByDefault': {
                    'SSEAlgorithm': 'aws:kms',
                    'KMSMasterKeyID': '13056591-9cca-457d-84d0-d262c4c370f0'
                }
            }]
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'BucketEncryption']
        assert sut == expected_accepted

    def test_version_configuration_validates_no_versioning(self):
        """ Test Success: Validates no versioning and sets mandatory """
        test_template = deepcopy(self.mock_template)
        expected_mandatory = {'Status': 'Enabled'}
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'VersioningConfiguration']
        assert sut == expected_mandatory
        assert test_template != self.mock_template

    def test_version_configuration_validates_diasabled_versioning(self):
        """ Test Success: Validates disabled versioning and sets mandatory """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['VersioningConfiguration'] = {'Status': 'Suspended'}
        expected_mandatory = {'Status': 'Enabled'}
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'VersioningConfiguration']
        assert sut == expected_mandatory

    def test_version_configuration_validates_enabled_versioning(self):
        """ Test Success: Validates enabled versioning and sets mandatory """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['VersioningConfiguration'] = {'Status': 'Enabled'}
        expected_mandatory = {'Status': 'Enabled'}
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'VersioningConfiguration']
        assert sut == expected_mandatory

    def test_public_access_validates_no_public_access_config(self):
        """ Test Success: Validates no public access config and sets mandatory public access """
        test_template = deepcopy(self.mock_template)
        expected_mandatory = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': True,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': True
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'PublicAccessBlockConfiguration']
        assert sut == expected_mandatory
        assert test_template != self.mock_template

    def test_public_access_validates_incorrect_public_access_config(self):
        """ 
        Test Success: Validates incorrect public access config and sets mandatory public access 
        """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['PublicAccessBlockConfiguration'] = {'Test': 'test'}
        expected_mandatory = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': True,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': True
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'PublicAccessBlockConfiguration']
        assert sut == expected_mandatory

    def test_public_access_validates_mandatory_public_access_config(self):
        """ Test Success: Validates mandatory public access config """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['PublicAccessBlockConfiguration'] = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': True,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': True
        }
        expected_mandatory = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': True,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': True
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'PublicAccessBlockConfiguration']
        assert sut == expected_mandatory

    def test_public_access_validates_accepted_public_access_config(self):
        """ Test Success: Validates accepted public access config """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['PublicAccessBlockConfiguration'] = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': False,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': False
        }
        expected_accepted = {
            'BlockPublicAcls': True,
            'BlockPublicPolicy': False,
            'IgnorePublicAcls': True,
            'RestrictPublicBuckets': False
        }
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'PublicAccessBlockConfiguration']
        assert sut == expected_accepted

    def test_access_control_validates_no_access_control(self):
        """ Test Success: Validates no access control and sets mandatory """
        test_template = deepcopy(self.mock_template)
        expected_mandatory = 'BucketOwnerFullControl'
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'AccessControl']
        assert sut == expected_mandatory
        assert test_template != self.mock_template

    def test_access_control_validates_incorrect_access_control(self):
        """ Test Success: Validates incorrect access control and sets mandatory """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['AccessControl'] = 'test'
        expected_mandatory = 'BucketOwnerFullControl'
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'AccessControl']
        assert sut == expected_mandatory

    def test_access_control_validates_mandatory_access_control(self):
        """ Test Success: Validates mandatory access control """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['AccessControl'] = ' BucketOwnerFullControl'
        expected_mandatory = 'BucketOwnerFullControl'
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'AccessControl']
        assert sut == expected_mandatory

    def test_access_control_validates_accepted_access_control(self):
        """ Test Success: Validates accepted access control """
        test_template = deepcopy(self.mock_template)
        properties = test_template['Resources']['Bucket']['Properties']
        properties['AccessControl'] = 'Private'
        expected_accepted = 'Private'
        self.mock_governance.set_template(template=test_template)
        self.mock_governance.get_resources()
        self.mock_governance.validate()
        sut = test_template['Resources']['Bucket']['Properties'][
            'AccessControl']
        assert sut == expected_accepted