def test_s3download_gets_file(mocker):
    mocked = mocker.patch('notifications_utils.s3.resource')
    mocked_object = mocked.return_value.Object
    mocked_get = mocked.return_value.Object.return_value.get
    s3download('bucket', 'location.file')
    mocked_object.assert_called_once_with('bucket', 'location.file')
    mocked_get.assert_called_once_with()
def test_s3download_raises_on_error(mocker):
    mocked = mocker.patch('notifications_utils.s3.resource')
    mocked.return_value.Object.side_effect = botocore.exceptions.ClientError(
        {'Error': {
            'Code': 404
        }},
        'Bad exception',
    )

    with pytest.raises(S3ObjectNotFound):
        s3download('bucket', 'location.file')
Exemple #3
0
def sanitise_and_upload_letter(notification_id,
                               filename,
                               allow_international_letters=False):
    current_app.logger.info(
        'Sanitising notification with id {}'.format(notification_id))

    try:
        pdf_content = s3download(
            current_app.config['LETTERS_SCAN_BUCKET_NAME'], filename).read()
        sanitisation_details = sanitise_file_contents(
            pdf_content,
            allow_international_letters=allow_international_letters,
            filename=filename)

        # Only files that have failed sanitisation have 'message' in the sanitisation_details dict
        if sanitisation_details.get('message'):
            validation_status = 'failed'
        else:
            validation_status = 'passed'
            file_data = base64.b64decode(sanitisation_details['file'].encode())

            redaction_failed_message = sanitisation_details.get(
                'redaction_failed_message')
            if redaction_failed_message:
                current_app.logger.info(
                    f'{redaction_failed_message} for file {filename}')
                copy_redaction_failed_pdf(filename)

            # If the file already exists in S3, it will be overwritten
            s3upload(
                filedata=file_data,
                region=current_app.config['AWS_REGION'],
                bucket_name=current_app.config['SANITISED_LETTER_BUCKET_NAME'],
                file_location=filename,
            )

        current_app.logger.info('Notification {} sanitisation: {}'.format(
            validation_status, notification_id))

    except BotoClientError:
        current_app.logger.exception(
            "Error downloading {} from scan bucket or uploading to sanitise bucket for notification {}"
            .format(filename, notification_id))
        return

    sanitise_data = {
        'page_count': sanitisation_details['page_count'],
        'message': sanitisation_details['message'],
        'invalid_pages': sanitisation_details['invalid_pages'],
        'validation_status': validation_status,
        'filename': filename,
        'notification_id': notification_id,
        'address': sanitisation_details['recipient_address']
    }
    encrypted_data = current_app.encryption_client.encrypt(sanitise_data)

    notify_celery.send_task(name=TaskNames.PROCESS_SANITISED_LETTER,
                            args=(encrypted_data, ),
                            queue=QueueNames.LETTERS)
            def new_function():

                with suppress(S3ObjectNotFound):
                    return s3download(
                        application.config['LETTER_CACHE_BUCKET_NAME'],
                        cache_key,
                    )

                data = original_function()

                s3upload(
                    data,
                    application.config['AWS_REGION'],
                    application.config['LETTER_CACHE_BUCKET_NAME'],
                    cache_key,
                )

                data.seek(0)
                return data