From 7f6f4659dc80f07038845f7d129ba949a2365911 Mon Sep 17 00:00:00 2001 From: "shimoda.m@nds-tyo.co.jp" Date: Thu, 7 Jul 2022 13:28:49 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=A1=E3=83=BC=E3=83=AB=E6=9C=AC?= =?UTF-8?q?=E6=96=87=E7=94=9F=E6=88=90=E5=87=A6=E7=90=86=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../check-view-option/aws/__init__.py | 0 .../check-view-option/aws/s3.py | 41 +++++++++++-- .../check-view-option/aws/ssm.py | 3 + .../check-view-option/constants.py | 3 +- .../check-view-option/dto/__init__.py | 0 .../dto/view_secutiry_option.py | 7 +++ .../check-view-option/main.py | 60 ++++++++++++++++--- ...heck_view_secutiry_option_mail_body.config | 6 ++ ...eck_view_secutiry_option_mail_title.config | 1 + 9 files changed, 109 insertions(+), 12 deletions(-) create mode 100644 lambda/check-view-secutiry-option/check-view-option/aws/__init__.py create mode 100644 lambda/check-view-secutiry-option/check-view-option/dto/__init__.py create mode 100644 lambda/check-view-secutiry-option/check-view-option/dto/view_secutiry_option.py create mode 100644 s3/config/view_check/check_view_secutiry_option_mail_body.config create mode 100644 s3/config/view_check/check_view_secutiry_option_mail_title.config diff --git a/lambda/check-view-secutiry-option/check-view-option/aws/__init__.py b/lambda/check-view-secutiry-option/check-view-option/aws/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lambda/check-view-secutiry-option/check-view-option/aws/s3.py b/lambda/check-view-secutiry-option/check-view-option/aws/s3.py index 8d512b71..d18b74e5 100644 --- a/lambda/check-view-secutiry-option/check-view-option/aws/s3.py +++ b/lambda/check-view-secutiry-option/check-view-option/aws/s3.py @@ -1,6 +1,6 @@ import boto3 import environments -from constants import AWS_RESOURCE_S3, S3_RESPONSE_BODY +from constants import AWS_RESOURCE_S3, S3_RESPONSE_BODY, UTF8 class S3Resource: @@ -12,14 +12,47 @@ class S3Resource: def get_object(self, object_key: str): s3_object = self.__s3_bucket.Object(object_key) response = s3_object.get() - return response[S3_RESPONSE_BODY].read() + return response[S3_RESPONSE_BODY].read().decode(UTF8) class ConfigBucket: __s3_resource: S3Resource = None + __bucket_name: str + __check_target_schema_names_file_path: str + __notice_mail_title_template_file_path: str + __notice_mail_body_template_file_path: str def __init__(self) -> None: - self.__s3_resource = S3Resource(environments.CONFIG_BUCKET_NAME) + self.__bucket_name = environments.CONFIG_BUCKET_NAME + self.__check_target_schema_names_file_path = environments.CHECK_TARGET_SCHEMA_NAMES_PATH + self.__notice_mail_title_template_file_path = environments.NOTICE_MAIL_TITLE_TEMPLATE_PATH + self.__notice_mail_body_template_file_path = environments.NOTICE_MAIL_BODY_TEMPLATE_PATH + self.__s3_resource = S3Resource(self.__bucket_name) + @property + def bucket_name(self): + return self.__bucket_name + + @property + def check_target_schema_names_file_path(self): + return self.__check_target_schema_names_file_path + + @property + def mail_body_file_path(self): + return self.__notice_mail_body_template_file_path + + @property + def mail_title_file_path(self): + return self.__notice_mail_title_template_file_path + + @property def check_target_schema_names(self): - return self.__s3_resource.get_object(environments.CHECK_TARGET_SCHEMA_NAMES_PATH) + return self.__s3_resource.get_object(self.__check_target_schema_names_file_path) + + @property + def notice_mail_title_template(self): + return self.__s3_resource.get_object(self.__notice_mail_title_template_file_path) + + @property + def notice_mail_body_template(self): + return self.__s3_resource.get_object(self.__notice_mail_body_template_file_path) diff --git a/lambda/check-view-secutiry-option/check-view-option/aws/ssm.py b/lambda/check-view-secutiry-option/check-view-option/aws/ssm.py index 528b4516..7b618b59 100644 --- a/lambda/check-view-secutiry-option/check-view-option/aws/ssm.py +++ b/lambda/check-view-secutiry-option/check-view-option/aws/ssm.py @@ -21,11 +21,14 @@ class SSMParameterStore: def __init__(self) -> None: self.__ssm_client = SSMClient() + @property def db_host(self): return self.__ssm_client.get_ssm_params(environments.PARAM_NAME_DB_HOST, True) + @property def db_user_name(self): return self.__ssm_client.get_ssm_params(environments.PARAM_NAME_DB_USER_NAME, True) + @property def db_user_password(self): return self.__ssm_client.get_ssm_params(environments.PARAM_NAME_DB_USER_PASSWORD, True) diff --git a/lambda/check-view-secutiry-option/check-view-option/constants.py b/lambda/check-view-secutiry-option/check-view-option/constants.py index a0f93a3a..9f6b0735 100644 --- a/lambda/check-view-secutiry-option/check-view-option/constants.py +++ b/lambda/check-view-secutiry-option/check-view-option/constants.py @@ -29,7 +29,6 @@ RESPONSE_CODE_NO_SUCH_KEY = 'NoSuchKey' RESPONSE_CODE_PARAMETER_NOT_FOUND = 'ParameterNotFound' # sql - DEFAULT_SCHEMA = 'INFORMATION_SCHEMA' INFORMATION_SCHEMA_SECURITY_TYPE_INVOKER = 'INVOKER' CONNECTION_TIMEOUT = 5 @@ -38,3 +37,5 @@ CONNECTION_TIMEOUT = 5 UTF8 = 'utf-8' LAUNCH_ON_LOCAL = 'local' CHECK_TARGET_SCHEMAS = 'check_target_schemas' +# メール本文に出力する不足ファイル名一覧のインデント +MAIL_INDENT = '\n  ' diff --git a/lambda/check-view-secutiry-option/check-view-option/dto/__init__.py b/lambda/check-view-secutiry-option/check-view-option/dto/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/lambda/check-view-secutiry-option/check-view-option/dto/view_secutiry_option.py b/lambda/check-view-secutiry-option/check-view-option/dto/view_secutiry_option.py new file mode 100644 index 00000000..f5cdc3dc --- /dev/null +++ b/lambda/check-view-secutiry-option/check-view-option/dto/view_secutiry_option.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + + +@dataclass +class ViewSecurityOption: + schema_name: str + table_name: str diff --git a/lambda/check-view-secutiry-option/check-view-option/main.py b/lambda/check-view-secutiry-option/check-view-option/main.py index cd41aaa4..81586cc3 100644 --- a/lambda/check-view-secutiry-option/check-view-option/main.py +++ b/lambda/check-view-secutiry-option/check-view-option/main.py @@ -9,18 +9,20 @@ import botocore from aws.s3 import ConfigBucket from aws.ssm import SSMParameterStore from constants import (CHECK_TARGET_SCHEMAS, - INFORMATION_SCHEMA_SECURITY_TYPE_INVOKER, + INFORMATION_SCHEMA_SECURITY_TYPE_INVOKER, MAIL_INDENT, RESPONSE_CODE_NO_SUCH_KEY, RESPONSE_CODE_PARAMETER_NOT_FOUND, RESPONSE_ERROR, RESPONSE_ERROR_CODE) from database import Database +from dto.view_secutiry_option import ViewSecurityOption from exceptions import (DatabaseConnectionException, FileNotFoundException, MeDaCaException, ParameterNotFoundException) from medaca_logger import MeDaCaLogger +logger = MeDaCaLogger.get_logger() + def handler(event, context): - logger = MeDaCaLogger.get_logger() try: logger.info('I-01-01', '処理開始 Viewセキュリティオプション付与チェック') logger.info('I-02-02', 'チェック対象スキーマ名ファイルを読み込み 開始') @@ -38,9 +40,13 @@ def handler(event, context): if len(check_result) == 0: logger.info('I-04-02', 'Viewセキュリティオプション 未設定のViewはありません。処理を終了します。') return - logger.info('I-04-01', 'Viewセキュリティオプション 未設定のViewがあるため、メール送信処理を開始します。') + view_security_options = [ViewSecurityOption(*row) for row in check_result] + + mail_title, mail_body = make_notice_mail(view_security_options) + print(mail_title, mail_body) + except MeDaCaException as e: logger.exception(e.error_id, e) raise e @@ -63,7 +69,7 @@ def read_check_target_schemas() -> list: """ try: config_bucket = ConfigBucket() - check_target_schema_names = config_bucket.check_target_schema_names() + check_target_schema_names = config_bucket.check_target_schema_names return json.loads(check_target_schema_names)[CHECK_TARGET_SCHEMAS] except botocore.exceptions.ClientError as e: if e.response[RESPONSE_ERROR][RESPONSE_ERROR_CODE] == RESPONSE_CODE_NO_SUCH_KEY: @@ -84,9 +90,9 @@ def read_db_param_from_parameter_store() -> tuple: """ try: parameter_store = SSMParameterStore() - db_host = parameter_store.db_host() - db_user_name = parameter_store.db_user_name() - db_user_password = parameter_store.db_user_password() + db_host = parameter_store.db_host + db_user_name = parameter_store.db_user_name + db_user_password = parameter_store.db_user_password return db_host, db_user_name, db_user_password except botocore.exceptions.ClientError as e: if e.response[RESPONSE_ERROR][RESPONSE_ERROR_CODE] == RESPONSE_CODE_PARAMETER_NOT_FOUND: @@ -126,6 +132,46 @@ def check_view_security_option(connection: Database, check_target_schemas: list) raise DatabaseConnectionException('E-03-02', f'Viewセキュリティオプションチェックに失敗しました エラー内容:{e}') +def make_notice_mail(view_security_options: list[ViewSecurityOption]): + config_bucket = ConfigBucket() + logger.info( + 'I-05-02', f'通知メール(タイトル)テンプレートファイル読込 読込元:{config_bucket.bucket_name}/{config_bucket.mail_title_file_path}') + mail_title_template = read_mail_title(config_bucket) + logger.info( + 'I-05-02', f'通知メール(本文)テンプレートファイル読込 読込元:{config_bucket.bucket_name}/{config_bucket.mail_body_file_path}') + mail_body_template = read_mail_body_template(config_bucket) + + mail_message = MAIL_INDENT.join([f'{option.schema_name}.{option.table_name}' for option in view_security_options]) + + mail_body = mail_body_template.format(no_option_views=mail_message) + + return mail_title_template, mail_body + + +def read_mail_title(config_bucket: ConfigBucket): + try: + mail_title = config_bucket.notice_mail_title_template + except botocore.exceptions.ClientError as e: + if e.response[RESPONSE_ERROR][RESPONSE_ERROR_CODE] == RESPONSE_CODE_NO_SUCH_KEY: + raise FileNotFoundException('E-02-01', f'通知メール(タイトル)テンプレートファイルの読み込みに失敗しました エラー内容:{e}') + else: + raise Exception(e) + + return mail_title + + +def read_mail_body_template(config_bucket: ConfigBucket): + try: + mail_body_template = config_bucket.notice_mail_body_template + except botocore.exceptions.ClientError as e: + if e.response[RESPONSE_ERROR][RESPONSE_ERROR_CODE] == RESPONSE_CODE_NO_SUCH_KEY: + raise FileNotFoundException('E-02-01', f'通知メール(本文)テンプレートファイルの読み込みに失敗しました エラー内容:{e}') + else: + raise Exception(e) + + return mail_body_template + + # ローカル実行用 if __name__ == '__main__': handler({}, {}) diff --git a/s3/config/view_check/check_view_secutiry_option_mail_body.config b/s3/config/view_check/check_view_secutiry_option_mail_body.config new file mode 100644 index 00000000..5457eafc --- /dev/null +++ b/s3/config/view_check/check_view_secutiry_option_mail_body.config @@ -0,0 +1,6 @@ +宛先各位 + customスキーマの以下のviewに「SQL SECURITY INVOKER」オプションが指定されておりません。viewを再作成しオプションを指定してください。 +  {no_option_views} + + 尚、本メールはシステム自動送信ですので、返信できません。 + 本件に関する問い合わせは、IT部門ゴザリ様にお願いいたします。 diff --git a/s3/config/view_check/check_view_secutiry_option_mail_title.config b/s3/config/view_check/check_view_secutiry_option_mail_title.config new file mode 100644 index 00000000..a85c0134 --- /dev/null +++ b/s3/config/view_check/check_view_secutiry_option_mail_title.config @@ -0,0 +1 @@ +【MeDaCaシステム通知】view参照制限オプション指定漏れを検出しました \ No newline at end of file