def upload_countersigned_agreement_file(supplier_id, framework_slug): agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) errors = {} if request.files.get('countersigned_agreement'): the_file = request.files['countersigned_agreement'] if not file_is_pdf(the_file): errors['countersigned_agreement'] = 'not_pdf' if 'countersigned_agreement' not in errors.keys(): filename = get_agreement_document_path(framework_slug, supplier_id, COUNTERSIGNED_AGREEMENT_FILENAME) agreements_bucket.save(filename, the_file) data_api_client.create_audit_event( audit_type=AuditTypes.upload_countersigned_agreement, user=current_user.email_address, object_type='suppliers', object_id=supplier_id, data={'upload_countersigned_agreement': filename}) flash('countersigned_agreement', 'upload_countersigned_agreement') if len(errors) > 0: for category, message in errors.items(): flash(category, message) return redirect(url_for( '.list_countersigned_agreement_file', supplier_id=supplier_id, framework_slug=framework_slug) )
def upload_countersigned_agreement_file(supplier_code, framework_slug): agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) errors = {} if request.files.get('countersigned_agreement'): the_file = request.files['countersigned_agreement'] if not file_is_pdf(the_file): errors['countersigned_agreement'] = 'not_pdf' if 'countersigned_agreement' not in errors.keys(): filename = get_agreement_document_path( framework_slug, supplier_code, COUNTERSIGNED_AGREEMENT_FILENAME) agreements_bucket.save(filename, the_file) data_api_client.create_audit_event( audit_type=AuditTypes.upload_countersigned_agreement, user=current_user.email_address, object_type='suppliers', object_id=supplier_code, data={'upload_countersigned_agreement': filename}) flash('countersigned_agreement', 'upload_countersigned_agreement') if len(errors) > 0: for category, message in errors.items(): flash(category, message) return redirect( url_for('.list_countersigned_agreement_file', supplier_code=supplier_code, framework_slug=framework_slug))
def get_most_recently_uploaded_agreement_file_or_none(bucket, framework_slug, supplier_id): download_path = get_agreement_document_path( framework_slug, supplier_id, SIGNED_AGREEMENT_PREFIX ) files = bucket.list(download_path) return files.pop() if files else None
def signature_upload(framework_slug): framework = get_framework(data_api_client, framework_slug) return_supplier_framework_info_if_on_framework_or_abort( data_api_client, framework_slug) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) signature_page = get_most_recently_uploaded_agreement_file_or_none( agreements_bucket, framework_slug) upload_error = None if request.method == 'POST': # No file chosen for upload and file already exists on s3 so can use existing and progress if not request.files['signature_page'].filename and signature_page: return redirect( url_for(".contract_review", framework_slug=framework_slug)) if not file_is_image( request.files['signature_page']) and not file_is_pdf( request.files['signature_page']): upload_error = "The file must be a PDF, JPG or PNG" elif not file_is_less_than_5mb(request.files['signature_page']): upload_error = "The file must be less than 5MB" elif file_is_empty(request.files['signature_page']): upload_error = "The file must not be empty" if not upload_error: upload_path = get_agreement_document_path( framework_slug, current_user.supplier_code, '{}{}'.format( SIGNED_AGREEMENT_PREFIX, get_extension(request.files['signature_page'].filename))) agreements_bucket.save(upload_path, request.files['signature_page'], acl='private') session['signature_page'] = request.files[ 'signature_page'].filename data_api_client.create_audit_event( audit_type=AuditTypes.upload_signed_agreement, user=current_user.email_address, object_type="suppliers", object_id=current_user.supplier_code, data={ "upload_signed_agreement": request.files['signature_page'].filename, "upload_path": upload_path }) return redirect( url_for(".contract_review", framework_slug=framework_slug)) status_code = 400 if upload_error else 200 return render_template_with_csrf( "frameworks/signature_upload.html", status_code=status_code, framework=framework, signature_page=signature_page, upload_error=upload_error, )
def download_agreement_file(framework_slug, document_name): supplier_framework_info = get_supplier_framework_info(data_api_client, framework_slug) if supplier_framework_info is None or not supplier_framework_info.get("declaration"): abort(404) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) path = get_agreement_document_path(framework_slug, current_user.supplier_code, document_name) url = get_signed_url(agreements_bucket, path, current_app.config['DM_ASSETS_URL']) if not url: abort(404) return redirect(url)
def signature_upload(framework_slug): framework = get_framework(data_api_client, framework_slug) return_supplier_framework_info_if_on_framework_or_abort(data_api_client, framework_slug) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) signature_page = get_most_recently_uploaded_agreement_file_or_none(agreements_bucket, framework_slug) upload_error = None if request.method == 'POST': # No file chosen for upload and file already exists on s3 so can use existing and progress if not request.files['signature_page'].filename and signature_page: return redirect(url_for(".contract_review", framework_slug=framework_slug)) if not file_is_image(request.files['signature_page']) and not file_is_pdf(request.files['signature_page']): upload_error = "The file must be a PDF, JPG or PNG" elif not file_is_less_than_5mb(request.files['signature_page']): upload_error = "The file must be less than 5MB" elif file_is_empty(request.files['signature_page']): upload_error = "The file must not be empty" if not upload_error: upload_path = get_agreement_document_path( framework_slug, current_user.supplier_code, '{}{}'.format(SIGNED_AGREEMENT_PREFIX, get_extension(request.files['signature_page'].filename)) ) agreements_bucket.save( upload_path, request.files['signature_page'], acl='private' ) session['signature_page'] = request.files['signature_page'].filename data_api_client.create_audit_event( audit_type=AuditTypes.upload_signed_agreement, user=current_user.email_address, object_type="suppliers", object_id=current_user.supplier_code, data={ "upload_signed_agreement": request.files['signature_page'].filename, "upload_path": upload_path }) return redirect(url_for(".contract_review", framework_slug=framework_slug)) status_code = 400 if upload_error else 200 return render_template_with_csrf( "frameworks/signature_upload.html", status_code=status_code, framework=framework, signature_page=signature_page, upload_error=upload_error, )
def download_agreement_file(supplier_id, framework_slug, document_name): supplier_framework = data_api_client.get_supplier_framework_info(supplier_id, framework_slug)['frameworkInterest'] if not supplier_framework.get('declaration'): abort(404) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) prefix = get_agreement_document_path(framework_slug, supplier_id, document_name) agreement_documents = agreements_bucket.list(prefix=prefix) if not len(agreement_documents): abort(404) path = agreement_documents[-1]['path'] url = get_signed_url(agreements_bucket, path, current_app.config['DM_ASSETS_URL']) if not url: abort(404) return redirect(url)
def download_agreement_file(framework_slug, document_name): supplier_framework_info = get_supplier_framework_info( data_api_client, framework_slug) if supplier_framework_info is None or not supplier_framework_info.get( "declaration"): abort(404) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) path = get_agreement_document_path(framework_slug, current_user.supplier_id, document_name) url = get_signed_url(agreements_bucket, path, current_app.config['DM_ASSETS_URL']) if not url: abort(404) return redirect(url)
def list_countersigned_agreement_file(supplier_id, framework_slug): supplier = data_api_client.get_supplier(supplier_id)['suppliers'] framework = data_api_client.get_framework(framework_slug)['frameworks'] agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) path = get_agreement_document_path(framework_slug, supplier_id, COUNTERSIGNED_AGREEMENT_FILENAME) countersigned_agreement_document = agreements_bucket.get_key(path) if countersigned_agreement_document: countersigned_agreement = countersigned_agreement_document countersigned_agreement['last_modified'] = datetimeformat(parse_date( countersigned_agreement['last_modified'])) countersigned_agreement = [countersigned_agreement] else: countersigned_agreement = [] return render_template( "suppliers/upload_countersigned_agreement.html", supplier=supplier, framework=framework, countersigned_agreement=countersigned_agreement, countersigned_agreement_filename=COUNTERSIGNED_AGREEMENT_FILENAME )
def remove_countersigned_agreement_file(supplier_id, framework_slug): agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) document = get_agreement_document_path(framework_slug, supplier_id, COUNTERSIGNED_AGREEMENT_FILENAME) if request.method == 'GET': flash('countersigned_agreement', 'remove_countersigned_agreement') if request.method == 'POST': agreements_bucket.delete_key(document) data_api_client.create_audit_event( audit_type=AuditTypes.delete_countersigned_agreement, user=current_user.email_address, object_type='suppliers', object_id=supplier_id, data={'upload_countersigned_agreement': document}) return redirect(url_for( '.list_countersigned_agreement_file', supplier_id=supplier_id, framework_slug=framework_slug) )
def remove_countersigned_agreement_file(supplier_code, framework_slug): agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) document = get_agreement_document_path(framework_slug, supplier_code, COUNTERSIGNED_AGREEMENT_FILENAME) if request.method == 'GET': flash('countersigned_agreement', 'remove_countersigned_agreement') if request.method == 'POST': agreements_bucket.delete_key(document) data_api_client.create_audit_event( audit_type=AuditTypes.delete_countersigned_agreement, user=current_user.email_address, object_type='suppliers', object_id=supplier_code, data={'upload_countersigned_agreement': document}) return redirect( url_for('.list_countersigned_agreement_file', supplier_code=supplier_code, framework_slug=framework_slug))
def countersigned_framework_agreement_exists_in_bucket(framework_slug, bucket): agreements_bucket = s3.S3(bucket) countersigned_path = get_agreement_document_path( framework_slug, current_user.supplier_code, COUNTERSIGNED_AGREEMENT_FILENAME) return agreements_bucket.path_exists(countersigned_path)
def test_get_agreement_document_path(): assert get_agreement_document_path('g-cloud-7', 1234, 'foo.pdf') == \ 'g-cloud-7/agreements/1234/1234-foo.pdf'
def countersigned_framework_agreement_exists_in_bucket(framework_slug, bucket): agreements_bucket = s3.S3(bucket) countersigned_path = get_agreement_document_path( framework_slug, current_user.supplier_id, COUNTERSIGNED_AGREEMENT_FILENAME) return agreements_bucket.path_exists(countersigned_path)
def upload_framework_agreement(framework_slug): framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort(data_api_client, framework_slug) upload_error = None if not file_is_less_than_5mb(request.files['agreement']): upload_error = "Document must be less than 5MB" elif file_is_empty(request.files['agreement']): upload_error = "Document must not be empty" if upload_error is not None: return render_template_with_csrf( "frameworks/agreement.html", status_code=400, framework=framework, supplier_framework=supplier_framework, upload_error=upload_error, agreement_filename=AGREEMENT_FILENAME ) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) extension = get_extension(request.files['agreement'].filename) path = get_agreement_document_path( framework_slug, current_user.supplier_code, '{}{}'.format(SIGNED_AGREEMENT_PREFIX, extension) ) agreements_bucket.save( path, request.files['agreement'], acl='private', download_filename='{}-{}-{}{}'.format( sanitise_supplier_name(current_user.supplier_name), current_user.supplier_code, SIGNED_AGREEMENT_PREFIX, extension ) ) data_api_client.register_framework_agreement_returned( current_user.supplier_code, framework_slug, current_user.email_address) try: email_body = render_template( 'emails/framework_agreement_uploaded.html', framework_name=framework['name'], supplier_name=current_user.supplier_name, supplier_code=current_user.supplier_code, user_name=current_user.name ) send_email( current_app.config['DM_FRAMEWORK_AGREEMENTS_EMAIL'], email_body, '{} framework agreement'.format(framework['name']), current_app.config["DM_GENERIC_NOREPLY_EMAIL"], '{} Supplier'.format(framework['name']), ['{}-framework-agreement'.format(framework_slug)], reply_to=current_user.email_address, ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( "Framework agreement email failed to send. " "error {error} supplier_code {supplier_code} email_hash {email_hash}", extra={'error': six.text_type(e), 'supplier_code': current_user.supplier_code, 'email_hash': hash_email(current_user.email_address)}) abort(503, "Framework agreement email failed to send") return redirect(url_for('.framework_agreement', framework_slug=framework_slug))
def upload_framework_agreement(framework_slug): framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort( data_api_client, framework_slug) upload_error = None if not file_is_less_than_5mb(request.files['agreement']): upload_error = "Document must be less than 5MB" elif file_is_empty(request.files['agreement']): upload_error = "Document must not be empty" if upload_error is not None: return render_template_with_csrf("frameworks/agreement.html", status_code=400, framework=framework, supplier_framework=supplier_framework, upload_error=upload_error, agreement_filename=AGREEMENT_FILENAME) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) extension = get_extension(request.files['agreement'].filename) path = get_agreement_document_path( framework_slug, current_user.supplier_code, '{}{}'.format(SIGNED_AGREEMENT_PREFIX, extension)) agreements_bucket.save( path, request.files['agreement'], acl='private', download_filename='{}-{}-{}{}'.format( sanitise_supplier_name(current_user.supplier_name), current_user.supplier_code, SIGNED_AGREEMENT_PREFIX, extension)) data_api_client.register_framework_agreement_returned( current_user.supplier_code, framework_slug, current_user.email_address) try: email_body = render_template( 'emails/framework_agreement_uploaded.html', framework_name=framework['name'], supplier_name=current_user.supplier_name, supplier_code=current_user.supplier_code, user_name=current_user.name) send_email( current_app.config['DM_FRAMEWORK_AGREEMENTS_EMAIL'], email_body, '{} framework agreement'.format(framework['name']), current_app.config["DM_GENERIC_NOREPLY_EMAIL"], '{} Supplier'.format(framework['name']), ['{}-framework-agreement'.format(framework_slug)], reply_to=current_user.email_address, ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( "Framework agreement email failed to send. " "error {error} supplier_code {supplier_code} email_hash {email_hash}", extra={ 'error': six.text_type(e), 'supplier_code': current_user.supplier_code, 'email_hash': hash_email(current_user.email_address) }) abort(503, "Framework agreement email failed to send") return redirect( url_for('.framework_agreement', framework_slug=framework_slug))
def test_get_agreement_document_path(): assert get_agreement_document_path('g-cloud-7', 1234, 'foo.pdf') == \ 'g-cloud-7/agreements/1234/1234-foo.pdf'
def get_most_recently_uploaded_agreement_file_or_none(bucket, framework_slug, supplier_id): download_path = get_agreement_document_path(framework_slug, supplier_id, SIGNED_AGREEMENT_PREFIX) files = bucket.list(download_path) return files.pop() if files else None