コード例 #1
0
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', ''))
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
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()
コード例 #5
0
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)
コード例 #6
0
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
    )
コード例 #7
0
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)
コード例 #8
0
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)
コード例 #9
0
 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)
コード例 #10
0
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
    )
コード例 #11
0
def list_users():

    return render_template_with_csrf(
        "users/list_users.html",
        current_user=current_user,
        users=get_current_suppliers_users()
    )
コード例 #12
0
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'])
    )
コード例 #13
0
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)
コード例 #14
0
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
    )
コード例 #15
0
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],
    )
コード例 #16
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)
コード例 #17
0
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', '')
    )
コード例 #18
0
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
    )
コード例 #19
0
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
    )
コード例 #20
0
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']
    )
コード例 #21
0
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))
コード例 #22
0
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']
    )
コード例 #23
0
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))
コード例 #24
0
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)
コード例 #25
0
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')
コード例 #26
0
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')
        }
    )
コード例 #27
0
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
コード例 #28
0
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,
    )
コード例 #29
0
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)
コード例 #30
0
 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)
コード例 #31
0
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)
コード例 #32
0
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)
コード例 #33
0
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
    )
コード例 #34
0
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
    )
コード例 #35
0
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)
コード例 #36
0
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)
コード例 #37
0
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
コード例 #38
0
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', ''))
コード例 #39
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
    )
コード例 #40
0
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)
コード例 #41
0
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,
    )
コード例 #42
0
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)
コード例 #43
0
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'],
        )
    )
コード例 #44
0
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', '')
    )
コード例 #45
0
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
    )
コード例 #46
0
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()
コード例 #47
0
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,
    )
コード例 #48
0
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)
コード例 #49
0
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
    )
コード例 #50
0
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)
コード例 #51
0
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
        )
コード例 #52
0
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)
コード例 #53
0
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']
    )
コード例 #54
0
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']))
コード例 #55
0
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
    )
コード例 #56
0
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
        )
コード例 #57
0
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
        )