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 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 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 signature_upload(framework_slug, agreement_id): framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) # if there's no frameworkAgreementVersion key it means we're pre-G-Cloud 8 and shouldn't be using this route if not framework.get('frameworkAgreementVersion'): abort(404) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort( data_api_client, framework_slug) agreement = data_api_client.get_framework_agreement( agreement_id)['agreement'] check_agreement_is_related_to_supplier_framework_or_abort( agreement, supplier_framework) agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) signature_page = agreements_bucket.get_key( agreement.get('signedAgreementPath')) 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, agreement_id=agreement_id)) 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: extension = get_extension(request.files['signature_page'].filename) upload_path = generate_timestamped_document_upload_path( framework_slug, current_user.supplier_id, 'agreements', '{}{}'.format(SIGNED_AGREEMENT_PREFIX, extension)) agreements_bucket.save( upload_path, request.files['signature_page'], acl='private', download_filename='{}-{}-{}{}'.format( sanitise_supplier_name(current_user.supplier_name), current_user.supplier_id, SIGNED_SIGNATURE_PAGE_PREFIX, extension), disposition_type= 'inline' # Embeddeding PDFs in admin pages requires 'inline' and not 'attachment' ) data_api_client.update_framework_agreement( agreement_id, {"signedAgreementPath": upload_path}, current_user.email_address) session['signature_page'] = request.files[ 'signature_page'].filename return redirect( url_for(".contract_review", framework_slug=framework_slug, agreement_id=agreement_id)) return render_template( "frameworks/signature_upload.html", agreement=agreement, framework=framework, signature_page=signature_page, upload_error=upload_error, ), 400 if upload_error else 200
def upload_framework_agreement(framework_slug): """ This is the route used to upload agreements for pre-G-Cloud 8 frameworks """ framework = get_framework(data_api_client, framework_slug, allowed_statuses=['standstill', 'live']) # if there's a frameworkAgreementVersion key it means we're on G-Cloud 8 or higher and shouldn't be using this route if framework.get('frameworkAgreementVersion'): abort(404) 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( "frameworks/agreement.html", framework=framework, supplier_framework=supplier_framework, upload_error=upload_error, agreement_filename=AGREEMENT_FILENAME, ), 400 agreements_bucket = s3.S3(current_app.config['DM_AGREEMENTS_BUCKET']) extension = get_extension(request.files['agreement'].filename) path = generate_timestamped_document_upload_path( framework_slug, current_user.supplier_id, 'agreements', '{}{}'.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_id, SIGNED_AGREEMENT_PREFIX, extension)) agreement_id = data_api_client.create_framework_agreement( current_user.supplier_id, framework_slug, current_user.email_address)['agreement']['id'] data_api_client.update_framework_agreement(agreement_id, {"signedAgreementPath": path}, current_user.email_address) data_api_client.sign_framework_agreement( agreement_id, current_user.email_address, {"uploaderUserId": current_user.id}) try: email_body = render_template( 'emails/framework_agreement_uploaded.html', framework_name=framework['name'], supplier_name=current_user.supplier_name, supplier_id=current_user.supplier_id, user_name=current_user.name) send_email( current_app.config['DM_FRAMEWORK_AGREEMENTS_EMAIL'], email_body, current_app.config['DM_MANDRILL_API_KEY'], '{} 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 MandrillException as e: current_app.logger.error( "Framework agreement email failed to send. " "error {error} supplier_id {supplier_id} email_hash {email_hash}", extra={ 'error': six.text_type(e), 'supplier_id': current_user.supplier_id, '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_file_is_empty(self): empty_file = mock_file('file1', 0) assert not file_is_not_empty(empty_file) assert file_is_empty(empty_file)
def test_file_is_not_empty(self): non_empty_file = mock_file('file1', 1) assert file_is_not_empty(non_empty_file) assert not file_is_empty(non_empty_file)
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_file_is_empty(self): empty_file = MockFile(b"", 'file1') assert not file_is_not_empty(empty_file) assert file_is_empty(empty_file)
def test_file_is_not_empty(self): non_empty_file = MockFile(b"*", 'file1') assert file_is_not_empty(non_empty_file) assert not file_is_empty(non_empty_file)
def test_file_is_empty(self): empty_file = mock_file('file1', 0) assert not file_is_not_empty(empty_file) assert file_is_empty(empty_file)
def test_file_is_not_empty(self): non_empty_file = mock_file('file1', 1) assert file_is_not_empty(non_empty_file) assert not file_is_empty(non_empty_file)