def withdraw_brief(brief_id): try: brief = data_api_client.req.briefs(brief_id).withdraw().post({ 'update_details': { 'updated_by': current_user.email_address } }).get('briefs') except HTTPError as e: flash(e.message, 'error') brief = data_api_client.get_brief(brief_id).get('briefs') return render_template_with_csrf('view_buyers.html', users=brief.get('users'), title=brief.get('title'), brief_id=brief_id, brief=brief) flash('brief_withdrawn', 'info') return render_template_with_csrf( 'view_buyers.html', users=brief.get('users'), title=brief.get('title'), brief_id=brief_id, brief=brief, seller_email_list=convert_array_to_string( brief.get('sellerEmailList', [])), seller_email=brief.get('sellerEmail', ''), area_of_expertise_list=AREA_OF_EXPERTISE_LIST, area_of_expertise_selected=brief.get('areaOfExpertise', ''))
def process_login(): form = auth_forms.LoginForm(request.form) next_url = request.args.get('next') if form.validate(): user_json = data_api_client.authenticate_user(form.email_address.data, form.password.data) if not user_json: current_app.logger.info( "login.fail: failed to sign in {email_hash}", extra={'email_hash': hash_email(form.email_address.data)}) flash("no_account", "error") return render_template_with_csrf("auth/login.html", status_code=403, form=form, next=next_url) user = User.from_json(user_json) login_user(user) current_app.logger.info('login.success: {user}', extra={'user': user_logging_string(user)}) check_terms_acceptance() return redirect_logged_in_user(next_url) else: return render_template_with_csrf("auth/login.html", status_code=400, form=form, next=next_url)
def send_invite_user(): form = EmailAddressForm(request.form) if form.validate(): email_address = form.email_address.data token = generate_supplier_invitation_token( name='', supplier_code=current_user.supplier_code, supplier_name=current_user.supplier_name, email_address=email_address ) url = url_for('main.create_user', token=token, _external=True) email_body = render_template( 'emails/invite_user_email.html', url=url, user=current_user.name, supplier=current_user.supplier_name, generic_contact_email=current_app.config['GENERIC_CONTACT_EMAIL']) try: send_email( email_address, email_body, 'Invitation to join {} as a team member'.format( current_user .supplier_name .encode("ascii", "ignore") .decode('ascii') ), current_app.config['INVITE_EMAIL_FROM'], current_app.config['INVITE_EMAIL_NAME'] ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( 'Invitation 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, 'Failed to send user invite reset') data_api_client.create_audit_event( audit_type=AuditTypes.invite_user, user=current_user.email_address, object_type='suppliers', object_id=current_user.supplier_code, data={'invitedEmail': email_address}, ) form.email_address.data = None return render_template_with_csrf( 'auth/submit_email_address.html', form=form, invited_user=email_address) else: return render_template_with_csrf( 'auth/submit_email_address.html', status_code=400, form=form)
def submit_create_buyer_account(token): try: data = decode_buyer_creation_token(token.encode()) except InvalidToken: return render_template_with_csrf('auth/create-buyer-user-error.html', status_code=400, token=None) form = auth_forms.CreateUserForm(request.form) email_address = data.get('emailAddress', None) if email_address is None: email_address = data.get('email_address', None) if not form.validate(): current_app.logger.warning( 'createbuyeruser.invalid: {form_errors}', extra={'form_errors': ', '.join(form.errors)}) return render_template_with_csrf('auth/create-user.html', status_code=400, form=form, email_address=email_address, token=token) try: user = data_api_client.create_user({ 'name': form.name.data, 'password': form.password.data, 'emailAddress': email_address, 'role': 'buyer' }) user = User.from_json(user) login_user(user) send_buyer_onboarding_email(form.name.data, email_address) except HTTPError as e: if e.status_code != 409: raise return render_template_with_csrf('auth/create-buyer-user-error.html', status_code=400, error=e.message, token=None) flash( 'Welcome to your buyer dashboard. \ This is where you can create and track the opportunities you publish in the Marketplace.', 'flag') return redirect_logged_in_user()
def edit_supplier_declaration_section(supplier_code, framework_slug, section_id): supplier = data_api_client.get_supplier(supplier_code)['supplier'] framework = data_api_client.get_framework(framework_slug)['frameworks'] if framework['status'] not in ['pending', 'standstill', 'live']: abort(403) try: declaration = data_api_client.get_supplier_declaration( supplier_code, framework_slug)['declaration'] except APIError as e: if e.status_code != 404: raise declaration = {} content = content_loader.get_manifest(framework_slug, 'declaration').filter(declaration) section = content.get_section(section_id) if section is None: abort(404) return render_template_with_csrf("suppliers/edit_declaration.html", supplier=supplier, framework=framework, declaration=declaration, section=section)
def 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) if supplier_framework['agreementReturned']: date_formatter = DateFormatter(current_app.config['DM_TIMEZONE']) supplier_framework['agreementReturnedAt'] = date_formatter.datetimeformat( date_parse(supplier_framework['agreementReturnedAt']) ) # if there's a frameworkAgreementVersion key, it means we're on G-Cloud 8 or higher if framework.get('frameworkAgreementVersion'): drafts, complete_drafts = get_drafts(data_api_client, framework_slug) lots_with_completed_drafts = [ lot for lot in framework['lots'] if count_drafts_by_lot(complete_drafts, lot['slug']) ] return render_template( 'frameworks/contract_start.html', signature_page_filename=SIGNATURE_PAGE_FILENAME, framework=framework, lots=[{ 'name': lot['name'], 'has_completed_draft': (lot in lots_with_completed_drafts) } for lot in framework['lots']], supplier_framework=supplier_framework, ), 200 return render_template_with_csrf( "frameworks/agreement.html", framework=framework, supplier_framework=supplier_framework, agreement_filename=AGREEMENT_FILENAME )
def update_password(token): form = auth_forms.ChangePasswordForm(request.form) decoded = decode_password_reset_token(token.encode(), data_api_client) if decoded.get('error', None): flash(decoded['error'], 'error') return redirect(url_for('.request_password_reset')) user_id = decoded["user"] email_address = decoded["email"] password = form.password.data if form.validate(): if data_api_client.update_user_password(user_id, password, email_address): current_app.logger.info( "User {user_id} ({hashed_email}) successfully changed their password", extra={ 'user_id': user_id, 'hashed_email': hash_email(email_address) }) flash('password_updated') else: flash('password_not_updated', 'error') return redirect(url_for('.render_login')) else: return render_template_with_csrf("auth/reset-password.html", status_code=400, email_address=email_address, form=form, token=token)
def render_login(): next_url = request.args.get('next') if current_user.is_authenticated and not get_flashed_messages(): return redirect_logged_in_user(next_url) return render_template_with_csrf("auth/login.html", form=auth_forms.LoginForm(), next=next_url)
def test_render_template_with_csrf(self): with self.flask.app_context(): response, status_code = render_template_with_csrf('test_form.html', 123) assert status_code == 123 assert response.cache_control.private assert response.cache_control.max_age == self.flask.config['CSRF_TIME_LIMIT'] assert FakeCsrf.valid_token in response.get_data(as_text=True)
def edit_brief_question(framework_slug, lot_slug, brief_id, section_slug, question_id): get_framework_and_lot(framework_slug, lot_slug, data_api_client, status='live', must_allow_brief=True) brief = data_api_client.get_brief(brief_id)["briefs"] if not is_brief_correct( brief, framework_slug, lot_slug, current_user.id ) or not brief_can_be_edited(brief): abort(404) content = content_loader.get_manifest(brief['frameworkSlug'], 'edit_brief').filter( {'lot': brief['lotSlug']} ) section = content.get_section(section_slug) if section is None or not section.editable: abort(404) remove_non_cascade_fields(brief, section, question_id) question = section.get_question(question_id) if not question: abort(404) return render_template_with_csrf( "buyers/edit_brief_question.html", brief=brief, section=section, question=question )
def list_users(): return render_template_with_csrf( "users/list_users.html", current_user=current_user, users=get_current_suppliers_users() )
def framework_updates(framework_slug, error_message=None, default_textbox_value=None): framework = get_framework(data_api_client, framework_slug) current_app.logger.info("{framework_slug}-updates.viewed: user_id {user_id} supplier_code {supplier_code}", extra={'framework_slug': framework_slug, 'user_id': current_user.id, 'supplier_code': current_user.supplier_code}) communications_bucket = s3.S3(current_app.config['DM_COMMUNICATIONS_BUCKET']) file_list = communications_bucket.list('{}/communications/updates/'.format(framework_slug), load_timestamps=True) files = { 'communications': [], 'clarifications': [], } for file in file_list: path_parts = file['path'].split('/') file['path'] = '/'.join(path_parts[2:]) files[path_parts[3]].append(file) status_code = 200 if not error_message else 400 return render_template_with_csrf( "frameworks/updates.html", status_code=status_code, framework=framework, clarification_question_name=CLARIFICATION_QUESTION_NAME, clarification_question_value=default_textbox_value, error_message=error_message, files=files, dates=content_loader.get_message(framework_slug, 'dates'), agreement_countersigned=countersigned_framework_agreement_exists_in_bucket( framework_slug, current_app.config['DM_AGREEMENTS_BUCKET']) )
def submit_single_signup(): user = from_response(request) if user['user_type'] != 'buyer': return abort(400) fields = ['name', 'email_address', 'employment_status', 'user_type'] errors = validate_form_data(user, fields) if not is_government_email(user['email_address']): errors['email_address'] = {"government_email": True} if errors: return single_signup(user, errors) if user['employment_status'] == 'employee': token = generate_buyer_creation_token(user['name'], user['email_address']) send_buyer_account_activation_email( name=user["name"], email_address=user["email_address"], token=token) return render_template('auth/buyer-signup-email-sent.html', email_address=user["email_address"]) assert user['employment_status'] == 'contractor' form = auth_forms.BuyerInviteRequestForm(request.form) return render_template_with_csrf('auth/buyer-invite-request.html', form=form)
def find_supplier_services(): if not request.args.get('supplier_code'): abort(404) supplier_code = int(request.args['supplier_code']) supplier = data_api_client.get_supplier(supplier_code) services = data_api_client.find_services(supplier_code) if 'domains' not in supplier['supplier']: domains = {} supplier['supplier']['domains'] = domains else: domains = supplier['supplier']['domains'] assessed = [sd for sd in domains.get('all', []) if sd['status'] == 'assessed'] for a in assessed: pricing = supplier['supplier'].get('pricing', None) if pricing: price = pricing.get(a['domain_name'], None) if price: a['price'] = price['maxPrice'] else: a['price'] = 'Not specified' return render_template_with_csrf( "view_supplier_services.html", services=services["services"], supplier=supplier['supplier'], assessed=assessed )
def start_new_brief(framework_slug, lot_slug): if lot_slug in ['digital-outcome', 'digital-professionals', 'training']: abort(404) if not has_permission_to_edit_brief(): return redirect('/2/request-access/create_drafts') framework, lot = get_framework_and_lot(framework_slug, lot_slug, data_api_client, status='live', must_allow_brief=True) content = content_loader.get_manifest(framework_slug, 'edit_brief').filter( {'lot': lot['slug']}) section = content.get_section(content.get_next_editable_section_id()) return render_template_with_csrf( "buyers/create_brief_question.html", brief={}, framework=framework, lot=lot, section=section, question=section.questions[0], )
def company_name(): form = CompanyNameForm() if form.company_name.name in session: form.company_name.data = session[form.company_name.name] return render_template_with_csrf("suppliers/company_name.html", form=form)
def find_buyer_by_brief_id(): brief_id = request.args.get('brief_id') try: brief = data_api_client.get_brief(brief_id).get('briefs') except: # noqa flash('no_brief', 'error') return render_template( "view_buyers.html", users=list(), brief_id=brief_id, brief=None ), 404 users = brief.get('users') title = brief.get('title') return render_template_with_csrf( "view_buyers.html", users=users, title=title, brief_id=brief_id, brief=brief, seller_email_list=convert_array_to_string(brief.get('sellerEmailList', [])), seller_email=brief.get('sellerEmail', ''), area_of_expertise_list=AREA_OF_EXPERTISE_LIST, area_of_expertise_selected=brief.get('areaOfExpertise', '') )
def get_work_order_question(work_order_id, question_slug): try: work_order = data_api_client.get_work_order(work_order_id)['workOrder'] except APIError as e: abort(e.status_code) brief = data_api_client.get_brief(work_order['briefId'])["briefs"] if not is_brief_associated_with_user( brief, current_user.id ): abort(404) if questions.get(question_slug, None) is None: abort(404) form = FormFactory(question_slug) value = work_order.get(question_slug, None) if value is not None: if questions[question_slug].get('type') == 'address': form.abn.data = value['abn'] form.contact.data = value['contact'] form.name.data = value['name'] else: form[question_slug].data = value return render_template_with_csrf( 'workorder/work-order-question.html', work_order_id=work_order_id, question_slug=question_slug, form=form )
def edit_brief_question(framework_slug, lot_slug, brief_id, section_slug, question_id): get_framework_and_lot(framework_slug, lot_slug, data_api_client, status='live', must_allow_brief=True) brief = data_api_client.get_brief(brief_id)["briefs"] if not is_brief_correct( brief, framework_slug, lot_slug, current_user.id, data_api_client ) or not brief_can_be_edited(brief): abort(404) if not has_permission_to_edit_brief(brief): return redirect('/2/request-access/create_drafts') content = content_loader.get_manifest(brief['frameworkSlug'], 'edit_brief').filter( {'lot': brief['lotSlug']} ) section = content.get_section(section_slug) if section is None or not section.editable: abort(404) remove_non_cascade_fields(brief, section, question_id) question = section.get_question(question_id) if not question: abort(404) return render_template_with_csrf( "buyers/edit_brief_question.html", brief=brief, section=section, question=question )
def edit_supplier_name(supplier_code): supplier = data_api_client.get_supplier(supplier_code) return render_template_with_csrf( "edit_supplier_name.html", supplier=supplier['supplier'] )
def update_section(service_id, section_id): service = data_api_client.get_service(service_id) if service is None: abort(404) service = service['services'] if not is_service_associated_with_supplier(service): abort(404) content = content_loader.get_manifest('g-cloud-6', 'edit_service').filter(service) section = content.get_section(section_id) if section is None or not section.editable: abort(404) posted_data = section.get_data(request.form) try: data_api_client.update_service(service_id, posted_data, current_user.email_address) except HTTPError as e: errors = section.get_error_messages(e.message) if not posted_data.get('serviceName', None): posted_data['serviceName'] = service.get('serviceName', '') return render_template_with_csrf("services/edit_section.html", section=section, service_data=posted_data, service_id=service_id, errors=errors) return redirect(url_for(".edit_service", service_id=service_id))
def edit_service_submission(framework_slug, lot_slug, service_id, section_id, question_slug=None): framework, lot = get_framework_and_lot(data_api_client, framework_slug, lot_slug, allowed_statuses=['open']) try: draft = data_api_client.get_draft_service(service_id)['services'] except HTTPError as e: abort(e.status_code) if draft['lotSlug'] != lot_slug or draft['frameworkSlug'] != framework_slug: abort(404) if not is_service_associated_with_supplier(draft): abort(404) content = content_loader.get_manifest(framework_slug, 'edit_submission').filter(draft) section = content.get_section(section_id) if section and (question_slug is not None): section = section.get_question_as_section(question_slug) if section is None or not section.editable: abort(404) draft = section.unformat_data(draft) return render_template_with_csrf( "services/edit_submission_section.html", section=section, framework=framework, next_section_name=get_next_section_name(content, section.id), service_data=draft, service_id=service_id, return_to_summary=bool(request.args.get('return_to_summary')), one_service_limit=lot['oneServiceLimit'] )
def update_section(service_id, section_id): service = data_api_client.get_service(service_id) if service is None: abort(404) service = service['services'] if not is_service_associated_with_supplier(service): abort(404) content = content_loader.get_manifest('g-cloud-6', 'edit_service').filter(service) section = content.get_section(section_id) if section is None or not section.editable: abort(404) posted_data = section.get_data(request.form) try: data_api_client.update_service( service_id, posted_data, current_user.email_address) except HTTPError as e: errors = section.get_error_messages(e.message) if not posted_data.get('serviceName', None): posted_data['serviceName'] = service.get('serviceName', '') return render_template_with_csrf( "services/edit_section.html", section=section, service_data=posted_data, service_id=service_id, errors=errors ) return redirect(url_for(".edit_service", service_id=service_id))
def find_buyer_by_brief_id(): brief_id = request.args.get('brief_id') teams = [] try: brief = data_api_client.get_brief(brief_id).get('briefs') teams = data_api_client.req.admin().buyers(brief_id).teams().get() except: # noqa flash('no_brief', 'error') return render_template("view_buyers.html", users=list(), brief_id=brief_id, brief=None), 404 users = brief.get('users') title = brief.get('title') return render_template_with_csrf( "view_buyers.html", users=users, title=title, brief_id=brief_id, brief=brief, seller_email_list=convert_array_to_string( brief.get('sellerEmailList', [])), seller_email=brief.get('sellerEmail', ''), area_of_expertise_list=AREA_OF_EXPERTISE_LIST, area_of_expertise_selected=brief.get('areaOfExpertise', ''), teams_exists=len(teams) > 0, teams=teams)
def submit_buyer_invite_request(): form = auth_forms.BuyerInviteRequestForm(request.form) if not form.validate(): return render_template_with_csrf('auth/buyer-invite-request.html', status_code=400, form=form) token = generate_buyer_creation_token(**form.data) invite_url = url_for('.send_buyer_invite', token=token, _external=True) email_body = render_template( 'emails/buyer_account_invite_request_email.html', form=form, invite_url=invite_url) try: send_email( current_app.config['BUYER_INVITE_REQUEST_ADMIN_EMAIL'], email_body, current_app.config['BUYER_INVITE_REQUEST_SUBJECT'], current_app.config['BUYER_INVITE_REQUEST_EMAIL_FROM'], current_app.config['BUYER_INVITE_REQUEST_EMAIL_NAME'], ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( 'buyerinvite.fail: Buyer account invite request email failed to send. ' 'error {error} invite email_hash {email_hash}', extra={ 'error': six.text_type(e), 'email_hash': hash_email(form.email_address.data) }) abort(503, response='Failed to send buyer account invite request email.') email_body = render_template( 'emails/buyer_account_invite_manager_confirmation.html', form=form) try: send_email( form.manager_email.data, email_body, current_app.config['BUYER_INVITE_MANAGER_CONFIRMATION_SUBJECT'], current_app.config['DM_GENERIC_NOREPLY_EMAIL'], current_app.config['BUYER_INVITE_MANAGER_CONFIRMATION_NAME'], ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( 'buyerinvite.fail: Buyer account invite request manager email failed to send. ' 'error {error} invite email_hash {email_hash} manager email_hash {manager_email_hash}', extra={ 'error': six.text_type(e), 'email_hash': hash_email(form.email_address.data), 'manager_email_hash': hash_email(form.manager_email.data) }) abort(503, response= 'Failed to send buyer account invite request manager email.') return render_template('auth/buyer-invite-request-complete.html')
def dashboard(): supplier = data_api_client.get_supplier( current_user.supplier_code )['supplier'] supplier['contact'] = supplier['contacts'][0] if supplier['contacts'] else None all_frameworks = sorted( data_api_client.find_frameworks()['frameworks'], key=lambda framework: framework['slug'], reverse=True ) supplier_frameworks = { framework['frameworkSlug']: framework for framework in data_api_client.get_supplier_frameworks(current_user.supplier_code)['frameworkInterest'] } for framework in all_frameworks: framework.update( supplier_frameworks.get(framework['slug'], {}) ) dates = {} try: dates = content_loader.get_message(framework['slug'], 'dates') except ContentNotFoundError: pass framework.update({ 'dates': dates, 'deadline': Markup("Deadline: {}".format(dates.get('framework_close_date', ''))), 'registered_interest': (framework['slug'] in supplier_frameworks), 'made_application': ( framework.get('declaration') and framework['declaration'].get('status') == 'complete' and framework.get('complete_drafts_count') > 0 ), 'needs_to_complete_declaration': ( framework.get('onFramework') and framework.get('agreementReturned') is False ) }) digital_marketplace_panel = False digital_marketplace_framework = data_api_client.req.frameworks('digital-marketplace').get() for framework in supplier.get('frameworks', []): if framework['framework_id'] == digital_marketplace_framework['frameworks']['id']: digital_marketplace_panel = True return render_template_with_csrf( "suppliers/dashboard.html", supplier=supplier, users=get_current_suppliers_users(), needs_upgrade=(not digital_marketplace_panel), frameworks={ 'coming': get_frameworks_by_status(all_frameworks, 'coming'), 'open': get_frameworks_by_status(all_frameworks, 'open'), 'pending': get_frameworks_by_status(all_frameworks, 'pending'), 'standstill': get_frameworks_by_status(all_frameworks, 'standstill', 'made_application'), 'live': get_frameworks_by_status(all_frameworks, 'live', 'services_count') } )
def duns_number(): form = DunsNumberForm() if form.duns_number.name in session: form.duns_number.data = session[form.duns_number.name] return render_template_with_csrf("suppliers/duns_number.html", form=form), 200
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 compare(old_archived_service_id, new_archived_service_id): def validate_archived_services(old_archived_service, new_archived_service): if old_archived_service.get('id', -1) \ != new_archived_service.get('id', -2): return False old_updated_at = datetime.strptime( old_archived_service.get('updatedAt'), DATETIME_FORMAT) new_updated_at = datetime.strptime( new_archived_service.get('updatedAt'), DATETIME_FORMAT) if old_updated_at >= new_updated_at: return False return True try: service_data_revision_1 = data_api_client.get_archived_service( old_archived_service_id)['services'] service_data_revision_2 = data_api_client.get_archived_service( new_archived_service_id)['services'] # ids exist, ids match, dates are chronological if not validate_archived_services(service_data_revision_1, service_data_revision_2): raise ValueError service_data = data_api_client.get_service( service_data_revision_1['id'])['services'] except (HTTPError, KeyError, ValueError): return abort(404) content = content_loader.get_manifest( 'g-cloud-6', 'edit_service_as_admin').filter(service_data) # It's possible to have an empty array if none of the lines were changed. # TODO This possibility isn't actually handled. service_diffs = get_diffs_from_service_data( sections=content.sections, revision_1=service_data_revision_1, revision_2=service_data_revision_2, include_unchanged_lines_in_output=False) revision_dates = None if not service_diffs else \ get_revision_dates( service_data_revision_1, service_data_revision_2 ) return render_template_with_csrf("compare_revisions.html", diffs=service_diffs, revision_dates=revision_dates, sections=content.sections, service_data=service_data)
def test_render_template_with_csrf(self): with self.flask.app_context(): response, status_code = render_template_with_csrf( 'test_form.html', 123) assert status_code == 123 assert response.cache_control.private assert response.cache_control.max_age == self.flask.config[ 'CSRF_TIME_LIMIT'] assert FakeCsrf.valid_token in response.get_data(as_text=True)
def companies_house_number(): form = CompaniesHouseNumberForm() if form.companies_house_number.name in session: form.companies_house_number.data = session[ form.companies_house_number.name] return render_template_with_csrf("suppliers/companies_house_number.html", form=form)
def edit(service_id, section): service_data = data_api_client.get_service(service_id)['services'] content = content_loader.get_manifest( 'g-cloud-6', 'edit_service_as_admin').filter(service_data) return render_template_with_csrf("edit_section.html", section=content.get_section(section), service_data=service_data)
def companies_house_number(): form = CompaniesHouseNumberForm() if form.companies_house_number.name in session: form.companies_house_number.data = session[form.companies_house_number.name] return render_template_with_csrf( "suppliers/companies_house_number.html", form=form )
def edit(service_id, section): service_data = data_api_client.get_service(service_id)['services'] content = content_loader.get_manifest('g-cloud-6', 'edit_service_as_admin').filter(service_data) return render_template_with_csrf( "edit_section.html", section=content.get_section(section), service_data=service_data )
def find_brief_by_team_id(): team_id = request.args.get('team_id') team_info = data_api_client.req.admin().team(team_id).get() team = team_info.get('team') briefs = team_info.get('briefs') return render_template_with_csrf("view_team.html", team_id=team_id, team=team)
def create_your_account_complete(): if 'email_sent_to' in session: email_address = session['email_sent_to'] else: email_address = "the email address you supplied" session.clear() session['email_sent_to'] = email_address return render_template_with_csrf( "suppliers/create_your_account_complete.html", email_address=email_address)
def duns_number(): form = DunsNumberForm() if form.duns_number.name in session: form.duns_number.data = session[form.duns_number.name] return render_template_with_csrf( "suppliers/duns_number.html", form=form ), 200
def create_your_account(): current_app.logger.info( "suppliercreate: get create-your-account supplier_code:{}".format( session.get('email_supplier_code', 'unknown'))) form = EmailAddressForm() return render_template_with_csrf("suppliers/create_your_account.html", form=form, email_address=session.get( 'account_email_address', ''))
def company_name(): form = CompanyNameForm() if form.company_name.name in session: form.company_name.data = session[form.company_name.name] return render_template_with_csrf( "suppliers/company_name.html", form=form )
def find_supplier_services(): if not request.args.get('supplier_code'): abort(404) supplier_code = int(request.args['supplier_code']) supplier = data_api_client.get_supplier(supplier_code) services = data_api_client.find_services(supplier_code) evidence = data_api_client.req.evidence().all().get( params={'supplier_code': supplier_code})['evidence'] if 'domains' not in supplier['supplier']: domains = {} supplier['supplier']['domains'] = domains else: domains = supplier['supplier']['domains'] assessed = [ sd for sd in domains.get('all', []) if sd['status'] == 'assessed' ] for a in assessed: pricing = supplier['supplier'].get('pricing', None) if pricing: price = pricing.get(a['domain_name'], None) if price: a['price'] = price['maxPrice'] else: a['price'] = 'Not specified' for e in evidence: if 'submitted_at' in e and e['submitted_at']: e['submitted_at'] = pendulum.parse( e['submitted_at']).format('%d-%m-%Y') if 'rejected_at' in e and e['rejected_at']: e['rejected_at'] = pendulum.parse( e['rejected_at']).format('%d-%m-%Y') if 'approved_at' in e and e['approved_at']: e['approved_at'] = pendulum.parse( e['approved_at']).format('%d-%m-%Y') if 'created_at' in e and e['created_at']: e['created_at'] = pendulum.parse( e['created_at']).format('%d-%m-%Y') assessments_draft = [e for e in evidence if e['status'] == 'draft'] assessments_rejected = [e for e in evidence if e['status'] == 'rejected'] assessments_approved = [e for e in evidence if e['status'] == 'assessed'] assessments_submitted = [e for e in evidence if e['status'] == 'submitted'] return render_template_with_csrf( "view_supplier_services.html", services=services["services"], supplier=supplier["supplier"], assessed=assessed, assessments_draft=assessments_draft, assessments_rejected=assessments_rejected, assessments_approved=assessments_approved, assessments_submitted=assessments_submitted)
def signer_details(framework_slug): framework = get_framework(data_api_client, framework_slug) supplier_framework = return_supplier_framework_info_if_on_framework_or_abort( data_api_client, framework_slug) form = SignerDetailsForm(request.form) question_keys = ['signerName', 'signerRole'] form_errors = {} if request.method == 'POST': if form.validate(): agreement_details = { question_key: form[question_key].data for question_key in question_keys } data_api_client.update_supplier_framework_agreement_details( current_user.supplier_code, framework_slug, agreement_details, current_user.email_address) # If they have already uploaded a file then let them go to straight to the contract review # page as they are likely editing their signer details if session.get('signature_page'): return redirect( url_for(".contract_review", framework_slug=framework_slug)) return redirect( url_for(".signature_upload", framework_slug=framework_slug)) else: error_keys_in_order = [ key for key in question_keys if key in form.errors.keys() ] form_errors = [{ 'question': form[key].label.text, 'input_name': key } for key in error_keys_in_order] # if the signer* keys exist, prefill them in the form if supplier_framework['agreementDetails']: for question_key in question_keys: if question_key in supplier_framework['agreementDetails']: form[question_key].data = supplier_framework[ 'agreementDetails'][question_key] status_code = 400 if form_errors else 200 return render_template_with_csrf( "frameworks/signer_details.html", status_code=status_code, form=form, form_errors=form_errors, framework=framework, question_keys=question_keys, supplier_framework=supplier_framework, )
def process_login(): form = auth_forms.LoginForm(request.form) next_url = request.args.get('next') if form.validate(): result = data_api_client.authenticate_user( form.email_address.data, form.password.data) if not result: current_app.logger.info( "login.fail: failed to sign in {email_hash}", extra={'email_hash': hash_email(form.email_address.data)}) flash("no_account", "error") return render_template_with_csrf( "auth/login.html", status_code=403, form=form, next=next_url) user = User.from_json(result) if '_csrf_token' in session: session.pop('_csrf_token') if 'csrf' in session: session.pop('csrf') if current_app.config['REDIS_SESSIONS']: session.regenerate() login_user(user) current_app.logger.info('login.success: {user}', extra={'user': user_logging_string(user)}) check_terms_acceptance() if current_user.role == 'buyer': user = User.load_user(data_api_client, current_user.id) if not user.is_team_member and user.must_join_team: next_url = '/2/team/join' return redirect_logged_in_user(next_url, result.get('validation_result', None)) else: return render_template_with_csrf( "auth/login.html", status_code=400, form=form, next=next_url)
def create_new_work_order(framework_slug, lot_slug, brief_id): brief = data_api_client.get_brief(brief_id)["briefs"] if not is_brief_correct( brief, framework_slug, lot_slug, current_user.id ): abort(404) form = WorkOrderSellerForm(formdata=request.form, data_api_client=data_api_client, brief_id=brief_id) if not form.validate(): return render_template_with_csrf( 'workorder/select-seller.html', status_code=400, brief=brief, form=form ) try: seller = data_api_client.get_supplier(form.seller.data)['supplier'] work_order = data_api_client.create_work_order( briefId=brief_id, supplierCode=form.seller.data, workOrder=_create_work_order_from_brief(brief, seller) )['workOrder'] except APIError as e: form.errors['seller'] = [e.message] return render_template_with_csrf( 'workorder/select-seller.html', status_code=e.status_code, brief=brief, form=form, ) return redirect( url_for( 'buyers.get_work_order', work_order_id=work_order['id'], ) )
def create_your_account(): current_app.logger.info( "suppliercreate: get create-your-account supplier_code:{}".format( session.get('email_supplier_code', 'unknown'))) form = EmailAddressForm() return render_template_with_csrf( "suppliers/create_your_account.html", form=form, email_address=session.get('account_email_address', '') )
def create_your_account_complete(): if 'email_sent_to' in session: email_address = session['email_sent_to'] else: email_address = "the email address you supplied" session.clear() session['email_sent_to'] = email_address return render_template_with_csrf( "suppliers/create_your_account_complete.html", email_address=email_address )
def accept_updated_terms(): form = auth_forms.AcceptUpdatedTerms(request.form) if not form.validate(): return render_template_with_csrf('auth/accept-updated-terms.html', status_code=400, form=form) timestamp = datetime.utcnow().strftime(DATETIME_FORMAT) data_api_client.update_user(current_user.id, fields={'termsAcceptedAt': timestamp}) terms_of_use.set_session_flag(False) return redirect_logged_in_user()
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 select_seller_for_work_order(framework_slug, lot_slug, brief_id): brief = data_api_client.get_brief(brief_id)["briefs"] if not is_brief_correct( brief, framework_slug, lot_slug, current_user.id ): abort(404) form = WorkOrderSellerForm(data_api_client=data_api_client, brief_id=brief_id) return render_template_with_csrf('workorder/select-seller.html', brief=brief, form=form)
def find_suppliers(): if request.args.get('supplier_code'): suppliers = [data_api_client.get_supplier(request.args.get('supplier_code'))['supplier']] else: suppliers = data_api_client.find_suppliers( prefix=request.args.get('supplier_name_prefix'), per_page=1000)['suppliers'] # hard coded to 1000 records, in hope this is enough for admins searching return render_template_with_csrf( "view_suppliers.html", suppliers=suppliers, signed_agreement_prefix=SIGNED_AGREEMENT_PREFIX, agreement_prefix=AGREEMENT_FILENAME )
def send_invite_user(): form = EmailAddressForm(request.form) if form.validate(): token = generate_supplier_invitation_token( name='', supplier_code=current_user.supplier_code, supplier_name=current_user.supplier_name, email_address=form.email_address.data ) url = url_for('main.create_user', token=token, _external=True) email_body = render_template( 'emails/invite_user_email.html', url=url, user=current_user.name, supplier=current_user.supplier_name) try: send_email( form.email_address.data, email_body, current_app.config['INVITE_EMAIL_SUBJECT'], current_app.config['INVITE_EMAIL_FROM'], current_app.config['INVITE_EMAIL_NAME'] ) except EmailError as e: rollbar.report_exc_info() current_app.logger.error( 'Invitation 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, 'Failed to send user invite reset') data_api_client.create_audit_event( audit_type=AuditTypes.invite_user, user=current_user.email_address, object_type='suppliers', object_id=current_user.supplier_code, data={'invitedEmail': form.email_address.data}, ) flash('user_invited', 'success') return redirect(url_for('.list_users')) else: return render_template_with_csrf( 'auth/submit_email_address.html', status_code=400, form=form)
def find_user_by_email_address(): template = "view_users.html" users = None teammembers = None email_address = request.args.get("email_address", None) if email_address: users = data_api_client.get_user(email_address=email_address) # skip calling of teammembers.get when an @ charater is present. # that method only searches the domain field. if users is None and email_address and "@" not in email_address: teammembers = data_api_client.req.teammembers(email_address).get() if teammembers: return render_template_with_csrf( template, search_result=True, teammembers=teammembers ) if users: user, supplier, teammembers, application, briefs = _user_info(email_address) return render_template_with_csrf( template, users=[users['users']], email_address=email_address, user=user, supplier=supplier, teammembers=teammembers, applications=application, briefs=briefs ) else: flash('no_users', 'error') return render_template_with_csrf( template, status_code=404, users=list(), email_address=None )
def get_work_order(work_order_id): try: work_order = data_api_client.get_work_order(work_order_id)['workOrder'] except APIError as e: abort(e.status_code) brief = data_api_client.get_brief(work_order['briefId'])["briefs"] if not is_brief_associated_with_user( brief, current_user.id ): abort(404) return render_template_with_csrf('workorder/work-order-instruction-list.html', work_order=work_order, questions=questions)
def find_supplier_users(): if not request.args.get('supplier_code'): abort(404) supplier = data_api_client.get_supplier(request.args['supplier_code']) users = data_api_client.find_users(request.args.get('supplier_code')) return render_template_with_csrf( "view_supplier_users.html", users=users["users"], invite_form=InviteForm(), move_user_form=MoveUserForm(), supplier=supplier['supplier'] )
def create_new_brief(framework_slug, lot_slug): if lot_slug == 'digital-outcome': abort(404) framework, lot = get_framework_and_lot(framework_slug, lot_slug, data_api_client, status='live', must_allow_brief=True) content = content_loader.get_manifest(framework_slug, 'edit_brief').filter( {'lot': lot['slug']} ) section = content.get_section(content.get_next_editable_section_id()) update_data = section.get_data(request.form) try: brief = data_api_client.create_brief( framework_slug, lot_slug, current_user.id, update_data, updated_by=current_user.email_address, page_questions=section.get_field_names() )["briefs"] except HTTPError as e: update_data = section.unformat_data(update_data) errors = section.get_error_messages(e.message) return render_template_with_csrf( "buyers/create_brief_question.html", status_code=400, data=update_data, brief={}, framework=framework, lot=lot, section=section, question=section.questions[0], errors=errors ) response = __navigate_next(content, brief, lot_slug, section.id) if response: return response return redirect( url_for(".view_brief_overview", framework_slug=framework_slug, lot_slug=lot_slug, brief_id=brief['id']))
def company_contact_details(): form = CompanyContactDetailsForm() if form.email_address.name in session: form.email_address.data = session[form.email_address.name] if form.phone_number.name in session: form.phone_number.data = session[form.phone_number.name] if form.contact_name.name in session: form.contact_name.data = session[form.contact_name.name] return render_template_with_csrf( "suppliers/company_contact_details.html", form=form )
def submit_create_your_account(): current_app.logger.info( "suppliercreate: post create-your-account supplier_code:{}".format( session.get('email_supplier_code', 'unknown'))) form = EmailAddressForm(request.form) if form.validate(): session['account_email_address'] = form.email_address.data return redirect(url_for(".company_summary")) else: return render_template_with_csrf( "suppliers/create_your_account.html", status_code=400, form=form, email_address=form.email_address.data )
def withdraw_brief(brief_id): try: brief = data_api_client.req.briefs(brief_id).withdraw().post({ 'update_details': {'updated_by': current_user.email_address} }).get('briefs') except HTTPError, e: flash(e.message, 'error') brief = data_api_client.get_brief(brief_id).get('briefs') return render_template_with_csrf( 'view_buyers.html', users=brief.get('users'), title=brief.get('title'), brief_id=brief_id, brief=brief )