def sign_agreement():
    signed_agreement_json = get_json_from_request()
    json_has_required_keys(signed_agreement_json, ['signed_agreement'])

    user_id = signed_agreement_json['signed_agreement']['user_id']

    user = User.query.get(user_id)

    if user.supplier_code != signed_agreement_json['signed_agreement']['supplier_code']:
        abort(400, 'User is not authorized to submit application')

    signed_agreement = SignedAgreement()
    signed_agreement.update_from_json(signed_agreement_json['signed_agreement'])

    db.session.add(signed_agreement)

    try:
        db.session.flush()
    except IntegrityError as e:
        db.session.rollback()
        abort(400, e.orig)

    db.session.commit()

    return jsonify(signed_agreement=signed_agreement.serializable), 201
Пример #2
0
def get_duplicate_users():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["email_address"])
    email_address = json_payload["email_address"]
    domain = email_address.split('@')[-1]

    if domain in current_app.config['GENERIC_EMAIL_DOMAINS']:
        return jsonify(duplicate=None)

    supplier_code = db.session.execute("""
        select distinct(supplier_code) from vuser
        where email_domain = :domain
    """, {'domain': domain}).fetchone()

    if (supplier_code and supplier_code[0]):
        send_existing_seller_notification(email_address, supplier_code[0])
        duplicate_audit_event(email_address, {'supplier_code': supplier_code[0]})
        return jsonify(duplicate={"supplier_code": supplier_code[0]})

    application_id = db.session.execute("""
        select distinct(application_id) from vuser
        where email_domain = :domain
    """, {'domain': domain}).fetchone()

    if (application_id and application_id[0]):
        send_existing_application_notification(email_address, application_id[0])
        duplicate_audit_event(email_address, {'application_id': application_id[0]})
        return jsonify(duplicate={"application_id": application_id[0]})

    return jsonify(duplicate=None)
 def test_json_has_required_keys(self):
     with self.app.app_context():
         sample_json = {"name": "Linus",
                        "favourite_kitten": "all of them"}
         keys = ["name", "favourite_kitten", "gender"]
         with pytest.raises(HTTPException):
             json_has_required_keys(sample_json, keys)
def set_a_declaration(code, framework_slug):
    framework = Framework.query.filter(
        Framework.slug == framework_slug
    ).first_or_404()

    supplier_framework = SupplierFramework.find_by_supplier_and_framework(
        code, framework_slug
    )
    supplier = None
    if supplier_framework is not None:
        status_code = 200 if supplier_framework.declaration else 201
    else:
        supplier = Supplier.query.filter(
            Supplier.code == code
        ).first_or_404()

        supplier_framework = SupplierFramework(
            supplier_code=supplier.code,
            framework_id=framework.id,
            declaration={}
        )
        status_code = 201

    request_data = get_json_from_request()
    updater_json = validate_and_return_updater_request()
    json_has_required_keys(request_data, ['declaration'])

    supplier_framework.declaration = request_data['declaration'] or {}
    db.session.add(supplier_framework)
    db.session.add(
        AuditEvent(
            audit_type=AuditTypes.answer_selection_questions,
            db_object=supplier_framework,
            user=updater_json['updated_by'],
            data={'update': request_data['declaration']})
    )

    try:
        db.session.commit()
        if supplier:
            publish_tasks.supplier.delay(
                publish_tasks.compress_supplier(supplier),
                'set_declaration',
                updated_by=updater_json['updated_by']
            )
    except IntegrityError as e:
        db.session.rollback()
        abort(400, "Database Error: {}".format(e))

    return jsonify(declaration=supplier_framework.declaration), status_code
def get_brief_for_new_work_order(work_order_json):
    json_has_required_keys(work_order_json, ['briefId'])
    brief_id = work_order_json['briefId']

    try:
        brief = Brief.query.get(brief_id)
    except DataError:
        brief = None

    if brief is None:
        abort(400, "Invalid brief ID '{}'".format(brief_id))

    if brief.status != 'closed':
        abort(400, "Brief must be closed")

    return brief
Пример #6
0
def record_supplier_invite():
    json_data = get_json_from_request()
    json_has_required_keys(json_data, ('supplierCode', 'email'))

    supplier_contact = SupplierContact.query.join(Supplier).join(Contact) \
        .filter(Supplier.code == json_data['supplierCode']) \
        .filter(Contact.email == json_data['email']) \
        .first()
    if supplier_contact is None:
        abort(400, 'No matching supplier and contact found')

    log_entry = SupplierUserInviteLog(supplier_id=supplier_contact.supplier_id, contact_id=supplier_contact.contact_id)
    db.session.merge(log_entry)
    db.session.commit()

    return jsonify(message='done')
Пример #7
0
def record_supplier_invite():
    json_data = get_json_from_request()
    json_has_required_keys(json_data, ('supplierCode', 'email'))

    supplier_contact = SupplierContact.query.join(Supplier).join(Contact) \
        .filter(Supplier.code == json_data['supplierCode']) \
        .filter(Contact.email == json_data['email']) \
        .first()
    if supplier_contact is None:
        abort(400, 'No matching supplier and contact found')

    log_entry = SupplierUserInviteLog(supplier_id=supplier_contact.supplier_id, contact_id=supplier_contact.contact_id)
    db.session.merge(log_entry)
    db.session.commit()

    return jsonify(message='done')
Пример #8
0
def auth_user():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["authUsers"])
    json_payload = json_payload["authUsers"]
    validate_user_auth_json_or_400(json_payload)
    email_address = json_payload.get('email_address', None)
    if email_address is None:
        # will remove camel case email address with future api
        email_address = json_payload.get('emailAddress', None)

    user = User.query.options(
        joinedload('supplier'),
        noload('supplier.*'),
        joinedload('application'),
        noload('application.*'),
        noload('*')
    ).filter(
        User.email_address == email_address.lower()
    ).first()

    if user is None or (user.supplier and user.supplier.status == 'deleted'):
        return jsonify(authorization=False), 404
    elif encryption.authenticate_user(json_payload['password'], user) and user.active:
        user.logged_in_at = datetime.utcnow()
        user.failed_login_count = 0
        db.session.add(user)
        db.session.commit()

        validation_result = None
        if user.role == 'supplier':
            messages = supplier_business.get_supplier_messages(user.supplier_code, False)
            validation_result = (
                messages._asdict() if messages else None
            )

        return jsonify(users=user.serialize(), validation_result=validation_result), 200
    else:
        user.failed_login_count += 1
        db.session.add(user)
        db.session.commit()

        return jsonify(authorization=False), 403
Пример #9
0
def auth_user():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["authUsers"])
    json_payload = json_payload["authUsers"]
    validate_user_auth_json_or_400(json_payload)
    email_address = json_payload.get('email_address', None)
    if email_address is None:
        # will remove camel case email address with future api
        email_address = json_payload.get('emailAddress', None)

    user = User.query.options(
        joinedload('supplier'),
        noload('supplier.*'),
        joinedload('application'),
        noload('application.*'),
        noload('*')
    ).filter(
        User.email_address == email_address.lower()
    ).first()

    if user is None or (user.supplier and user.supplier.status == 'deleted'):
        return jsonify(authorization=False), 404
    elif encryption.authenticate_user(json_payload['password'], user) and user.active:
        user.logged_in_at = datetime.utcnow()
        user.failed_login_count = 0
        db.session.add(user)
        db.session.commit()

        validation_result = None
        if user.role == 'supplier':
            messages = supplier_business.get_supplier_messages(user.supplier_code, False)
            validation_result = (
                messages._asdict() if messages else None
            )

        return jsonify(users=user.serialize(), validation_result=validation_result), 200
    else:
        user.failed_login_count += 1
        db.session.add(user)
        db.session.commit()

        return jsonify(authorization=False), 403
Пример #10
0
def set_a_declaration(code, framework_slug):
    framework = Framework.query.filter(
        Framework.slug == framework_slug).first_or_404()

    supplier_framework = SupplierFramework.find_by_supplier_and_framework(
        code, framework_slug)
    supplier = None
    if supplier_framework is not None:
        status_code = 200 if supplier_framework.declaration else 201
    else:
        supplier = Supplier.query.filter(Supplier.code == code).first_or_404()

        supplier_framework = SupplierFramework(supplier_code=supplier.code,
                                               framework_id=framework.id,
                                               declaration={})
        status_code = 201

    request_data = get_json_from_request()
    updater_json = validate_and_return_updater_request()
    json_has_required_keys(request_data, ['declaration'])

    supplier_framework.declaration = request_data['declaration'] or {}
    db.session.add(supplier_framework)
    db.session.add(
        AuditEvent(audit_type=AuditTypes.answer_selection_questions,
                   db_object=supplier_framework,
                   user=updater_json['updated_by'],
                   data={'update': request_data['declaration']}))

    try:
        db.session.commit()
        if supplier:
            publish_tasks.supplier.delay(
                publish_tasks.compress_supplier(supplier),
                'set_declaration',
                updated_by=updater_json['updated_by'])
    except IntegrityError as e:
        db.session.rollback()
        abort(400, "Database Error: {}".format(e))

    return jsonify(declaration=supplier_framework.declaration), status_code
Пример #11
0
def get_duplicate_users():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["email_address"])
    email_address = json_payload["email_address"]
    domain = email_address.split('@')[-1]

    if domain in current_app.config['GENERIC_EMAIL_DOMAINS']:
        return jsonify(duplicate=None)

    supplier_code = db.session.execute(
        """
        select distinct(supplier_code) from vuser
        where email_domain = :domain
    """, {
            'domain': domain
        }).fetchone()

    if (supplier_code and supplier_code[0]):
        send_existing_seller_notification(email_address, supplier_code[0])
        duplicate_audit_event(email_address,
                              {'supplier_code': supplier_code[0]})
        return jsonify(duplicate={"supplier_code": supplier_code[0]})

    application_id = db.session.execute(
        """
        select distinct(application_id) from vuser
        where email_domain = :domain
    """, {
            'domain': domain
        }).fetchone()

    if (application_id and application_id[0]):
        send_existing_application_notification(email_address,
                                               application_id[0])
        duplicate_audit_event(email_address,
                              {'application_id': application_id[0]})
        return jsonify(duplicate={"application_id": application_id[0]})

    return jsonify(duplicate=None)
def get_work_order_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['workOrder'])
    return json_payload['workOrder']
Пример #13
0
def submit_application(application_id):
    current_time = pendulum.now('UTC').to_iso8601_string(extended=True)

    application = Application.query.get(application_id)
    if application is None:
        abort(404, "Application '{}' does not exist".format(application_id))

    if application.status == 'submitted':
        abort(400, 'Application is already submitted')

    errors = ApplicationValidator(application).validate_all()
    if errors:
        abort(400, 'Application has errors')

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['user_id'])
    user_id = json_payload['user_id']

    user = User.query.get(user_id)

    if application.type != 'edit':
        if user.application_id != application.id:
            abort(400, 'User is not authorized to submit application')
    else:
        if user.supplier_code != application.supplier_code:
            abort(
                400,
                'User supplier code does not match application supplier code')

    agreement = get_current_agreement()
    if agreement is None:
        abort(404, 'Current master agreement not found')

    db.session.add(
        AuditEvent(audit_type=AuditTypes.submit_application,
                   user=user_id,
                   data={},
                   db_object=application))

    application.submit_for_approval()

    application.update_from_json({'submitted_at': current_time})

    signed_agreement = None
    if application.type != 'edit':
        # only create signed agreements on initial applications
        signed_agreement = SignedAgreement()
        signed_agreement.user_id = user_id
        signed_agreement.agreement_id = agreement.id
        signed_agreement.signed_at = current_time
        signed_agreement.application_id = application_id

        db.session.add(signed_agreement)

        if application.supplier_code:
            send_submitted_existing_seller_notification(application.id)
        else:
            send_submitted_new_seller_notification(application.id)

    db.session.commit()
    publish_tasks.application.delay(
        publish_tasks.compress_application(application), 'submitted')
    return jsonify(application=application.serializable,
                   signed_agreement=signed_agreement)
Пример #14
0
def get_application_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['application'])
    return json_payload['application']
Пример #15
0
 def test_json_has_required_keys(self):
     sample_json = {"name": "Linus", "favourite_kitten": "all of them"}
     keys = ["name", "favourite_kitten", "gender"]
     with pytest.raises(HTTPException):
         json_has_required_keys(sample_json, keys)
Пример #16
0
def update_supplier_framework_details(code, framework_slug):

    framework = Framework.query.filter(
        Framework.slug == framework_slug).first_or_404()

    supplier = Supplier.query.filter(Supplier.code == code).first_or_404()

    json_payload = get_json_from_request()
    updater_json = validate_and_return_updater_request()
    json_has_required_keys(json_payload, ["frameworkInterest"])
    update_json = json_payload["frameworkInterest"]

    interest_record = SupplierFramework.query.filter(
        SupplierFramework.supplier_code == supplier.code,
        SupplierFramework.framework_id == framework.id).first()

    if not interest_record:
        abort(
            404, "code '{}' has not registered interest in {}".format(
                code, framework_slug))

    # `agreementDetails` shouldn't be passed in unless the framework has framework_agreement_details
    if 'agreementDetails' in update_json and framework.framework_agreement_details is None:
        abort(
            400, "Framework '{}' does not accept 'agreementDetails'".format(
                framework_slug))

    if ((framework.framework_agreement_details and
         framework.framework_agreement_details.get('frameworkAgreementVersion')
         ) and  # noqa
        ('agreementDetails' in update_json
         or update_json.get('agreementReturned'))):
        required_fields = ['signerName', 'signerRole']
        if update_json.get('agreementReturned'):
            required_fields.append('uploaderUserId')

        # Make a copy of the existing agreement_details with our new changes to be added and validate this
        # If invalid, 400
        agreement_details = interest_record.agreement_details.copy(
        ) if interest_record.agreement_details else {}

        if update_json.get('agreementDetails'):
            agreement_details.update(update_json['agreementDetails'])
        if update_json.get('agreementReturned'):
            agreement_details[
                'frameworkAgreementVersion'] = framework.framework_agreement_details[
                    'frameworkAgreementVersion']  # noqa

        validate_agreement_details_data(agreement_details,
                                        enforce_required=False,
                                        required_fields=required_fields)

        if update_json.get('agreementDetails') and update_json[
                'agreementDetails'].get('uploaderUserId'):
            user = User.query.filter(User.id == update_json['agreementDetails']
                                     ['uploaderUserId']).first()
            if not user:
                abort(
                    400, "No user found with id '{}'".format(
                        update_json['agreementDetails']['uploaderUserId']))

        interest_record.agreement_details = agreement_details or None

    uniform_now = datetime.utcnow()

    if 'onFramework' in update_json:
        interest_record.on_framework = update_json['onFramework']
    if 'agreementReturned' in update_json:
        if update_json["agreementReturned"] is False:
            interest_record.agreement_returned_at = None
            interest_record.agreement_details = None
        else:
            interest_record.agreement_returned_at = uniform_now
    if update_json.get('countersigned'):
        interest_record.countersigned_at = uniform_now

    audit_event = AuditEvent(audit_type=AuditTypes.supplier_update,
                             user=updater_json['updated_by'],
                             data={
                                 'supplierId': supplier.code,
                                 'frameworkSlug': framework_slug,
                                 'update': update_json
                             },
                             db_object=supplier)

    try:
        db.session.add(interest_record)
        db.session.add(audit_event)
        db.session.commit()
    except IntegrityError as e:
        db.session.rollback()
        return jsonify(message="Database Error: {0}".format(e)), 400

    return jsonify(frameworkInterest=interest_record.serialize()), 200
def create_assessment():
    updater_json = validate_and_return_updater_request()
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['assessment'])
    data = json_payload['assessment']
    json_has_required_keys(data, ['supplier_code'])
    json_has_required_keys(data, ['domain_name'])
    supplier_code = data['supplier_code']
    updated_by = updater_json['updated_by']

    existing_assessment = db.session.query(
        Assessment
    ).join(
        SupplierDomain, Supplier, Domain
    ).filter(
        Supplier.code == supplier_code,
        Domain.name == data['domain_name'],
        Assessment.active
    ).first()

    if existing_assessment:
        send_assessment_requested_notification(existing_assessment, updated_by)
        publish_tasks.assessment.delay(
            publish_tasks.compress_assessment(existing_assessment),
            'existing',
            updated_by=updated_by
        )

        return jsonify(assessment=existing_assessment.serializable), 201

    assessment = Assessment()
    assessment.update_from_json(json_payload['assessment'])
    db.session.add(assessment)

    try:
        db.session.commit()
    except IntegrityError:
        abort(400)

    db.session.add(AuditEvent(
        audit_type=AuditTypes.create_assessment,
        user=updated_by,
        data={},
        db_object=assessment
    ))

    if current_app.config['JIRA_FEATURES']:
        application = db.session.query(Application).filter(
            Application.supplier_code == supplier_code,
            Application.type == 'edit',
            Application.status == 'submitted'
        ).one_or_none()

        mj = get_marketplace_jira()
        mj.create_domain_approval_task(assessment, application)

    send_assessment_requested_notification(assessment, updater_json['updated_by'])

    publish_tasks.assessment.delay(
        publish_tasks.compress_assessment(assessment),
        'created',
        updated_by=updated_by
    )

    return jsonify(assessment=assessment.serializable), 201
Пример #18
0
def update_user(user_id):
    """
        Update a user. Looks user up in DB, and updates where necessary.
    """
    update_details = validate_and_return_updater_request()

    user = User.query.options(
        noload('*')
    ).filter(
        User.id == user_id
    ).first_or_404()

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["users"])
    user_update = json_payload["users"]

    json_has_matching_id(user_update, user_id)
    existing_user = publish_tasks.compress_user(user)

    if 'password' in user_update:
        user.password = encryption.hashpw(user_update['password'])
        user.password_changed_at = datetime.utcnow()
        user_update['password'] = '******'
    if 'active' in user_update:
        user.active = user_update['active']
    if 'name' in user_update:
        user.name = user_update['name']
    if 'emailAddress' in user_update:
        user.email_address = user_update['emailAddress']
    if 'role' in user_update:
        if user.role == 'supplier' and user_update['role'] != user.role:
            user.supplier_code = None
            user_update.pop('supplierCode', None)
        user.role = user_update['role']
    if 'supplierCode' in user_update:
        user.supplier_code = user_update['supplierCode']
    if 'application_id' in user_update:
        user.application_id = user_update['application_id']
    if 'locked' in user_update and not user_update['locked']:
        user.failed_login_count = 0
    if 'termsAcceptedAt' in user_update:
        user.terms_accepted_at = user_update['termsAcceptedAt']

    check_supplier_role(user.role, user.supplier_code)

    audit = AuditEvent(
        audit_type=AuditTypes.update_user,
        user=update_details.get('updated_by', 'no user data'),
        data={
            'user': user.email_address,
            'update': user_update
        },
        db_object=user
    )

    db.session.add(user)
    db.session.add(audit)

    publish_tasks.user.delay(
        publish_tasks.compress_user(user),
        'updated',
        old_user=existing_user
    )

    try:
        db.session.commit()
        return jsonify(users=user.serialize()), 200
    except (IntegrityError, DataError):
        db.session.rollback()
        abort(400, "Could not update user with: {0}".format(user_update))
Пример #19
0
def create_user():

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["users"])
    json_payload = json_payload["users"]
    validate_user_json_or_400(json_payload)
    email_address = json_payload.get('email_address', None)
    if email_address is None:
        email_address = json_payload.get('emailAddress', None)

    user = User.query.filter(
        User.email_address == email_address.lower()).first()

    if user:
        abort(409, "User already exists")

    if 'hashpw' in json_payload and not json_payload['hashpw']:
        password = json_payload['password']
    else:
        password = encryption.hashpw(json_payload['password'])

    now = datetime.utcnow()
    user = User(email_address=email_address.lower(),
                phone_number=json_payload.get('phoneNumber') or None,
                name=json_payload['name'],
                role=json_payload['role'],
                password=password,
                active=True,
                created_at=now,
                updated_at=now,
                password_changed_at=now)

    audit_data = {}

    if "supplierCode" in json_payload:
        user.supplier_code = json_payload['supplierCode']
        audit_data['supplier_code'] = user.supplier_code

    check_supplier_role(user.role, user.supplier_code)

    if "application_id" in json_payload:
        user.application_id = json_payload['application_id']
    elif user.supplier_code is not None:
        appl = Application.query.filter_by(
            supplier_code=user.supplier_code).first()
        user.application_id = appl and appl.id or None

    check_applicant_role(user.role, user.application_id)

    try:
        db.session.add(user)
        db.session.flush()

        audit = AuditEvent(audit_type=AuditTypes.create_user,
                           user=email_address.lower(),
                           data=audit_data,
                           db_object=user)

        db.session.add(audit)
        db.session.commit()

        user = db.session.query(User).options(
            noload('*')).filter(User.id == user.id).one_or_none()
        publish_tasks.user.delay(publish_tasks.compress_user(user), 'created')

        if user.role == 'buyer':
            notification_message = 'Domain: {}'.format(
                email_address.split('@')[-1])

            notification_text = 'A new buyer has signed up'
            notify_team(notification_text, notification_message)

    except IntegrityError:
        db.session.rollback()
        abort(400, "Invalid supplier code or application id")
    except DataError:
        db.session.rollback()
        abort(400, "Invalid user role")

    return jsonify(users=user.serialize()), 201
def get_application_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['application'])
    return json_payload['application']
Пример #21
0
def create_application_from_supplier(code, application_type=None):
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["current_user"])
    current_user = json_payload["current_user"]

    supplier = Supplier.query.options(
        joinedload('domains'),
        joinedload('domains.assessments'),
        joinedload('domains.domain'),
        joinedload('domains.recruiter_info'),
        noload('domains.supplier'),
        noload('domains.assessments.briefs')
    ).filter(
        Supplier.code == code
    ).first_or_404()

    # hotfix for exception. shouldn't need to do this
    supplier.data = supplier.data or {}
    application_type = application_type or 'upgrade'
    existing_application = Application.query.options(
        joinedload('supplier')
    ).filter(
        Application.supplier_code == supplier.code,
        or_(Application.status == 'submitted', Application.status == 'saved')
    ).first()
    if existing_application:
        errors = ApplicationValidator(existing_application).validate_all()
        return jsonify(application=existing_application.serializable,
                       application_errors=errors)

    data = json.loads(supplier.json)

    data['status'] = 'saved'
    data = {key: data[key] for key in data if key not in ['id', 'contacts', 'domains', 'links',
                                                          'prices', 'frameworks', 'steps', 'signed_agreements']}
    if data.get('products'):
        for product in data['products']:
            if product.get('links'):
                del product['links']
    application = Application()
    application.update_from_json(data)
    application.type = application_type

    db.session.add(application)
    db.session.flush()

    audit_type = application_type == 'edit' and AuditTypes.supplier_update or AuditTypes.create_application
    db.session.add(AuditEvent(
        audit_type=audit_type,
        user='',
        data={},
        db_object=application
    ))
    db.session.flush()

    if application_type != 'edit':
        notification_message = '{}\nApplication Id:{}\nBy: {} ({})'.format(
            data['name'],
            application.id,
            current_user['name'],
            current_user['email_address']
        )

        notification_text = 'An existing seller has started a new application'

        notify_team(notification_text, notification_message)

    # TODO stop using application_id on user
    supplier.update_from_json({'application_id': application.id})
    users = User.query.options(
        noload('supplier'),
        noload('application')
    ).filter(
        User.supplier_code == code and User.active == true()
    ).all()

    for user in users:
        user.application_id = application.id

    db.session.commit()

    publish_tasks.application.delay(
        publish_tasks.compress_application(application),
        'created',
        name=current_user['name'],
        email_address=current_user['email_address'],
        from_expired=False
    )
    return jsonify(application=application)
Пример #22
0
def update_supplier_framework_details(code, framework_slug):

    framework = Framework.query.filter(
        Framework.slug == framework_slug
    ).first_or_404()

    supplier = Supplier.query.filter(
        Supplier.code == code
    ).first_or_404()

    json_payload = get_json_from_request()
    updater_json = validate_and_return_updater_request()
    json_has_required_keys(json_payload, ["frameworkInterest"])
    update_json = json_payload["frameworkInterest"]

    interest_record = SupplierFramework.query.filter(
        SupplierFramework.supplier_code == supplier.code,
        SupplierFramework.framework_id == framework.id
    ).first()

    if not interest_record:
        abort(404, "code '{}' has not registered interest in {}".format(code, framework_slug))

    # `agreementDetails` shouldn't be passed in unless the framework has framework_agreement_details
    if 'agreementDetails' in update_json and framework.framework_agreement_details is None:
        abort(400, "Framework '{}' does not accept 'agreementDetails'".format(framework_slug))

    if (
            (framework.framework_agreement_details and framework.framework_agreement_details.get('frameworkAgreementVersion')) and  # noqa
            ('agreementDetails' in update_json or update_json.get('agreementReturned'))
    ):
        required_fields = ['signerName', 'signerRole']
        if update_json.get('agreementReturned'):
            required_fields.append('uploaderUserId')

        # Make a copy of the existing agreement_details with our new changes to be added and validate this
        # If invalid, 400
        agreement_details = interest_record.agreement_details.copy() if interest_record.agreement_details else {}

        if update_json.get('agreementDetails'):
            agreement_details.update(update_json['agreementDetails'])
        if update_json.get('agreementReturned'):
            agreement_details['frameworkAgreementVersion'] = framework.framework_agreement_details['frameworkAgreementVersion']  # noqa

        validate_agreement_details_data(
            agreement_details,
            enforce_required=False,
            required_fields=required_fields
        )

        if update_json.get('agreementDetails') and update_json['agreementDetails'].get('uploaderUserId'):
            user = User.query.filter(User.id == update_json['agreementDetails']['uploaderUserId']).first()
            if not user:
                abort(400, "No user found with id '{}'".format(update_json['agreementDetails']['uploaderUserId']))

        interest_record.agreement_details = agreement_details or None

    uniform_now = datetime.utcnow()

    if 'onFramework' in update_json:
        interest_record.on_framework = update_json['onFramework']
    if 'agreementReturned' in update_json:
        if update_json["agreementReturned"] is False:
            interest_record.agreement_returned_at = None
            interest_record.agreement_details = None
        else:
            interest_record.agreement_returned_at = uniform_now
    if update_json.get('countersigned'):
        interest_record.countersigned_at = uniform_now

    audit_event = AuditEvent(
        audit_type=AuditTypes.supplier_update,
        user=updater_json['updated_by'],
        data={'supplierId': supplier.code, 'frameworkSlug': framework_slug, 'update': update_json},
        db_object=supplier
    )

    try:
        db.session.add(interest_record)
        db.session.add(audit_event)
        db.session.commit()
    except IntegrityError as e:
        db.session.rollback()
        return jsonify(message="Database Error: {0}".format(e)), 400

    return jsonify(frameworkInterest=interest_record.serialize()), 200
Пример #23
0
def get_project_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['project'])
    return json_payload['project']
Пример #24
0
def get_case_study_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['caseStudy'])
    return json_payload['caseStudy']
Пример #25
0
def update_user(user_id):
    """
        Update a user. Looks user up in DB, and updates where necessary.
    """
    update_details = validate_and_return_updater_request()

    user = User.query.options(
        noload('*')).filter(User.id == user_id).first_or_404()

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["users"])
    user_update = json_payload["users"]

    json_has_matching_id(user_update, user_id)
    existing_user = publish_tasks.compress_user(user)

    if 'password' in user_update:
        user.password = encryption.hashpw(user_update['password'])
        user.password_changed_at = datetime.utcnow()
        user_update['password'] = '******'
    if 'active' in user_update:
        user.active = user_update['active']
    if 'name' in user_update:
        user.name = user_update['name']
    if 'emailAddress' in user_update:
        user.email_address = user_update['emailAddress']
    if 'role' in user_update:
        if user.role == 'supplier' and user_update['role'] != user.role:
            user.supplier_code = None
            user_update.pop('supplierCode', None)
        user.role = user_update['role']
    if 'supplierCode' in user_update:
        user.supplier_code = user_update['supplierCode']
    if 'application_id' in user_update:
        user.application_id = user_update['application_id']
    if 'locked' in user_update and not user_update['locked']:
        user.failed_login_count = 0
    if 'termsAcceptedAt' in user_update:
        user.terms_accepted_at = user_update['termsAcceptedAt']

    check_supplier_role(user.role, user.supplier_code)

    audit = AuditEvent(audit_type=AuditTypes.update_user,
                       user=update_details.get('updated_by', 'no user data'),
                       data={
                           'user': user.email_address,
                           'update': user_update
                       },
                       db_object=user)

    db.session.add(user)
    db.session.add(audit)

    publish_tasks.user.delay(publish_tasks.compress_user(user),
                             'updated',
                             old_user=existing_user)

    try:
        db.session.commit()
        return jsonify(users=user.serialize()), 200
    except (IntegrityError, DataError):
        db.session.rollback()
        abort(400, "Could not update user with: {0}".format(user_update))
def get_case_study_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['caseStudy'])
    return json_payload['caseStudy']
Пример #27
0
def create_user():

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["users"])
    json_payload = json_payload["users"]
    validate_user_json_or_400(json_payload)
    email_address = json_payload.get('email_address', None)
    if email_address is None:
        email_address = json_payload.get('emailAddress', None)

    user = User.query.filter(
        User.email_address == email_address.lower()).first()

    if user:
        abort(409, "User already exists")

    if 'hashpw' in json_payload and not json_payload['hashpw']:
        password = json_payload['password']
    else:
        password = encryption.hashpw(json_payload['password'])

    now = datetime.utcnow()
    user = User(
        email_address=email_address.lower(),
        phone_number=json_payload.get('phoneNumber') or None,
        name=json_payload['name'],
        role=json_payload['role'],
        password=password,
        active=True,
        created_at=now,
        updated_at=now,
        password_changed_at=now
    )

    audit_data = {}

    if "supplierCode" in json_payload:
        user.supplier_code = json_payload['supplierCode']
        audit_data['supplier_code'] = user.supplier_code

    check_supplier_role(user.role, user.supplier_code)

    if "application_id" in json_payload:
        user.application_id = json_payload['application_id']
    elif user.supplier_code is not None:
        appl = Application.query.filter_by(supplier_code=user.supplier_code).first()
        user.application_id = appl and appl.id or None

    check_applicant_role(user.role, user.application_id)

    try:
        db.session.add(user)
        db.session.flush()

        audit = AuditEvent(
            audit_type=AuditTypes.create_user,
            user=email_address.lower(),
            data=audit_data,
            db_object=user
        )

        db.session.add(audit)
        db.session.commit()

        user = db.session.query(User).options(noload('*')).filter(User.id == user.id).one_or_none()
        publish_tasks.user.delay(
            publish_tasks.compress_user(user),
            'created'
        )

        if user.role == 'buyer':
            notification_message = 'Domain: {}'.format(
                email_address.split('@')[-1]
            )

            notification_text = 'A new buyer has signed up'
            notify_team(notification_text, notification_message)

    except IntegrityError:
        db.session.rollback()
        abort(400, "Invalid supplier code or application id")
    except DataError:
        db.session.rollback()
        abort(400, "Invalid user role")

    return jsonify(users=user.serialize()), 201
def submit_application(application_id):
    current_time = pendulum.now('UTC').to_iso8601_string(extended=True)

    application = Application.query.get(application_id)
    if application is None:
        abort(404, "Application '{}' does not exist".format(application_id))

    if application.status == 'submitted':
        abort(400, 'Application is already submitted')

    errors = ApplicationValidator(application).validate_all()
    if errors:
        abort(400, 'Application has errors')

    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['user_id'])
    user_id = json_payload['user_id']

    user = User.query.get(user_id)

    if application.type != 'edit':
        if user.application_id != application.id:
            abort(400, 'User is not authorized to submit application')
    else:
        if user.supplier_code != application.supplier_code:
            abort(400, 'User supplier code does not match application supplier code')

    current_agreement = Agreement.query.filter(
        Agreement.is_current == true()
    ).first_or_404()

    db.session.add(AuditEvent(
        audit_type=AuditTypes.submit_application,
        user=user_id,
        data={},
        db_object=application
    ))

    application.submit_for_approval()

    application.update_from_json({'submitted_at': current_time})

    signed_agreement = None
    if application.type != 'edit':
        # only create signed agreements on initial applications
        signed_agreement = SignedAgreement()
        signed_agreement.user_id = user_id
        signed_agreement.agreement_id = current_agreement.id
        signed_agreement.signed_at = current_time
        signed_agreement.application_id = application_id

        db.session.add(signed_agreement)

        if application.supplier_code:
            send_submitted_existing_seller_notification(application.id)
        else:
            send_submitted_new_seller_notification(application.id)

    db.session.commit()
    publish_tasks.application.delay(
        publish_tasks.compress_application(application),
        'submitted'
    )
    return jsonify(application=application.serializable,
                   signed_agreement=signed_agreement)
Пример #29
0
def create_application_from_supplier(code, application_type=None):
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ["current_user"])
    current_user = json_payload["current_user"]

    supplier = Supplier.query.options(
        joinedload('domains'), joinedload('domains.assessments'),
        joinedload('domains.domain'), joinedload('domains.recruiter_info'),
        noload('domains.supplier'),
        noload('domains.assessments.briefs')).filter(
            Supplier.code == code).first_or_404()

    # hotfix for exception. shouldn't need to do this
    supplier.data = supplier.data or {}
    application_type = application_type or 'upgrade'
    existing_application = Application.query.options(
        joinedload('supplier')).filter(
            Application.supplier_code == supplier.code,
            or_(Application.status == 'submitted',
                Application.status == 'saved')).first()
    if existing_application:
        errors = ApplicationValidator(existing_application).validate_all()
        return jsonify(application=existing_application.serializable,
                       application_errors=errors)

    data = json.loads(supplier.json)

    data['status'] = 'saved'
    data = {
        key: data[key]
        for key in data if key not in [
            'id', 'contacts', 'domains', 'links', 'prices', 'frameworks',
            'steps', 'signed_agreements'
        ]
    }
    if data.get('products'):
        for product in data['products']:
            if product.get('links'):
                del product['links']
    application = Application()
    application.update_from_json(data)
    application.type = application_type

    db.session.add(application)
    db.session.flush()

    audit_type = application_type == 'edit' and AuditTypes.supplier_update or AuditTypes.create_application
    db.session.add(
        AuditEvent(audit_type=audit_type,
                   user='',
                   data={},
                   db_object=application))
    db.session.flush()

    if application_type != 'edit':
        notification_message = '{}\nApplication Id:{}\nBy: {} ({})'.format(
            data['name'], application.id, current_user['name'],
            current_user['email_address'])

        notification_text = 'An existing seller has started a new application'

        notify_team(notification_text, notification_message)

    # TODO stop using application_id on user
    supplier.update_from_json({'application_id': application.id})
    users = User.query.options(noload('supplier'),
                               noload('application')).filter(
                                   User.supplier_code == code
                                   and User.active == true()).all()

    for user in users:
        user.application_id = application.id

    db.session.commit()

    publish_tasks.application.delay(
        publish_tasks.compress_application(application),
        'created',
        name=current_user['name'],
        email_address=current_user['email_address'],
        from_expired=False)
    return jsonify(application=application)