"""Lambda av_scan function module. you can run locally with something like: CLAMSCAN_PATH='/usr/local/Cellar/clamav/0.102.2/bin/clamscan' \ PYTHONPATH=. env/bin/python3.8 index.py """ import src.av_scan as av_scan from src.handle_result.handle_result import handle_result from lambdacommon.common_config import logger import src.s3 as s3 def extract_triggered_key(event): """Get S3 bucket and key from CloudWatch or Eventbridge event. Args: event (dict): AWS CloudWatch or Eventbridge event data object. Returns: (str, str): Tuple of bucket and key names. """ if not event.get('detail'): raise Exception('Invalid event. Cannot scan this file.') if event['detail'].get('requestParameters'): # this is cloudwatch event request_params = event['detail']['requestParameters'] bucket_name = request_params.get('bucketName') key = request_params.get('key') return bucket_name, key if event['detail'].get('bucket') and event['detail'].get('object'): # this is Eventbridge event bucket_name = event['detail']['bucket']['name'] key = event['detail']['object']['key'] return bucket_name, key def handler(event, context): """Lambda entry point.""" try: bucket, key = extract_triggered_key(event) s3_obj = s3.get_object(bucket=bucket, key=key) file_contents = s3_obj['Body'].read() file_metadata = s3_obj['Metadata'] result = av_scan.scan_string_for_virus(file_contents) if result == 1 and event.get('delete', True) is True: s3.delete_object(bucket=bucket, key=key) handle_result(bucket, key, result, file_metadata) return {'has_virus': False if result == 0 else True} except Exception as e: logger.exception(str(e)) raise e if __name__ == '__main__': handler({ 'detail': { 'requestParameters': { 'bucketName': 'dev-orcd-podcast-output-assets', 'key': 'copies/safe.pdf' } } }, None) handler({ 'detail': { 'requestParameters': { 'bucketName': 'dev-orcd-podcast-output-assets', 'key': 'copies/eicar.pdf' } }, 'delete': False }, None) handler({ 'detail': { 'requestParameters': { 'bucketName': 'test-orcd-bucket', 'key': 'nr-ingestion/valid_test1.csv' } } }, None)