def test_list_permissions_for_storage(self, forseti_cli: ForsetiCli, forseti_model_readonly): """Test list_permissions for the storage.admin role includes the expected permissions. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_list_permissions( roles=['roles/storage.admin']) # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'storage.buckets.create', str(result.stdout)) assert re.search(r'storage.buckets.delete', str(result.stdout)) assert re.search(r'storage.buckets.get', str(result.stdout)) assert re.search(r'storage.buckets.getIamPolicy', str(result.stdout)) assert re.search(r'storage.buckets.list', str(result.stdout)) assert re.search(r'storage.buckets.setIamPolicy', str(result.stdout)) assert re.search(r'storage.buckets.update', str(result.stdout)) assert re.search(r'storage.objects.create', str(result.stdout)) assert re.search(r'storage.objects.delete', str(result.stdout)) assert re.search(r'storage.objects.get', str(result.stdout)) assert re.search(r'storage.objects.getIamPolicy', str(result.stdout)) assert re.search(r'storage.objects.list', str(result.stdout)) assert re.search(r'storage.objects.setIamPolicy', str(result.stdout)) assert re.search(r'storage.objects.update', str(result.stdout))
def test_access_by_member_with_permission(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account, organization_id): """Test access_by_member with Forseti SA has expected permissions. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email organization_id (str): Org id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_access_by_member( f'serviceaccount/{forseti_server_service_account}', ['storage.buckets.list']) # Assert Server SA has org browser role assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'"resources":[\s+]\[\\n' fr'[\s+]*"organization\/{organization_id}"\\n' fr'[\s+]*\],\\n' fr'[\s+]*"role":[\s+]"roles\/iam.securityReviewer"', str(result.stdout))
def test_why_denied(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account: str, project_id: str): """Test why_denied for why the Forseti SA doesn't have the storage.buckets.delete permission. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_why_denied( forseti_server_service_account, f'project/{project_id}', permissions=['storage.buckets.delete']) # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'roles\/cloudmigration.inframanager', str(result.stdout)) assert re.search(r'roles\/owner', str(result.stdout)) assert re.search(r'roles\/storage.admin', str(result.stdout))
def test_check_policy(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account, project_id): """Test check_policy with Forseti SA includes storage.objects.get permission. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_check_policy( f'project/{project_id}', 'storage.objects.get', f'serviceAccount/{forseti_server_service_account}') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'"result":[\s+]true', str(result.stdout))
def test_list_members_with_prefix(self, forseti_cli: ForsetiCli, forseti_client_service_account, forseti_model_readonly, forseti_server_service_account): """Test list_members includes Forseti project and service accounts. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_client_service_account (str): Client service account email forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_list_members('forseti') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'serviceaccount\/{forseti_client_service_account}', str(result.stdout)) assert re.search(fr'serviceaccount\/{forseti_server_service_account}', str(result.stdout))
def test_why_granted_role_for_org(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account: str, organization_id: str): """Test why_granted for why the Forseti SA is granted role for the org. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email organization_id (str): Org id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_why_granted( f'serviceaccount/{forseti_server_service_account}', f'organization/{organization_id}', role='roles/iam.securityReviewer') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'organization\/{organization_id}', str(result.stdout))
def test_model_delete(self, cloudsql_connection, forseti_cli: ForsetiCli, forseti_inventory_readonly, test_id: str): # Arrange inventory_id, _ = forseti_inventory_readonly model_name = f'TMD{test_id}' _, _ = forseti_cli.model_create(inventory_id, model_name) # Assert model was created query = text('SELECT ' 'COUNT(*) ' 'FROM forseti_security.model ' 'WHERE ' f"name = '{model_name}'") model_created = cloudsql_connection.execute(query).fetchone() assert model_created assert model_created[0] == 1 # Act result = forseti_cli.model_delete(model_name) # Assert assert re.search(r'SUCCESS', str(result.stdout)) # Assert model deleted from database query = text('SELECT ' 'COUNT(*) ' 'FROM forseti_security.model ' 'WHERE ' f"name = '{model_name}'") model_deleted = cloudsql_connection.execute(query).fetchone() assert model_deleted assert model_deleted[0] == 0
def test_access_by_authz_with_role(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account, project_id): """Test access_by_authz with role includes Forseti project id. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_access_by_authz( role='roles/storage.objectCreator') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'{project_id}', str(result.stdout)) assert re.search(fr'serviceaccount\/{forseti_server_service_account}', str(result.stdout))
def test_why_granted_permission_for_project( self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account: str, project_id: str): """Test why_granted for why the Forseti SA is granted permission for the project. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_why_granted( f'serviceaccount/{forseti_server_service_account}', f'project/{project_id}', permission='compute.instances.get') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'roles\/compute.networkViewer', str(result.stdout))
def test_model_use(self, forseti_cli: ForsetiCli, forseti_model_readonly): # Arrange model_name, handle, _ = forseti_model_readonly # Act forseti_cli.model_use(model_name) result = forseti_cli.config_show() # Assert assert re.search(fr'{handle}', str(result.stdout))
def test_external_project_access_scanner(self, forseti_cli: ForsetiCli, forseti_model_readonly): model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) result = forseti_cli.run_external_project_access_scanner() assert result.returncode == 0 assert re.search('Running ExternalProjectAccessScanner', str(result.stdout)) assert re.search('Scan completed!', str(result.stdout))
def test_inventory_delete(self, forseti_cli: ForsetiCli): # Arrange inventory_id, result = forseti_cli.inventory_create() # Assert inventory exists # Act forseti_cli.inventory_delete(inventory_id) # Assert assert result.returncode == 0 assert re.search(inventory_id, str(result.stdout))
def test_model_get(self, forseti_cli: ForsetiCli, forseti_model_readonly): # Arrange model_name, handle, _ = forseti_model_readonly # Act result = forseti_cli.model_get(model_name) # Assert assert handle assert re.search(fr'{handle}', str(result.stdout))
def test_inventory_list(self, forseti_cli: ForsetiCli, forseti_inventory_readonly): # Arrange inventory_id, _ = forseti_inventory_readonly # Act result = forseti_cli.inventory_list() # Assert assert result.returncode == 0 assert re.search(inventory_id, str(result.stdout))
def test_list_roles_with_iam_prefix(self, forseti_cli: ForsetiCli, forseti_model_readonly): """Test list_permissions for the storage.admin role includes the expected permissions. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_list_roles('roles/iam') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'roles\/iam.organizationRoleAdmin', str(result.stdout)) assert re.search(r'roles\/iam.organizationRoleViewer', str(result.stdout)) assert re.search(r'roles\/iam.roleAdmin', str(result.stdout)) assert re.search(r'roles\/iam.roleViewer', str(result.stdout)) assert re.search(r'roles\/iam.securityAdmin', str(result.stdout)) assert re.search(r'roles\/iam.securityReviewer', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountAdmin', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountCreator', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountDeleter', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountKeyAdmin', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountTokenCreator', str(result.stdout)) assert re.search(r'roles\/iam.serviceAccountUser', str(result.stdout)) assert re.search(r'roles\/iam.workloadIdentityUser', str(result.stdout))
def test_access_by_authz_with_permission(self, forseti_cli: ForsetiCli, forseti_model_readonly, project_id): """Test access_by_authz with permission includes Forseti project id. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_access_by_authz( permission='iam.serviceAccounts.get') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(fr'"resource":[\s+]"project\/{project_id}"', str(result.stdout)) assert re.search(fr'"role":[\s+]"roles\/editor"', str(result.stdout))
def test_access_by_resource_for_organization( self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account, organization_id): """Test access_by_resource for organization includes Forseti SA. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email organization_id (str): Organization id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_access_by_resource( f'organization/{organization_id}') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert EXPECTED_COUNT_FOR_ORG == len( re.findall(forseti_server_service_account, str(result.stdout)))
def test_list_permissions_with_role_prefix(self, forseti_cli: ForsetiCli, forseti_model_readonly): """Test list_permissions with storage role prefix includes the expected roles. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_list_permissions( role_prefixes=['roles/storage']) # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'roles\/storage.admin', str(result.stdout)) assert re.search(r'roles\/storage.hmacKeyAdmin', str(result.stdout)) assert re.search(r'roles\/storage.legacyBucketOwner', str(result.stdout)) assert re.search(r'roles\/storage.legacyBucketReader', str(result.stdout)) assert re.search(r'roles\/storage.legacyBucketWriter', str(result.stdout)) assert re.search(r'roles\/storage.legacyObjectOwner', str(result.stdout)) assert re.search(r'roles\/storage.legacyObjectReader', str(result.stdout)) assert re.search(r'roles\/storage.objectAdmin', str(result.stdout)) assert re.search(r'roles\/storage.objectCreator', str(result.stdout)) assert re.search(r'roles\/storage.objectViewer', str(result.stdout)) assert re.search(r'roles\/storagetransfer.admin', str(result.stdout)) assert re.search(r'roles\/storagetransfer.user', str(result.stdout)) assert re.search(r'roles\/storagetransfer.viewer', str(result.stdout))
def test_access_by_resource_for_project(self, forseti_cli: ForsetiCli, forseti_model_readonly, forseti_server_service_account, project_id): """Test access_by_resource for project includes Forseti SA. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result forseti_server_service_account (str): Server service account email project_id (str): Project id being scanned """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_access_by_resource( f'project/{project_id}') # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert 17 == len( re.findall(forseti_server_service_account, str(result.stdout)))
def test_list_roles(self, forseti_cli: ForsetiCli, forseti_model_readonly): """Test list_roles includes the expected roles. Args: forseti_cli (ForsetiCli): Instance of the forseti cli helper forseti_model_readonly (Tuple): Model name & process result """ # Arrange model_name, _, _ = forseti_model_readonly forseti_cli.model_use(model_name=model_name) # Act result = forseti_cli.explainer_list_roles() # Assert assert result.returncode == 0, f'Forseti stdout: {str(result.stdout)}' assert re.search(r'roles\/cloudtrace.user', str(result.stdout)) assert re.search(r'roles\/compute.admin', str(result.stdout)) assert re.search(r'roles\/storage.objectAdmin', str(result.stdout)) assert re.search(r'roles\/stackdriver.accounts.viewer', str(result.stdout)) assert re.search(r'roles\/serviceusage.serviceUsageViewer', str(result.stdout)) assert re.search(r'roles\/servicemanagement.quotaAdmin', str(result.stdout)) assert re.search(r'roles\/securitycenter.sourcesEditor', str(result.stdout)) assert re.search(r'roles\/securitycenter.findingsStateSetter', str(result.stdout)) assert re.search(r'roles\/securitycenter.findingsEditor', str(result.stdout)) assert re.search(r'roles\/pubsub.editor', str(result.stdout)) assert re.search(r'roles\/monitoring.viewer', str(result.stdout)) assert re.search(r'roles\/container.clusterViewer', str(result.stdout)) assert re.search(r'roles\/dataflow.worker', str(result.stdout)) assert re.search(r'roles\/datastore.viewer', str(result.stdout))
def test_model_create(self, cloudsql_connection, forseti_cli: ForsetiCli, forseti_model_readonly): # Arrange model_name, handle, _ = forseti_model_readonly # Act result = forseti_cli.model_get(model_name) # Assert assert handle assert re.search(fr'{handle}', str(result.stdout)) # Assert model in database query = text('SELECT ' 'state ' 'FROM forseti_security.model ' 'WHERE ' f"name = '{model_name}'") model = cloudsql_connection.execute(query).fetchone() assert model assert model[0] == 'PARTIAL_SUCCESS'
def forseti_cli(): return ForsetiCli()