def publish_error_message(trace_id, check_history_id, aws_request_id, message):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    try:
        subject = "セキュリティチェック結果メール通知失敗({0})".format(
            common_utils.get_environ(CommonConst.STAGE))
        message = "RequestID: {0}\nCheckHistoryID: {1}\nMessage: {2}".format(
            aws_request_id, check_history_id, message)
        aws_common.aws_sns(
            trace_id, subject, message,
            common_utils.get_environ(CommonConst.SENDMAIL_ERROR_NOTIFY_TOPIC))
    except PmError as e:
        pm_logger.error("通知メール送信エラーメッセージのパブリッシュに失敗しました")
Exemple #2
0
    def test_upload_json_success(self):
        # connect s3
        resource_s3 = s3_utils.resource_connect()

        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")

        # prepare data
        resource_s3.create_bucket(Bucket=check_bucket)
        more_binary_data = json.dumps(data_file,
                                      indent=4,
                                      default=FileUtils.convert_handler,
                                      ensure_ascii=False)
        with patch.object(PmLogAdapter, 'info',
                          return_value=None) as mock_method_info:
            with patch.object(boto3, 'client') as mock_method_client:
                mock_method_client.return_value = client_s3
                with patch.object(client_s3, 'put_object') as mock_method:
                    # call function test
                    FileUtils.upload_json(trace_id, "S3_CHECK_BUCKET",
                                          data_file, s3_file_name)

        # check write log info
        mock_method_info.assert_any_call(
            "Upload file json [%s] success on bucket [%s]", s3_file_name,
            check_bucket)

        # check connect client
        mock_method_client.assert_called_with('s3')

        # check param call function put_object
        mock_method.assert_any_call(Body=more_binary_data,
                                    Bucket=check_bucket,
                                    Key=s3_file_name)
    def test_s3_delete_report_success(self):
        # connect s3
        resource_s3 = s3_utils.resource_connect()
        client_s3 = s3_utils.client_connect()

        report_bucket = common_utils.get_environ("S3_REPORT_BUCKET")

        # prepare data
        resource_s3.create_bucket(Bucket=report_bucket)
        client_s3.put_object(Body=json.dumps(
            copy.deepcopy(DataTestS3.INFO_BUCKET)),
                             Bucket=report_bucket,
                             Key=prefix)
        mybucket = resource_s3.Bucket(name=report_bucket)

        with patch.object(boto3, 'resource') as mock_method_resource:
            mock_method_resource.return_value = resource_s3
            with patch.object(resource_s3, 'Bucket') as mock_method_bucket:
                mock_method_bucket.return_value = mybucket

            # call function test
            aws_common.s3_delete_report(trace_id, report_id)

        report_delete = True

        # check report delete
        for obj in mybucket.objects.filter(Prefix=prefix):
            report_delete = False

        # check result
        self.assertTrue(report_delete)

        # check connect resource
        mock_method_resource.assert_called_with('s3')
Exemple #4
0
    def test_execute_security_check_handler_success(self):
        # mock object
        patch_aws_sns = patch("premembers.common.aws_common.aws_sns")
        patch_get_uuid4 = patch("premembers.common.common_utils.get_uuid4")

        # start mock object
        mock_aws_sns = patch_aws_sns.start()
        mock_get_uuid4 = patch_get_uuid4.start()

        # mock data
        mock_aws_sns.side_effect = None
        mock_get_uuid4.return_value = check_history_id

        # addCleanup stop mock object
        self.addCleanup(patch_aws_sns.stop)
        self.addCleanup(patch_get_uuid4.stop)

        event_mock = event_create.get_event_object(
            path_parameters=path_parameters,
            trace_id=user_id_test,
            email=email)

        # Call function test
        actual_response = awschecks.execute_security_check_handler(
            event_mock, {})

        # assert call aws_sns
        topic_arn = common_utils.get_environ(
            CommonConst.SECURITYCHECK_EXECUTE_TOPIC)
        subject = "USER : {0}".format(execute_user_id)
        message = {'CheckHistoryId': check_history_id}
        mock_aws_sns.assert_called_once_with(user_id_test, subject,
                                             json.dumps(message), topic_arn)

        # Get data response
        actual_status_code = actual_response['statusCode']
        actual_response_bodys = json.loads(actual_response['body'])

        expect_response_pm_checkHistory = mock_pm_checkHistory.query_key(
            check_history_id)

        # Check data
        self.assertEqual(HTTPStatus.CREATED, actual_status_code)

        self.assertEqual(expect_response_pm_checkHistory['CheckCode'],
                         actual_response_bodys['checkCode'])
        self.assertEqual(expect_response_pm_checkHistory['CheckStatus'],
                         actual_response_bodys['checkStatus'])
        self.assertEqual('', actual_response_bodys['errorCode'])
        self.assertEqual(expect_response_pm_checkHistory['ExecutedDateTime'],
                         actual_response_bodys['executedDateTime'])
        self.assertEqual(expect_response_pm_checkHistory['ExecutedType'],
                         actual_response_bodys['executedType'])
        self.assertEqual(expect_response_pm_checkHistory['CheckHistoryID'],
                         actual_response_bodys['id'])
        self.assertEqual(expect_response_pm_checkHistory['OrganizationID'],
                         actual_response_bodys['organizationId'])
        self.assertEqual(expect_response_pm_checkHistory['ProjectID'],
                         actual_response_bodys['projectId'])
        self.assertEqual('', actual_response_bodys['reportFilePath'])
    def test_upload_csv_success(self):
        # connect s3
        resource_s3 = s3_utils.resource_connect()

        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")

        # prepare data
        resource_s3.create_bucket(Bucket=check_bucket)
        with patch.object(PmLogAdapter, 'info',
                          return_value=None) as mock_method_info:
            with patch.object(boto3, 'client') as mock_method_client:
                mock_method_client.return_value = client_s3
                with patch.object(client_s3, 'put_object') as mock_method:
                    # call function test
                    FileUtils.upload_csv(trace_id, "S3_CHECK_BUCKET",
                                         data_file, s3_file_name)

        # check write log info
        mock_method_info.assert_any_call(
            "Upload file csv [%s] success on bucket [%s]", s3_file_name,
            check_bucket)

        # check connect client
        mock_method_client.assert_called_with('s3')

        # check param call function put_object
        mock_method.assert_any_call(Body=data_file,
                                    Bucket=check_bucket,
                                    Key=s3_file_name)
    def test_check_exists_file_s3_success_case_not_exists_file_s3(self):
        # connect s3
        resource_s3 = s3_utils.resource_connect()

        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")
        s3_file_name_not_exists = "check_history_id/organization_id/project_id/awsaccount/raw/filenamenotexists.json"

        # prepare data
        resource_s3.create_bucket(Bucket=check_bucket)
        mybucket = resource_s3.Bucket(name=check_bucket)

        with patch.object(boto3, 'resource') as mock_method_resource:
            mock_method_resource.return_value = resource_s3
            with patch.object(resource_s3, 'Bucket') as mock_method_bucket:
                mock_method_bucket.return_value = mybucket

            # call function test
            actual_response = aws_common.check_exists_file_s3(
                trace_id, "S3_CHECK_BUCKET", s3_file_name_not_exists)

        # check result
        expected_response = False
        self.assertEqual(expected_response, actual_response)

        # check connect resource
        mock_method_resource.assert_called_with('s3')
    def test_check_exists_file_s3_success_case_exists_file_s3(self):
        # connect s3
        resource_s3 = s3_utils.resource_connect()
        client_s3 = s3_utils.client_connect()

        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")

        # prepare data
        resource_s3.create_bucket(Bucket=check_bucket)
        client_s3.put_object(Body=json.dumps(
            copy.deepcopy(DataTestS3.INFO_BUCKET)),
                             Bucket=check_bucket,
                             Key=s3_file_name)
        mybucket = resource_s3.Bucket(name=check_bucket)

        with patch.object(boto3, 'resource') as mock_method_resource:
            mock_method_resource.return_value = resource_s3
            with patch.object(resource_s3, 'Bucket') as mock_method_bucket:
                mock_method_bucket.return_value = mybucket

            # call function test
            actual_response = aws_common.check_exists_file_s3(
                trace_id, "S3_CHECK_BUCKET", s3_file_name)

        # check result
        expected_response = True
        self.assertEqual(expected_response, actual_response)

        # check connect resource
        mock_method_resource.assert_called_with('s3')
    def test_read_csv_success(self):
        # prepare data
        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")
        data_file = copy.deepcopy(DataTestS3.DATA_TEST_UPLOAD_CSV)
        client_s3.create_bucket(Bucket=check_bucket)
        client_s3.put_object(Body=data_file,
                             Bucket=check_bucket,
                             Key=s3_file_name)
        object_csv = client_s3.get_object(Bucket=check_bucket,
                                          Key=s3_file_name)
        object_csv_copy = copy.deepcopy(object_csv)

        with patch.object(PmLogAdapter, 'info',
                          return_value=None) as mock_method_info:
            with patch.object(boto3, 'client') as mock_method_client:
                mock_method_client.return_value = client_s3
                with patch.object(client_s3, 'get_object') as mock_method:
                    mock_method.return_value = object_csv
                    # call function test
                    actual_response = FileUtils.read_csv(
                        trace_id, 'S3_CHECK_BUCKET', s3_file_name)

        # check result
        expected_result = str(object_csv_copy['Body'].read().decode())
        self.assertEqual(expected_result, actual_response)

        # check write log info
        mock_method_info.assert_any_call('read csv success')

        # check connect client
        mock_method_client.assert_called_with('s3')

        # check param call function get_object
        mock_method.assert_any_call(Bucket=check_bucket, Key=s3_file_name)
def publish_error_message_send_checkerror_email(trace_id, check_history_id,
                                                organization_id, project_id,
                                                aws_request_id, message):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    try:
        subject = "チェックバッチエラー通知メール送信失敗({0})".format(
            common_utils.get_environ(CommonConst.STAGE))
        message = "RequestID: {0}\nCheckHistoryID: {1}\nOrganizationID: {2}\nProjectID: {3}\nMessage: {3}".format(
            aws_request_id, check_history_id, organization_id, project_id,
            message)
        aws_common.aws_sns(
            trace_id, subject, message,
            common_utils.get_environ(CommonConst.SENDMAIL_ERROR_NOTIFY_TOPIC))
    except PmError:
        pm_logger.error("通知メール送信エラーメッセージのパブリッシュに失敗しました。")
Exemple #10
0
def get_membership_aws_account(trace_id, session, aws_account):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    # デフォルト値はメンバーズに加入していないAWSアカウントです。
    members = Members.Disable

    # 対象AWSアカウントに対する接続を作成します。
    try:
        client = session.client(service_name="iam")
    except ClientError as e:
        pm_logger.error("[%s] IAMクライアント作成に失敗しました。", aws_account)
        return members

    # IAMクライアントを用いて、IAMロールcm-membersportalを取得します。
    cm_members_role_name = common_utils.get_environ(
        CommonConst.CM_MEMBERS_ROLE_NAME, CommonConst.CM_MEMBERS_PORTAL)
    try:
        get_role(trace_id, client, cm_members_role_name)
        members = Members.Enable
        pm_logger.info("[%s] IAMロール「%s」が存在します。", aws_account,
                       cm_members_role_name)
    except PmError as e:
        if e.cause_error.response['Error'][
                'Code'] == CommonConst.NO_SUCH_ENTITY:
            pm_logger.info("[%s] IAMロール「%s」が存在しません。", aws_account,
                           cm_members_role_name)
        else:
            pm_logger.warning("[%s] IAMロール「%s」の取得に失敗しました。", aws_account,
                              cm_members_role_name)
    return members
Exemple #11
0
    def test_read_object_success(self):
        data_file = copy.deepcopy(DataYaml.DATA_FILE_YAML)

        # prepare data
        check_bucket = common_utils.get_environ("S3_CHECK_BUCKET")
        client_s3.create_bucket(Bucket=check_bucket)
        client_s3.put_object(Body=data_file,
                             Bucket=check_bucket,
                             Key=s3_file_name)
        object_file = client_s3.get_object(Bucket=check_bucket,
                                           Key=s3_file_name)
        object_file_copy = copy.deepcopy(object_file)

        with patch.object(boto3, 'client') as mock_method_client:
            mock_method_client.return_value = client_s3
            with patch.object(client_s3, 'get_object') as mock_method:
                mock_method.return_value = object_file
                # call function test
                actual_response = FileUtils.read_object(
                    trace_id, 'S3_CHECK_BUCKET', s3_file_name)

        # check result
        expected_result = object_file_copy['Body'].read()
        self.assertEqual(expected_result, actual_response)

        # check connect client
        mock_method_client.assert_called_with('s3')

        # check param call function get_object
        mock_method.assert_any_call(Bucket=check_bucket, Key=s3_file_name)
    def test_execute_security_check_with_executed_type_case_error_get_pm_check_history(self):
        # patch mock
        patch_get_projects_by_organization_id = patch(
            "premembers.repository.pm_projects.get_projects_by_organization_id"
        )
        patch_create_pm_check_history = patch(
            "premembers.repository.pm_checkHistory.create")
        patch_aws_sns = patch("premembers.common.aws_common.aws_sns")
        patch_query_key_pm_check_history = patch("premembers.repository.pm_checkHistory.query_key")
        patch_get_uuid4 = patch("premembers.common.common_utils.get_uuid4")

        # start mock object
        mock_query_key_pm_check_history = patch_query_key_pm_check_history.start()
        mock_get_projects_by_organization_id = patch_get_projects_by_organization_id.start()
        mock_create_pm_check_history = patch_create_pm_check_history.start()
        mock_aws_sns = patch_aws_sns.start()
        mock_get_uuid4 = patch_get_uuid4.start()
        mock_error_exception = mock_common_utils.mock_error_exception(self)

        # mock object
        mock_query_key_pm_check_history.side_effect = PmError()
        mock_get_projects_by_organization_id.return_value = data_pm_project
        mock_create_pm_check_history.side_effect = None
        mock_aws_sns.side_effect = None
        mock_get_uuid4.return_value = check_history_id

        # addCleanup stop mock object
        self.addCleanup(patch_get_projects_by_organization_id.stop)
        self.addCleanup(patch_create_pm_check_history.stop)
        self.addCleanup(patch_aws_sns.stop)
        self.addCleanup(patch_get_uuid4.stop)

        # call function test
        actual_response = awschecks_logic.execute_security_check_with_executed_type(
            trace_id, organization_id, project_id, execute_user_id, email,
            "MANUAL")

        # assert output function
        # check call function common write log error
        mock_error_exception.assert_called_once()

        # assert call aws_sns
        topic_arn = common_utils.get_environ(
            CommonConst.SECURITYCHECK_EXECUTE_TOPIC)
        subject = "USER : {0}".format(execute_user_id)
        message = {'CheckHistoryId': check_history_id}
        mock_aws_sns.assert_called_once_with(trace_id, subject,
                                             json.dumps(message), topic_arn)

        # assert output function
        actual_response_body = json.loads(actual_response["body"])
        err_402 = MsgConst.ERR_402
        self.assertEqual(err_402["code"], actual_response_body["code"])
        self.assertEqual(err_402["message"], actual_response_body["message"])
        self.assertEqual(err_402["description"],
                         actual_response_body["description"])
        self.assertEqual(HTTPStatus.INTERNAL_SERVER_ERROR.value,
                         actual_response["statusCode"])
Exemple #13
0
def read_object(trace_id, bucket, s3_file_name):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    try:
        global global_s3_client
        if not global_s3_client:
            global_s3_client = boto3.client('s3')
        response = global_s3_client.get_object(
            Bucket=common_utils.get_environ(bucket), Key=s3_file_name)
        return response['Body'].read()
    except ClientError as e:
        raise common_utils.write_log_exception(e, pm_logger)
def execute_security_check_with_executed_type(trace_id, organization_id,
                                              project_id, user_id, email,
                                              executed_type):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())

    # リソース関連性のバリデーションチェックを行います。
    try:
        project = pm_projects.get_projects_by_organization_id(
            trace_id, project_id, organization_id)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_402,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)
    if not project:
        return common_utils.error_common(
            MsgConst.ERR_AWS_401, HTTPStatus.UNPROCESSABLE_ENTITY, pm_logger)

    try:
        check_history_id = common_utils.get_uuid4()
        executed_date_time = common_utils.get_current_date()
        pm_checkHistory.create(trace_id, check_history_id, organization_id,
                               project_id, CHECK_SECURITY, CheckStatus.Waiting,
                               None, executed_type, None, executed_date_time,
                               None, user_id)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_DB_403,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    try:
        topic_arn = common_utils.get_environ(
            CommonConst.SECURITYCHECK_EXECUTE_TOPIC)
        subject = "USER : {0}".format(user_id)
        message = {
            'CheckHistoryId': check_history_id
        }
        # Publish message
        aws_common.aws_sns(trace_id, subject, json.dumps(message), topic_arn)
    except PmError as e:
        common_utils.write_log_pm_error(e, pm_logger, exc_info=True)

    try:
        check_history = pm_checkHistory.query_key(trace_id, check_history_id,
                                                  True)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_402,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)
    # return data response
    response = common_utils.get_response_by_response_body(
        HTTPStatus.CREATED, check_history)
    return common_utils.response(response, pm_logger)
    def test_execute_security_check_with_executed_type_case_error_publish_message(self):
        # patch mock
        patch_get_projects_by_organization_id = patch(
            "premembers.repository.pm_projects.get_projects_by_organization_id"
        )
        patch_create_pm_check_history = patch(
            "premembers.repository.pm_checkHistory.create")
        patch_aws_sns = patch("premembers.common.aws_common.aws_sns")
        patch_query_key_pm_check_history = patch("premembers.repository.pm_checkHistory.query_key")
        patch_get_uuid4 = patch("premembers.common.common_utils.get_uuid4")

        # start mock object
        mock_query_key_pm_check_history = patch_query_key_pm_check_history.start()
        mock_get_projects_by_organization_id = patch_get_projects_by_organization_id.start()
        mock_create_pm_check_history = patch_create_pm_check_history.start()
        mock_aws_sns = patch_aws_sns.start()
        mock_get_uuid4 = patch_get_uuid4.start()

        # mock object
        mock_query_key_pm_check_history.return_value = data_pm_check_history
        mock_get_projects_by_organization_id.return_value = data_pm_project
        mock_create_pm_check_history.side_effect = None
        mock_aws_sns.side_effect = PmError()
        mock_get_uuid4.return_value = check_history_id

        # addCleanup stop mock object
        self.addCleanup(patch_get_projects_by_organization_id.stop)
        self.addCleanup(patch_create_pm_check_history.stop)
        self.addCleanup(patch_aws_sns.stop)
        self.addCleanup(patch_get_uuid4.stop)

        # call function test
        actual_response = awschecks_logic.execute_security_check_with_executed_type(
            trace_id, organization_id, project_id, execute_user_id, email,
            "MANUAL")

        # assert call aws_sns
        topic_arn = common_utils.get_environ(
            CommonConst.SECURITYCHECK_EXECUTE_TOPIC)
        subject = "USER : {0}".format(execute_user_id)
        message = {'CheckHistoryId': check_history_id}
        mock_aws_sns.assert_called_once_with(trace_id, subject,
                                             json.dumps(message), topic_arn)

        # Get data response
        actual_status_code = actual_response['statusCode']
        actual_response_bodys = json.loads(actual_response['body'])

        # Check data
        self.assertEqual(HTTPStatus.CREATED, actual_status_code)
        self.assertEqual(data_pm_check_history, actual_response_bodys)
Exemple #16
0
    def test_apply_change_email_handler_error_read_file_template(self):
        # mock object
        patch_get_cognito_user_pools = patch('premembers.common.aws_common.get_cognito_user_pools')
        patch_method_error = patch.object(PmLogAdapter, "error")
        patch_read_decode = patch("premembers.common.FileUtils.read_decode")
        patch_read_yaml = patch("premembers.common.FileUtils.read_yaml")
        # start mock object
        mock_get_cognito_user_pools = patch_get_cognito_user_pools.start()
        mock_method_error = patch_method_error.start()
        mock_read_yaml = patch_read_yaml.start()
        mock_read_decode = patch_read_decode.start()

        # mock data
        mock_get_cognito_user_pools.return_value = []
        mock_method_error.return_value = None
        mock_read_yaml.return_value = response_data_config
        mock_read_decode.side_effect = PmError()

        # addCleanup stop mock object
        self.addCleanup(patch_get_cognito_user_pools.stop)
        self.addCleanup(patch_method_error.stop)
        self.addCleanup(patch_read_yaml.stop)
        self.addCleanup(patch_read_decode.stop)

        # Call function test
        body = {
            "mailAddress": mail_after,
            "callerServiceName": "insightwatch",
            "mailLang": language_mail_test
        }
        event_mock = event_create.get_event_object(
            trace_id=trace_id,
            email=mail_before,
            body=json.dumps(body))
        result = user.apply_change_email_handler(event_mock, {})

        # Check data
        mock_method_error.assert_any_call(
            "メールアドレス変更通知メール本文テンプレートファイルの取得に失敗しました。:s3://%s/%s",
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            "check/notify/mail/insightwatch_apply_change_mail_template_ja.tpl")

        response_body = json.loads(result['body'])
        err_s3_702 = MsgConst.ERR_S3_702
        self.assertEqual(err_s3_702['code'], response_body['code'])
        self.assertEqual(err_s3_702['message'], response_body['message'])
        self.assertEqual(err_s3_702['description'], response_body['description'])
        self.assertEqual(result['statusCode'],
                         HTTPStatus.INTERNAL_SERVER_ERROR.value)
Exemple #17
0
def check_exists_file_s3(trace_id, bucket, prefix, is_cw_logger=False):
    if (is_cw_logger):
        logger = common_utils.begin_cw_logger(trace_id, __name__,
                                              inspect.currentframe())
    else:
        logger = common_utils.begin_logger(trace_id, __name__,
                                           inspect.currentframe())
    result = False
    try:
        s3 = boto3.resource('s3')
        mybucket = s3.Bucket(name=common_utils.get_environ(bucket))
        for object in mybucket.objects.filter(Prefix=prefix):
            result = True
            break
    except Exception as e:
        raise common_utils.write_log_exception(e, logger)
    return result
Exemple #18
0
def read_json(trace_id, bucket, s3_file_name, is_cw_logger=False):
    if (is_cw_logger):
        logger = common_utils.begin_cw_logger(trace_id, __name__,
                                              inspect.currentframe())
    else:
        logger = common_utils.begin_logger(trace_id, __name__,
                                           inspect.currentframe())
    try:
        global global_s3_client
        if not global_s3_client:
            global_s3_client = boto3.client('s3')
        response = global_s3_client.get_object(
            Bucket=common_utils.get_environ(bucket), Key=s3_file_name)
        result = json.loads(response['Body'].read())
        logger.info("read json success")
        return result
    except ClientError as e:
        raise common_utils.write_log_exception(e, logger)
def get_security_check_report_url(trace_id, user_id, history_id):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())

    # チェック履歴情報を取得します。
    try:
        check_history = pm_checkHistory.get_check_history_by_status(
            trace_id, history_id, CheckStatus.ReportCompleted)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_402,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # 該当するレコードが存在しない場合(取得件数が0件)
    if len(check_history) == 0:
        return common_utils.error_common(MsgConst.ERR_301,
                                         HTTPStatus.NOT_FOUND, pm_logger)

    # 取得したチェック履歴情報より組織IDを取得する
    organization_id = check_history[0]['OrganizationID']

    # アクセス権限チェックを行います
    response_authority = checkauthority.authority(
        trace_id, user_id, organization_id, Authority.Viewer)
    if response_authority:
        return common_utils.response(response_authority, pm_logger)

    # 有効期限が作成から1時間となる署名付きURLを作成します。
    try:
        signed_url = aws_common.generate_presigned_url(
            trace_id, common_utils.get_environ('S3_CHECK_BUCKET'),
            check_history[0]['ReportFilePath'])
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_999,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # return data response
    response_body = {"URL": signed_url}
    response = common_utils.get_response_by_response_body(
        HTTPStatus.OK, response_body)
    return common_utils.response(response, pm_logger)
    def test_read_json_success(self):
        # prepare data
        bucket_name = common_utils.get_environ("S3_CHECK_BUCKET")
        client_s3.create_bucket(Bucket=bucket_name)
        body = json.dumps(data_test_upload_s3)
        client_s3.put_object(Bucket=bucket_name, Key=s3_file_name, Body=body)

        with patch.object(PmLogAdapter, 'info',
                          return_value=None) as mock_method_info:
            with patch.object(boto3, "client", return_value=client_s3):
                # call function test
                actual_result = FileUtils.read_json(trace_id,
                                                    "S3_CHECK_BUCKET",
                                                    s3_file_name)

        # check result
        self.assertEqual(data_test_upload_s3, actual_result)

        # check write log info
        mock_method_info.assert_any_call('read json success')
Exemple #21
0
def upload_csv(trace_id, bucket, data, s3_file_name, is_cw_logger=False):
    if (is_cw_logger):
        logger = common_utils.begin_cw_logger(trace_id, __name__,
                                              inspect.currentframe())
    else:
        logger = common_utils.begin_logger(trace_id, __name__,
                                           inspect.currentframe())
    bucket_name = common_utils.get_environ(bucket)
    try:
        global global_s3_client
        if not global_s3_client:
            global_s3_client = boto3.client('s3')
        # Upload the file to S3
        global_s3_client.put_object(Body=data,
                                    Bucket=bucket_name,
                                    Key=s3_file_name)
        logger.info("Upload file csv [%s] success on bucket [%s]",
                    s3_file_name, bucket_name)
    except ClientError as e:
        raise common_utils.write_log_exception(e, logger)
Exemple #22
0
    def test_execute_change_email_case_read_yaml_error(self):
        # patch mock
        patch_read_yaml = patch('premembers.common.FileUtils.read_yaml')
        mock_error_exception = mock_common_utils.mock_error_exception(self)

        # start mock object
        mock_read_yaml = patch_read_yaml.start()

        # mock data
        mock_read_yaml.side_effect = PmError()

        # addCleanup stop mock object
        self.addCleanup(patch_read_yaml.stop)

        with patch.object(PmLogAdapter, 'error',
                          return_value=None) as mock_method_error:
            # call function test
            result = user_logic.execute_change_email(apply_id)

        # Check data
        status_code = result['statusCode']
        response_body = result['body']
        response_headers = result['headers']

        self.assertEqual(HTTPStatus.OK.value, status_code)
        self.assertEqual(response_error_page_caller_service_insightwatch,
                         response_body)
        self.assertEqual(content_type_text_html,
                         response_headers['content-type'])

        # check param call function read_yaml
        mock_read_yaml.assert_called_once_with(apply_id, s3_setting_bucket,
                                               notify_config_cis_result_mail)

        mock_error_exception.assert_called_once()

        # check write log error
        mock_method_error.assert_called_once_with(
            "メールアドレス変更通知メール送信設定ファイルの取得に失敗しました。:s3://%s/%s",
            common_utils.get_environ(s3_setting_bucket),
            notify_config_cis_result_mail)
Exemple #23
0
    def test_publish_error_message_send_checkerror_email_case_success(self):
        # mock object
        patch_aws_sns = patch("premembers.common.aws_common.aws_sns")

        # start mock object
        mock_aws_sns = patch_aws_sns.start()

        # mock data
        mock_aws_sns.side_effect = None

        # addCleanup stop mock object
        self.addCleanup(patch_aws_sns.stop)

        # call function test
        awschecksBatch_logic.publish_error_message_send_checkerror_email(
            trace_id, check_history_id, organization_id, project_id,
            context_aws.aws_request_id, message)

        # check param call function aws_sns
        mock_aws_sns.assert_any_call(
            trace_id, subject, body_mail,
            common_utils.get_environ(CommonConst.SENDMAIL_ERROR_NOTIFY_TOPIC))
Exemple #24
0
def get_all_projects(trace_id):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    exclusiveStartKey = None
    projects = []
    limit = int(common_utils.get_environ("NUM_OF_PROJECT_ITEMS_PER_1TIME"))
    segment = 0
    while True:
        try:
            result = DB_utils.scan(trace_id, Tables.PM_PROJECTS, limit,
                                   exclusiveStartKey)
            projects.extend(result['Items'])
            if (common_utils.check_key('LastEvaluatedKey', result)):
                exclusiveStartKey = result['LastEvaluatedKey']
            else:
                break
            segment += 1
            time.sleep(1)
        except PmError as e:
            pm_logger.warning("プロジェクト情報取得に失敗しました。: 取得回数=%s、一度に取得する件数=%s",
                              segment, limit)
            break
    return common_utils.response(projects, pm_logger), segment
Exemple #25
0
def upload_json(trace_id, bucket, data, s3_file_name, is_cw_logger=False):
    if (is_cw_logger):
        logger = common_utils.begin_cw_logger(trace_id, __name__,
                                              inspect.currentframe())
    else:
        logger = common_utils.begin_logger(trace_id, __name__,
                                           inspect.currentframe())
    bucket_name = common_utils.get_environ(bucket)
    try:
        global global_s3_client
        if not global_s3_client:
            global_s3_client = boto3.client('s3')
        more_binary_data = json.dumps(data,
                                      indent=4,
                                      default=convert_handler,
                                      ensure_ascii=False)
        # Upload the file to S3
        global_s3_client.put_object(Body=more_binary_data,
                                    Bucket=bucket_name,
                                    Key=s3_file_name)
        logger.info("Upload file json [%s] success on bucket [%s]",
                    s3_file_name, bucket_name)
    except ClientError as e:
        raise common_utils.write_log_exception(e, logger)
Exemple #26
0
def execute_change_email(apply_id):
    pm_logger = common_utils.begin_logger(apply_id, __name__,
                                          inspect.currentframe())

    # バリデーションチェックを行います
    if common_utils.is_null(apply_id):
        return common_utils.error_common(MsgConst.ERR_201,
                                         HTTPStatus.UNPROCESSABLE_ENTITY,
                                         pm_logger)

    # set default value
    caller_service_name = 'insightwatch'

    # S3から通知メール送信設定ファイルを取得します。
    try:
        config = FileUtils.read_yaml(apply_id, CommonConst.S3_SETTING_BUCKET,
                                     CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
    except PmError as e:
        pm_logger.error(
            "メールアドレス変更通知メール送信設定ファイルの取得に失敗しました。:s3://%s/%s",
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
        common_utils.error_exception(MsgConst.ERR_S3_702,
                                     HTTPStatus.INTERNAL_SERVER_ERROR, e,
                                     pm_logger, True)
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            CommonConst.DEFAULT_RESPONSE_ERROR_PAGE[caller_service_name],
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    # set data response error page default
    response_error_page = config[CommonConst.KEY_RESPONSE_ERROR_PAGE.format(
        serviceName=caller_service_name)]

    # メールアドレス変更申請テーブルから申請レコードを取得します。
    try:
        email_change_apply_info = pm_emailChangeApply.query_key(
            apply_id, apply_id, None)
    except PmError:
        pm_logger.error("メールアドレス変更申請テーブルでレコード取得に失敗しました。変更申請ID: %s", apply_id)
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    if not email_change_apply_info:
        pm_logger.warning("メールアドレス変更申請テーブルでレコードが存在しませんでした。変更申請ID: %s",
                          apply_id)
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    user_name = email_change_apply_info['UserID']
    if common_utils.check_key('CallerServiceName', email_change_apply_info):
        caller_service_name = email_change_apply_info['CallerServiceName']

    # data response page
    response_error_page = config[CommonConst.KEY_RESPONSE_ERROR_PAGE.format(
        serviceName=caller_service_name)]
    response_execute_change_email = config[
        CommonConst.KEY_RESPONSE_EXECUTE_CHANGE_EMAIL.format(
            serviceName=caller_service_name)]

    # メールアドレス変更申請テーブルから取得した UserID でCognito に合致する該当するユーザー情報を取得します。
    try:
        user_info = aws_common.get_cognito_user_info_by_user_name(
            apply_id, user_name)
    except PmError:
        pm_logger.error("Cognitoから情報取得に失敗しました。")
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    if not user_info:
        pm_logger.warning("Cognitoにユーザーが存在しませんでした。ユーザーID: %s", user_name)
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    before_mail_address = email_change_apply_info['BeforeMailAddress']
    after_mail_address = email_change_apply_info['AfterMailAddress']

    # get cognito email
    cognito_email = jmespath.search("[?Name=='email'].Value | [0]",
                                    user_info['UserAttributes'])

    if before_mail_address != cognito_email:
        pm_logger.warning("変更前メールアドレスがCognitoのメールアドレスと合致しませんでした。")
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    # Cognitoのメールアドレスを変更する
    try:
        user_attributes = [{
            'Name': 'email',
            'Value': after_mail_address
        }, {
            'Name': 'email_verified',
            'Value': 'true'
        }]
        aws_common.update_cognito_user_attributes(apply_id, user_name,
                                                  user_attributes)
    except PmError:
        pm_logger.error("Cognitoの項目変更に失敗しました。")
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    # get list affiliations
    try:
        affiliations = pm_affiliation.query_userid_key(apply_id, user_name)
    except PmError:
        pm_logger.error("ユーザー所属テーブルでレコード取得に失敗しました。")
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    for affiliation in affiliations:
        try:
            org_notify_mail_destinations = pm_orgNotifyMailDestinations.query_key(
                apply_id, affiliation['OrganizationID'],
                CommonConst.NOTIFY_CODE, None)
        except PmError:
            pm_logger.error("組織別通知メール宛先テーブルでレコード取得に失敗しました。")
            return common_utils.get_response_by_response_body(
                HTTPStatus.OK,
                response_error_page,
                is_response_json=False,
                content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

        if org_notify_mail_destinations:
            destinations_update = []
            for destination in org_notify_mail_destinations['Destinations']:
                if destination['MailAddress'] == before_mail_address:
                    destination['MailAddress'] = after_mail_address
                    destinations_update.append(destination)

            # update pm_orgNotifyMailDestinations
            try:
                attribute = {'Destinations': {"Value": destinations_update}}
                pm_orgNotifyMailDestinations.update(
                    apply_id, org_notify_mail_destinations['OrganizationID'],
                    org_notify_mail_destinations['NotifyCode'], attribute)
            except PmError:
                pm_logger.error("組織別通知メール宛先テーブルでレコード更新に失敗しました。")
                return common_utils.get_response_by_response_body(
                    HTTPStatus.OK,
                    response_error_page,
                    is_response_json=False,
                    content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

        # update pm_affiliation
        try:
            attribute = {'MailAddress': {"Value": after_mail_address}}
            pm_affiliation.update_affiliation(apply_id, affiliation['UserID'],
                                              affiliation['OrganizationID'],
                                              attribute,
                                              affiliation['UpdatedAt'])
        except PmError:
            pm_logger.error("ユーザー所属テーブルでレコード更新に失敗しました。")
            return common_utils.get_response_by_response_body(
                HTTPStatus.OK,
                response_error_page,
                is_response_json=False,
                content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    # メールアドレス変更申請テーブルで変更申請ID{applyid}をキーにして申請レコードを削除する。
    try:
        pm_emailChangeApply.delete(apply_id, apply_id)
    except PmError:
        pm_logger.error("メールアドレス変更申請テーブルでレコード削除に失敗しました。変更申請ID: %s", apply_id)
        return common_utils.get_response_by_response_body(
            HTTPStatus.OK,
            response_error_page,
            is_response_json=False,
            content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)

    # data response
    response = common_utils.get_response_by_response_body(
        HTTPStatus.OK,
        response_execute_change_email,
        is_response_json=False,
        content_type=CommonConst.CONTENT_TYPE_TEXT_HTML)
    return common_utils.response(response, pm_logger)
Exemple #27
0
def apply_change_email(user_id, mail_before_change, data_body):
    pm_logger = common_utils.begin_logger(user_id, __name__,
                                          inspect.currentframe())
    # Parse JSON
    try:
        body_object = json.loads(data_body)
    except Exception as e:
        return common_utils.error_exception(MsgConst.ERR_REQUEST_202,
                                            HTTPStatus.BAD_REQUEST, e,
                                            pm_logger, True)

    mail_after_change = common_utils.get_value("mailAddress", body_object,
                                               None)
    caller_service_name = common_utils.get_value("callerServiceName",
                                                 body_object, None)

    mail_lang = common_utils.get_value("mailLang", body_object, None)

    # validate
    list_errors = validate_param_apply_change_email(user_id, mail_lang,
                                                    caller_service_name,
                                                    mail_before_change)
    if list_errors:
        return common_utils.error_validate(MsgConst.ERR_REQUEST_201,
                                           HTTPStatus.UNPROCESSABLE_ENTITY,
                                           list_errors, pm_logger)

    # Cognito UserPoolsから変更するメールアドレス{mailaddress}に該当するユーザー情報情報を取得します。
    try:
        list_users = aws_common.get_cognito_user_pools(user_id,
                                                       mail_after_change,
                                                       "email")
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_COGNITO_501,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)
    if list_users:
        return common_utils.error_common(MsgConst.ERR_302, HTTPStatus.CONFLICT,
                                         pm_logger)

    # メールアドレス変更申請テーブルから申請レコードを取得します。
    try:
        list_email_change_apply = pm_emailChangeApply.query_user_index(user_id)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_402,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)
    if list_email_change_apply:
        return common_utils.error_common(MsgConst.ERR_302, HTTPStatus.CONFLICT,
                                         pm_logger)

    # メールアドレス変更申請テーブルに申請レコードを作成します。
    apply_id = common_utils.get_uuid4()
    time_to_live = common_utils.get_time_to_live(
        CommonConst.EMAIL_CHANGE_APPLY_EXPIRATION_DATE)
    try:
        pm_emailChangeApply.create(user_id, apply_id, mail_before_change,
                                   mail_after_change, time_to_live,
                                   caller_service_name)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_DB_403,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # get record PM_EmailChangeApply
    try:
        result = pm_emailChangeApply.query_key(user_id,
                                               apply_id,
                                               convert_response=True)
    except PmError as e:
        return common_utils.error_exception(MsgConst.ERR_402,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # S3から通知メール送信設定ファイルを取得します。
    try:
        config = FileUtils.read_yaml(user_id, CommonConst.S3_SETTING_BUCKET,
                                     CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
    except PmError as e:
        pm_logger.error(
            "メールアドレス変更通知メール送信設定ファイルの取得に失敗しました。:s3://%s/%s",
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
        return common_utils.error_exception(MsgConst.ERR_S3_702,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    path_file_template = config[
        CommonConst.KEY_GET_PATH_FILE_TEMPLATE_MAIL_SERVICE.format(
            language=mail_lang, serviceName=caller_service_name)]
    # 通知メール本文を作成
    try:
        template_body_mail = FileUtils.read_decode(
            user_id, CommonConst.S3_SETTING_BUCKET, path_file_template)
    except PmError as e:
        pm_logger.error(
            "メールアドレス変更通知メール本文テンプレートファイルの取得に失敗しました。:s3://%s/%s",
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            path_file_template)
        return common_utils.error_exception(MsgConst.ERR_S3_702,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # SESで通知メールを送信します。
    bcc_addresses = [mail_after_change]
    template_body_mail = Template(template_body_mail)
    body_mail = template_body_mail.render(ApplyID=apply_id)
    mail_subject = config[CommonConst.KEY_MAIL_SUBJECT_SERVICE.format(
        language=mail_lang, serviceName=caller_service_name)]
    mail_form = config[CommonConst.KEY_MAIL_FROM_SERVICE.format(
        serviceName=caller_service_name)]

    try:
        aws_common.send_email(user_id, config['ses.region'], mail_form,
                              bcc_addresses, mail_subject, body_mail)
    except PmError as e:
        pm_logger.error("通知メール送信に失敗しました。")
        return common_utils.error_exception(MsgConst.ERR_SES_801,
                                            HTTPStatus.INTERNAL_SERVER_ERROR,
                                            e, pm_logger, True)

    # return data response
    response = common_utils.get_response_by_response_body(
        HTTPStatus.CREATED, result)
    return common_utils.response(response, pm_logger)
def execute_send_result_slack(trace_id, check_history_id, language):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())

    # チェック結果テーブルのCheckHistoryIndexから、チェック履歴ID{CheckHistoryId}をキーとしてチェック結果一覧を取得します。
    try:
        list_check_result = pm_checkResults.query_history_index(
            trace_id, check_history_id)
    except PmError as e:
        msg_err = "チェック結果の取得に失敗しました。"
        pm_logger.error(msg_err)
        common_utils.write_log_pm_error(e, pm_logger, msg_err)
        return

    if (not list_check_result):
        msg_err = "チェック結果の取得に失敗しました。"
        pm_logger.error(msg_err)
        return

    # チェック結果一覧のうちの一つから、組織IDを取得します。
    organization_id = list_check_result[0]['OrganizationID']
    organization_name = list_check_result[0]['OrganizationName']
    project_name = list_check_result[0]['ProjectName']

    # 組織別Slack通知設定テーブルから、組織ID、通知コードCHECK_CISをキーとして設定情報を取得します。
    try:
        org_notify_slack = pm_orgNotifySlack.query_key(trace_id,
                                                       organization_id,
                                                       CommonConst.NOTIFY_CODE)
    except PmError as e:
        msg_err = "Slack設定情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.error(msg_err)
        common_utils.write_log_pm_error(e, pm_logger, msg_err)
        return

    if (not org_notify_slack):
        msg_err = "Slack設定情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.error(msg_err)
        return

    # S3から通知Slack設定ファイルを取得します。
    try:
        config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET,
                                     CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
    except PmError as e:
        msg_err = "通知Slack設定ファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
        pm_logger.error(msg_err)
        common_utils.write_log_pm_error(e, pm_logger, msg_err)
        return

    if language not in CommonConst.LANGUAGE_SUPPORT:
        language = CommonConst.LANGUAGE_DEFAULT

    path_file_template = config[
        CommonConst.KEY_GET_PATH_FILE_TEMPLATE_SLACK.format(language=language)]

    # メッセージ本文を作成します。
    try:
        template_message = FileUtils.read_decode(trace_id,
                                                 CommonConst.S3_SETTING_BUCKET,
                                                 path_file_template)
    except PmError as e:
        msg_err = "Slack通知本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            path_file_template)
        pm_logger.error(msg_err)
        common_utils.write_log_pm_error(e, pm_logger, msg_err)
        return

    executed_date_time = date_utils.toString(
        date_utils.toDate(list_check_result[0]['ExecutedDateTime'],
                          date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM,
        date_utils.get_time_zone_by_language(language))

    check_results = []
    for check_result in list_check_result:
        account_aws = CommonConst.AWS_ACCOUNT_MAIL.format(
            check_result['AWSAccount'][:4], check_result['AWSAccount'][4:8])
        check_result = {
            "accountAWS": account_aws,
            "okCount": check_result['OKCount'],
            "ngCount": check_result['NGCount'],
            "criticalCount": check_result['CriticalCount'],
            "managedCount": check_result['ManagedCount'],
            "errorCount": check_result['ErrorCount']
        }
        check_results.append(check_result)

    template = Template(template_message)
    context = {
        'organizationName': organization_name,
        'projectName': project_name,
        'executedDateTime': executed_date_time,
        'checkResults': check_results
    }
    body = template.render(context)
    mentions = slack_common.convert_command_slack(org_notify_slack['Mentions'])
    body = CommonConst.KEY_BODY_MESSAGE_SLACK.format(mentions=mentions,
                                                     body=body)

    notify_slack = {
        "username":
        config[CommonConst.KEY_USER_NAME_SLACK.format(language=language)],
        "icon_url":
        config['slack.iconurl'],
        "text":
        body
    }
    notify_slack = json.dumps(notify_slack)
    try:
        slack_common.send_message_slack(trace_id,
                                        org_notify_slack['WebhookURL'],
                                        notify_slack)
    except PmError as e:
        msg_err = "Slack通知のリクエスト送信に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.warning(msg_err)
        common_utils.write_log_pm_error(e, pm_logger, msg_err)
def send_result_email(trace_id, check_history_id, language):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())
    # チェック結果テーブルのCheckHistoryIndexから、チェック履歴ID{CheckHistoryId}をキーとしてチェック結果一覧を取得します。
    try:
        list_check_result = pm_checkResults.query_history_index(
            trace_id, check_history_id)
    except PmError as e:
        msg_err = "チェック結果の取得に失敗しました。"
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    if (not list_check_result):
        msg_err = "チェック結果の取得に失敗しました。"
        pm_logger.error(msg_err)
        raise PmError(message=msg_err)

    # チェック結果一覧のうちの一つから、組織IDを取得します。
    organization_id = list_check_result[0]['OrganizationID']
    organization_name = list_check_result[0]['OrganizationName']
    project_name = list_check_result[0]['ProjectName']

    # 宛先ユーザーの確認をします。ユーザー所属テーブルのOrganizationIndexから、組織IDをキー
    try:
        users = pm_affiliation.query_users_organization_index(
            trace_id, organization_id, InvitationStatus.Belong)
    except PmError as e:
        msg_err = "ユーザー所属情報の取得に失敗しました。:OrganizationID={0}".format(
            organization_id)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # 組織別通知メール宛先テーブルから、組織ID、通知コードCHECK_CISをキーとして宛先情報を取得します。
    try:
        org_notify_mail_destinations = pm_orgNotifyMailDestinations.query_key(
            trace_id, organization_id, CommonConst.NOTIFY_CODE)
    except PmError as e:
        msg_err = "宛先情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    if (not org_notify_mail_destinations):
        msg_err = "宛先情報の取得に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.error(msg_err)
        raise PmError(message=msg_err)

    destinations = []
    for destination in org_notify_mail_destinations['Destinations']:
        for user in users:
            if destination['UserID'] == user['UserID']:
                destinations.append(destination)
                break
    try:
        if (len(destinations) == 0):
            pm_orgNotifyMailDestinations.delete(trace_id, organization_id,
                                                CommonConst.NOTIFY_CODE)
        else:
            attribute = {'Destinations': {"Value": destinations}}
            pm_orgNotifyMailDestinations.update(trace_id, organization_id,
                                                CommonConst.NOTIFY_CODE,
                                                attribute)
    except PmError as e:
        msg_err = "通知メール宛先ユーザーの更新に失敗しました。:OrganizationID={0}, CheckCode={1}".format(
            organization_id, CommonConst.NOTIFY_CODE)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # S3から通知メール送信設定ファイルを取得します。
    try:
        config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET,
                                     CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
    except PmError as e:
        msg_err = "通知メール送信設定ファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    language_mail = CommonConst.LANGUAGE_DEFAULT
    if language in CommonConst.LANGUAGE_SUPPORT:
        language_mail = language

    path_file_template = config[CommonConst.KEY_GET_PATH_FILE_TEMPLATE_MAIL.
                                format(language=language_mail)]
    mail_subject_config = config[CommonConst.KEY_MAIL_SUBJECT.format(
        language=language_mail)]

    # 通知メール本文を作成
    try:
        template_body = FileUtils.read_decode(trace_id,
                                              CommonConst.S3_SETTING_BUCKET,
                                              path_file_template)
    except PmError as e:
        msg_err = "知メール本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            path_file_template)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # 通知メール件名を作成
    subject_template = Template(mail_subject_config)
    mail_subject = subject_template.render(project_name=project_name)

    # メール本文
    executed_date_time = date_utils.toString(
        date_utils.toDate(list_check_result[0]['ExecutedDateTime'],
                          date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM,
        date_utils.ASIA_TOKYO)

    executed_date_time_utc = date_utils.toString(
        date_utils.toDate(list_check_result[0]['ExecutedDateTime'],
                          date_utils.UTC), date_utils.PATTERN_YYYYMMDDHHMM,
        date_utils.UTC)

    check_results = []
    for check_result in list_check_result:
        account_aws = CommonConst.AWS_ACCOUNT_MAIL.format(
            check_result['AWSAccount'][:4], check_result['AWSAccount'][4:8])
        check_result = {
            "accountAWS": account_aws,
            "okCount": check_result['OKCount'],
            "ngCount": check_result['NGCount'],
            "criticalCount": check_result['CriticalCount'],
            "managedCount": check_result['ManagedCount'],
            "errorCount": check_result['ErrorCount']
        }
        check_results.append(check_result)

    template = Template(template_body)
    context = {
        'organizationName': organization_name,
        'projectName': project_name,
        'executedDateTime': executed_date_time,
        'executedDateTimeUTC': executed_date_time_utc,
        'checkResults': check_results
    }
    body = template.render(context)

    # SESで通知メールを送信します。
    list_bcc_addresses = []
    bcc_addresses = []
    for index, destination in enumerate(destinations):
        bcc_addresses.append(destination['MailAddress'])
        if (len(bcc_addresses) >= 50 or len(destinations) == index + 1):
            list_bcc_addresses.append(bcc_addresses)
            bcc_addresses = []

    for index, bcc_addresses in enumerate(list_bcc_addresses):
        try:
            aws_common.send_email(trace_id, config['ses.region'],
                                  config['mail.from'], bcc_addresses,
                                  mail_subject, body)
        except PmError as e:
            msg_err = "通知メール送信に失敗しました。({0}/{1})".format(
                index + 1, len(list_bcc_addresses))
            pm_logger.error(msg_err)
            raise common_utils.write_log_pm_error(e, pm_logger, msg_err)
def send_checkerror_email(trace_id, aws_account, check_history_id,
                          organization_id, project_id, error_code,
                          execute_user_id, region_name, check_code_item,
                          data_body):
    pm_logger = common_utils.begin_logger(trace_id, __name__,
                                          inspect.currentframe())

    # 組織情報を取得する。
    try:
        organization = pm_organizations.get_organization(
            trace_id, organization_id)
    except PmError as e:
        msg_err = "組織情報の取得に失敗しました。OrganizationID={0}".format(organization_id)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # プロジェクト情報を取得する。
    try:
        project = pm_projects.query_key(trace_id, project_id)
    except PmError as e:
        msg_err = "プロジェクト情報の取得に失敗しました。ProjectID={0}".format(project_id)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # チェック実行ユーザーのメールアドレスと言語を取得します。
    try:
        user_info = aws_common.get_cognito_user_info_by_user_name(
            trace_id, execute_user_id)
    except PmError as e:
        msg_err = "Cognitoから情報取得に失敗しました。"
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    language = jmespath.search("[?Name=='locale'].Value | [0]",
                               user_info['UserAttributes'])
    mail_execute_user = jmespath.search("[?Name=='email'].Value | [0]",
                                        user_info['UserAttributes'])

    # S3から通知メール送信設定ファイルを取得します。
    try:
        config = FileUtils.read_yaml(trace_id, CommonConst.S3_SETTING_BUCKET,
                                     CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
    except PmError as e:
        msg_err = "通知メール送信設定ファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            CommonConst.NOTIFY_CONFIG_CIS_RESULT_MAIL)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    language_mail = CommonConst.LANGUAGE_ENGLISH
    if language in CommonConst.LANGUAGE_SUPPORT:
        language_mail = language

    path_file_template_check_error_notice_mail = config[
        CommonConst.KEY_GET_PATH_FILE_TEMPLATE_CHECK_ERROR_NOTICE_MAIL.format(
            language=language_mail)]
    path_file_message_notice_error_execute_check_security = config[
        CommonConst.KEY_GET_PATH_MESSAGE_NOTICE_ERROR_EXECUTE_CHECK_SECURITY.
        format(language=language_mail)]
    mail_subject_config = config[
        CommonConst.KEY_CHECK_ERROR_NOTICE_MAIL_SUBJECT.format(
            language=language_mail)]

    # エラー通知内容設定ファイルを取得します。
    try:
        messages_notice_error_execute_check_security = FileUtils.read_yaml(
            trace_id, CommonConst.S3_SETTING_BUCKET,
            path_file_message_notice_error_execute_check_security)
    except PmError as e:
        msg_err = "エラー通知内容設定ファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            path_file_message_notice_error_execute_check_security)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # S3から通知メール本文テンプレートファイルを取得します。
    try:
        template_body = FileUtils.read_decode(
            trace_id, CommonConst.S3_SETTING_BUCKET,
            path_file_template_check_error_notice_mail)
    except PmError as e:
        msg_err = "通知メール本文テンプレートファイルの取得に失敗しました。:s3://{0}/{1}".format(
            common_utils.get_environ(CommonConst.S3_SETTING_BUCKET),
            path_file_template_check_error_notice_mail)
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)

    # に該当する通知内容を取得します。
    content_message = messages_notice_error_execute_check_security[
        CommonConst.KEY_GET_MESSAGE_NOTICE_ERROR_EXECUTE_CHECK_SECURITY.format(
            errorCode=error_code)]
    if data_body is not None:
        content_message = content_message.format_map(data_body)

    # 通知メール件名を作成
    subject_template = Template(mail_subject_config)
    project_name = project['ProjectName']
    mail_subject = subject_template.render(project_name=project_name)
    if check_code_item is not None:
        check_code_item = CommonConst.LIST_CHECK_ITEM_CODE_CONVERT[
            check_code_item]

    template = Template(template_body)
    context = {
        'organizationName': organization['OrganizationName'],
        'projectName': project_name,
        'checkCodeItem': check_code_item,
        'awsAccount': aws_account,
        'regionName': region_name,
        'contentMessage': content_message
    }
    body = template.render(context)

    # SESで通知メールを送信します
    bcc_addresses = [mail_execute_user]

    try:
        aws_common.send_email(trace_id, config['ses.region'],
                              config['mail.from'], bcc_addresses, mail_subject,
                              body)
    except PmError as e:
        msg_err = "通知メール送信に失敗しました。"
        pm_logger.error(msg_err)
        raise common_utils.write_log_pm_error(e, pm_logger, msg_err)