Beispiel #1
0
def delete_evidence_draft(evidence_id):
    json_payload = get_json_from_request()
    actioned_by = json_payload.get('actioned_by', None)
    deleted = delete_draft_evidence(evidence_id, actioned_by)
    if not deleted:
        abort(400, 'Evidence is not valid or not in a draft state')
    return jsonify(message="done"), 200
def notify_callback():
    notify_data = get_json_from_request()

    if notify_data['status'] == 'permanent-failure':
        user = User.query.filter(
            User.email_address == notify_data['to']
        ).first()

        if user and user.active:
            user.active = False
            db.session.add(user)

            audit_event = AuditEvent(
                audit_type=AuditTypes.update_user,
                user='******',
                data={"user": {"active": False}, "notify_callback_data": notify_data},
                db_object=user,
            )
            db.session.add(audit_event)

            db.session.commit()

            current_app.logger.info(
                "User account disabled for {hashed_email} after Notify reported permanent delivery "
                "failure.".format(hashed_email=hash_string(notify_data['to']))
            )

    elif notify_data['status'] == 'technical-failure':
        current_app.logger.warning("Notify failed to deliver {reference} to {hashed_email}".format(
            reference=notify_data['reference'],
            hashed_email=hash_string(notify_data['to']),
        ))

    return jsonify(status='ok'), 200
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
Beispiel #4
0
def reset_password():
    json_payload = get_json_from_request()
    email_address = json_payload.get('email_address', None)
    if not email_address:
        abort(400, "Must supply the email address of the account to reset")
    user = user_service.get_by_email(email_address.lower())
    if not user:
        abort(404, "User not found")
    user_data = {'user_id': user.id}
    claim = user_claims_service.make_claim(type='password_reset',
                                           email_address=email_address,
                                           data=user_data)
    if not claim:
        abort(500, "There was an issue completing the password reset process.")
    result = {'token': claim.token, 'email_address': email_address}

    try:
        audit = AuditEvent(audit_type=AuditTypes.update_user,
                           user=email_address.lower(),
                           data={},
                           db_object=user)

        db.session.add(audit)
        db.session.commit()
    except Exception:
        pass

    return jsonify(result)
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 create_application():
    application_json = get_application_json()
    json_payload = get_json_from_request()
    application = Application()
    application.update_from_json(application_json)

    save_application(application)
    name = json_payload.get('name')
    updated_by = json_payload.get('updated_by')
    db.session.add(AuditEvent(
        audit_type=AuditTypes.create_application,
        user=updated_by,
        data={},
        db_object=application
    ))
    db.session.commit()
    publish_tasks.application.delay(
        publish_tasks.compress_application(application),
        'created',
        name=name,
        email_address=updated_by,
        from_expired=True
    )

    return jsonify(application=application.serializable), 201
Beispiel #7
0
def reset_password(token):
    json_payload = get_json_from_request()

    required_keys = ['password', 'confirmPassword', 'email_address', 'user_id']

    if not set(required_keys).issubset(json_payload):
        return jsonify(
            message='One or more required args were missing from the request'
        ), 400

    if json_payload['password'] != json_payload['confirmPassword']:
        return jsonify(message="Passwords do not match"), 400

    data = decode_reset_password_token(token.encode())

    if data.get('error', None) is not None:
        return jsonify(
            message="An error occured decoding the reset password token"), 400

    try:
        update_user_details(password=json_payload['password'],
                            user_id=json_payload['user_id'])

        return jsonify(
            message="User with email {}, successfully updated their password".
            format(json_payload['email_address']),
            email_address=json_payload['email_address']), 200

    except Exception as error:
        return jsonify(message=error.message), 400
Beispiel #8
0
def send_reset_password_email(framework_slug):
    json_payload = get_json_from_request()
    email_address = json_payload.get('email_address', None)
    if email_address is None:
        return jsonify(
            message='One or more required args were missing from the request'
        ), 400
    user = User.query.filter(User.email_address == email_address).first()

    if user is None:
        return jsonify(email_address=email_address), 200

    app_root_url = get_root_url(framework_slug)

    try:
        reset_password_token = generate_reset_password_token(
            email_address, user.id)

        reset_password_url = '{}{}/reset-password/{}'.format(
            current_app.config['FRONTEND_ADDRESS'], app_root_url,
            quote(reset_password_token))

        send_reset_password_confirm_email(email_address=email_address,
                                          url=reset_password_url,
                                          locked=user.locked,
                                          framework=framework_slug)

    except Exception as error:
        return jsonify(message=error.message), 400

    return jsonify(email_address=email_address,
                   token=reset_password_token), 200
def create_application():
    application_json = get_application_json()
    json_payload = get_json_from_request()
    application = Application()
    application.update_from_json(application_json)

    save_application(application)
    name = json_payload.get('name')
    updated_by = json_payload.get('updated_by')
    db.session.add(AuditEvent(
        audit_type=AuditTypes.create_application,
        user=updated_by,
        data={},
        db_object=application
    ))
    db.session.commit()
    publish_tasks.application.delay(
        publish_tasks.compress_application(application),
        'created',
        name=name,
        email_address=updated_by,
        from_expired=True
    )

    return jsonify(application=application.serializable), 201
Beispiel #10
0
def update(code):
    """Update a supplier (role=buyer,supplier)
    ---
    tags:
      - suppliers
    security:
      - basicAuth: []
    parameters:
      - name: code
        in: path
        type: integer
        required: true
        default: all
    responses:
      200:
        description: A supplier
        type: object
        schema:
          $ref: '#/definitions/Supplier'
    """
    try:
        json_payload = get_json_from_request()
        supplier = update_supplier(code, **json_payload)

        return jsonify(supplier.serializable), 200

    except Exception as error:
        return jsonify(message=error.message), 400
Beispiel #11
0
def create_supplier():
    request_data = get_json_from_request()
    if 'supplier' in request_data:
        supplier_data = request_data.get('supplier')
    else:
        abort(400)

    supplier = Supplier()
    return update_supplier_data_impl(supplier, supplier_data, 201)
def create_supplier():
    request_data = get_json_from_request()
    if 'supplier' in request_data:
        supplier_data = request_data.get('supplier')
    else:
        abort(400)

    supplier = Supplier()
    return update_supplier_data_impl(supplier, supplier_data, 201)
def notify_callback():
    notify_data = get_json_from_request()

    email_address = notify_data["to"]
    hashed_email = hash_string(email_address)
    reference = notify_data["reference"]
    status = notify_data["status"]

    # remove PII from response for logging
    # according to docs only "to" has PII
    # https://docs.notifications.service.gov.uk/rest-api.html#delivery-receipts
    clean_notify_data = notify_data.copy()
    del clean_notify_data["to"]

    current_app.logger.info(
        f"Notify callback: {status}: {reference} to {hashed_email}",
        extra={"notify_delivery_receipt": clean_notify_data},
    )

    if status == "permanent-failure":
        user = User.query.filter(User.email_address == email_address).first()

        if user and user.active:
            user.active = False
            db.session.add(user)

            audit_event = AuditEvent(
                audit_type=AuditTypes.update_user,
                user='******',
                data={
                    "user": {
                        "active": False
                    },
                    "notify_callback_data": notify_data
                },
                db_object=user,
            )
            db.session.add(audit_event)

            db.session.commit()

            current_app.logger.info(
                f"User account disabled for {hashed_email} after Notify reported permanent delivery "
                "failure.")

    elif status.endswith("failure"):
        current_app.logger.warning(
            f"Notify failed to deliver {reference} to {hashed_email}")

    return jsonify(status='ok'), 200
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
Beispiel #15
0
def update_supplier(code):
    request_data = get_json_from_request()
    if 'supplier' in request_data:
        supplier_data = request_data.get('supplier')
    else:
        abort(400)

    if request.method == 'POST':
        supplier = Supplier(code=code)
    else:
        assert request.method == 'PATCH'
        supplier = Supplier.query.filter(Supplier.code == code).first_or_404()

    return update_supplier_data_impl(supplier, supplier_data, 200)
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')
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')
def update_supplier(code):
    request_data = get_json_from_request()
    if 'supplier' in request_data:
        supplier_data = request_data.get('supplier')
    else:
        abort(400)

    if request.method == 'POST':
        supplier = Supplier(code=code)
    else:
        assert request.method == 'PATCH'
        supplier = Supplier.query.filter(
            Supplier.code == code
        ).first_or_404()

    return update_supplier_data_impl(supplier, supplier_data, 200)
def register_framework_interest(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_payload.pop('updated_by')
    if json_payload:
        abort(400, "This PUT endpoint does not take a payload.")

    interest_record = SupplierFramework.query.filter(
        SupplierFramework.supplier_code == supplier.code,
        SupplierFramework.framework_id == framework.id
    ).first()
    if interest_record:
        return jsonify(frameworkInterest=interest_record.serialize()), 200

    if framework.status != 'open':
        abort(400, "'{}' framework is not open".format(framework_slug))

    interest_record = SupplierFramework(
        supplier_code=supplier.code,
        framework_id=framework.id,
        declaration={}
    )
    audit_event = AuditEvent(
        audit_type=AuditTypes.register_framework_interest,
        user=updater_json['updated_by'],
        data={'supplierId': supplier.code, 'frameworkSlug': framework_slug},
        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()), 201
Beispiel #20
0
def reset_password(token):
    email_address_encoded = request.args.get('e') or ''
    if not email_address_encoded:
        return jsonify(message='You must provide an email address when resetting a password'), 400
    email_address = unquote_plus(email_address_encoded)

    json_payload = get_json_from_request()

    required_keys = ['password', 'confirmPassword']

    if not set(required_keys).issubset(json_payload):
        return jsonify(message='One or more required args were missing from the request'), 400

    if json_payload['password'] != json_payload['confirmPassword']:
        return jsonify(message="Passwords do not match"), 400

    try:
        token_age_limit = key_values_service.get_by_key('password_reset_token_age_limit')
        claim = user_claims_service.validate_and_update_claim(
            type='password_reset',
            token=token,
            email_address=email_address,
            age=token_age_limit['data']['age']
        )
        if not claim:
            return jsonify(message='Invalid token'), 400
    except Exception as error:
        return jsonify(message='Invalid token'), 400

    try:
        publish_tasks.user_claim.delay(
            publish_tasks.compress_user_claim(claim),
            'updated'
        )

        update_user_details(
            password=json_payload['password'],
            user_id=claim.data.get('user_id', None)
        )

        return jsonify(
            message="User with email {}, successfully updated their password".format(email_address),
            email_address=email_address
        ), 200

    except Exception as error:
        return jsonify(message=error.message), 400
Beispiel #21
0
def upsert_insight():
    now = None
    incoming_month_ending = request.args.get('monthEnding', None)
    if incoming_month_ending:
        now = pendulum.parse(incoming_month_ending)

    json_payload = get_json_from_request()
    data = None
    if 'data' in json_payload:
        data = json_payload['data']

    active = None
    if 'active' in json_payload:
        active = json_payload['active']

    saved = insight_business.upsert(now, data, active)
    return jsonify(saved), 200
Beispiel #22
0
def update_supplier_domain(supplier_code, supplier_domain_id):
    json_payload = get_json_from_request()

    supplier_id = (db.session.query(
        Supplier.id).filter(Supplier.code == supplier_code).one_or_none())

    supplier_domain = (db.session.query(SupplierDomain).filter(
        SupplierDomain.supplier_id == supplier_id).filter(
            SupplierDomain.id == supplier_domain_id).one_or_none())

    if not supplier_domain:
        abort(
            404, "Supplier {} does not have domain '{}' does not exist".format(
                supplier_id, supplier_domain_id))

    user = ''
    dirty = False
    if 'update_details' in json_payload:
        user = json_payload['update_details']['updated_by']

    if 'status' in json_payload:
        supplier_domain.status = json_payload['status']
        dirty = True

    if 'price_status' in json_payload:
        supplier_domain.price_status = json_payload['price_status']
        dirty = True

    if dirty is True:
        db.session.add(
            AuditEvent(audit_type=AuditTypes.assessed_domain,
                       user=user,
                       data={'payload': json_payload},
                       db_object=supplier_domain))
        db.session.commit()

        publish_tasks.supplier_domain.delay(
            publish_tasks.compress_supplier_domain(supplier_domain),
            'updated',
            supplier_code=supplier_code)

    supplier = (db.session.query(Supplier).filter(
        Supplier.code == supplier_code).one_or_none())

    return jsonify(supplier=supplier.serializable), 200
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
Beispiel #24
0
def register_framework_interest(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_payload.pop('updated_by')
    if json_payload:
        abort(400, "This PUT endpoint does not take a payload.")

    interest_record = SupplierFramework.query.filter(
        SupplierFramework.supplier_code == supplier.code,
        SupplierFramework.framework_id == framework.id).first()
    if interest_record:
        return jsonify(frameworkInterest=interest_record.serialize()), 200

    if framework.status != 'open':
        abort(400, "'{}' framework is not open".format(framework_slug))

    interest_record = SupplierFramework(supplier_code=supplier.code,
                                        framework_id=framework.id,
                                        declaration={})
    audit_event = AuditEvent(audit_type=AuditTypes.register_framework_interest,
                             user=updater_json['updated_by'],
                             data={
                                 'supplierId': supplier.code,
                                 'frameworkSlug': framework_slug
                             },
                             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()), 201
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
def supplier_search():
    search_query = get_json_from_request()
    new_domains = False

    offset = get_nonnegative_int_or_400(request.args, 'from', 0)
    result_count = get_positive_int_or_400(request.args, 'size', current_app.config['DM_API_SUPPLIERS_PAGE_SIZE'])
    framework_slug = request.args.get('framework', 'digital-marketplace')
    sliced_results, count = do_search(search_query, offset, result_count, new_domains, framework_slug)

    result = {
        'hits': {
            'total': count,
            'hits': [{'_source': r} for r in sliced_results]
        }
    }

    try:
        return jsonify(result), 200
    except Exception as e:
        return jsonify(message=str(e)), 500
Beispiel #27
0
def evidence_approve(evidence_id):
    json_payload = get_json_from_request()

    try:
        action = DomainApproval(
            actioned_by=json_payload.get('actioned_by', None),
            evidence_id=evidence_id
        )
        evidence_assessment = action.approve_domain()
    except DomainApprovalException as e:
        abort(400, str(e))

    try:
        evidence = evidence_service.get_evidence_by_id(evidence_id)
        if evidence:
            send_evidence_assessment_approval_notification(evidence)
    except Exception as e:
        current_app.logger.warn('Failed to send approval email for evidence id: {}, {}'.format(evidence_id, e))

    return jsonify(evidence_assessment=evidence_assessment.serialize()), 200
Beispiel #28
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
Beispiel #29
0
def send_reset_password_email():
    json_payload = get_json_from_request()
    email_address = json_payload.get('email_address', None)
    framework_slug = json_payload.get('framework', None)
    if email_address is None:
        return jsonify(message='One or more required args were missing from the request'), 400
    user = User.query.filter(
        User.email_address == email_address.lower()).first()

    if user is None:
        return jsonify(email_address=email_address), 200

    app_root_url = get_root_url(framework_slug)

    try:
        user_data = {
            'user_id': user.id
        }
        claim = user_claims_service.make_claim(type='password_reset', email_address=email_address, data=user_data)
        if not claim:
            return jsonify(message="There was an issue completing the password reset process."), 500

        publish_tasks.user_claim.delay(
            publish_tasks.compress_user_claim(claim),
            'created'
        )

        send_reset_password_confirm_email(
            token=claim.token,
            email_address=email_address,
            locked=user.locked,
            framework=framework_slug
        )

    except Exception as error:
        return jsonify(message=error.message), 400

    return jsonify(
        email_address=email_address
    ), 200
Beispiel #30
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 notify_callback():
    notify_data = get_json_from_request()

    if notify_data['status'] == 'permanent-failure':
        user = User.query.filter(
            User.email_address == notify_data['to']).first()

        if user and user.active:
            user.active = False
            db.session.add(user)

            audit_event = AuditEvent(
                audit_type=AuditTypes.update_user,
                user='******',
                data={
                    "user": {
                        "active": False
                    },
                    "notify_callback_data": notify_data
                },
                db_object=user,
            )
            db.session.add(audit_event)

            db.session.commit()

            current_app.logger.info(
                "User account disabled for {hashed_email} after Notify reported permanent delivery "
                "failure.".format(hashed_email=hash_string(notify_data['to'])))

    elif notify_data['status'] == 'technical-failure':
        current_app.logger.warning(
            "Notify failed to deliver {reference} to {hashed_email}".format(
                reference=notify_data['reference'],
                hashed_email=hash_string(notify_data['to']),
            ))

    return jsonify(status='ok'), 200
Beispiel #32
0
def upsert(key):
    """Upsert a key value (role=admin)
    ---
    tags:
      - key_value
    security:
      - basicAuth: []
    parameters:
      - name: key
        in: path
        type: string
        required: true
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/KeyValueUpsert'
    definitions:
          KeyValueUpsert:
            properties:
              data:
                type: object
    responses:
      200:
        description: A key value
        type: object
        schema:
          $ref: '#/definitions/KeyValue'
    """
    try:
        json_payload = get_json_from_request()
        data = json_payload.get('data')
        saved = key_values_service.upsert(key, data)
        return jsonify(saved), 200

    except Exception as error:
        return abort(error.message)
def upsert(key):
    """Upsert a key value (role=admin)
    ---
    tags:
      - key_value
    security:
      - basicAuth: []
    parameters:
      - name: key
        in: path
        type: string
        required: true
      - name: data
        in: body
        required: true
        schema:
          $ref: '#/definitions/KeyValueUpsert'
    definitions:
          KeyValueUpsert:
            properties:
              data:
                type: object
    responses:
      200:
        description: A key value
        type: object
        schema:
          $ref: '#/definitions/KeyValue'
    """
    try:
        json_payload = get_json_from_request()
        data = json_payload.get('data')
        saved = key_values_service.upsert(key, data)
        return jsonify(saved), 200

    except Exception as error:
        return abort(error.message)
Beispiel #34
0
def supplier_search():
    search_query = get_json_from_request()
    new_domains = False

    offset = get_nonnegative_int_or_400(request.args, 'from', 0)
    result_count = get_positive_int_or_400(
        request.args, 'size', current_app.config['DM_API_SUPPLIERS_PAGE_SIZE'])
    framework_slug = request.args.get('framework', 'digital-marketplace')
    sliced_results, count = do_search(search_query, offset, result_count,
                                      new_domains, framework_slug)

    result = {
        'hits': {
            'total': count,
            'hits': [{
                '_source': r
            } for r in sliced_results]
        }
    }

    try:
        return jsonify(result), 200
    except Exception as e:
        return jsonify(message=str(e)), 500
def update_supplier_domain(supplier_code, supplier_domain_id):
    json_payload = get_json_from_request()

    supplier_id = (
        db
        .session
        .query(Supplier.id)
        .filter(Supplier.code == supplier_code)
        .one_or_none()
    )

    supplier_domain = (
        db
        .session
        .query(SupplierDomain)
        .filter(SupplierDomain.supplier_id == supplier_id)
        .filter(SupplierDomain.id == supplier_domain_id)
        .one_or_none()
    )

    if not supplier_domain:
        abort(404, "Supplier {} does not have domain '{}' does not exist".format(supplier_id, supplier_domain_id))

    user = ''
    dirty = False
    if 'update_details' in json_payload:
        user = json_payload['update_details']['updated_by']

    if 'status' in json_payload:
        supplier_domain.status = json_payload['status']
        dirty = True

    if 'price_status' in json_payload:
        supplier_domain.price_status = json_payload['price_status']
        dirty = True

    if dirty is True:
        db.session.add(AuditEvent(
            audit_type=AuditTypes.assessed_domain,
            user=user,
            data={
                'payload': json_payload
            },
            db_object=supplier_domain
        ))
        db.session.commit()

        publish_tasks.supplier_domain.delay(
            publish_tasks.compress_supplier_domain(supplier_domain),
            'updated',
            supplier_code=supplier_code
        )

    supplier = (
        db
        .session
        .query(Supplier)
        .filter(Supplier.code == supplier_code)
        .one_or_none()
    )

    return jsonify(supplier=supplier.serializable), 200
def get_case_study_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['caseStudy'])
    return json_payload['caseStudy']
Beispiel #37
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)
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)
Beispiel #39
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 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
Beispiel #41
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 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 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_work_order_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['workOrder'])
    return json_payload['workOrder']
Beispiel #45
0
def get_case_study_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['caseStudy'])
    return json_payload['caseStudy']
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)
Beispiel #47
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)
def get_application_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['application'])
    return json_payload['application']
Beispiel #49
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 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
Beispiel #51
0
def get_application_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['application'])
    return json_payload['application']
def casestudies_search():
    search_query = get_json_from_request()

    offset = get_nonnegative_int_or_400(request.args, 'from', 0)
    result_count = get_positive_int_or_400(request.args, 'size', current_app.config['DM_API_SUPPLIERS_PAGE_SIZE'])

    sort_dir = search_query.get('sort_dir', 'asc')
    sort_by = search_query.get('sort_by', None)
    domains = search_query.get('domains', None)
    seller_types = search_query.get('seller_types', None)
    search_term = search_query.get('search_term', None)
    framework_slug = request.args.get('framework', 'digital-marketplace')

    q = db.session.query(CaseStudy).join(Supplier).outerjoin(SupplierDomain).outerjoin(Domain) \
        .outerjoin(SupplierFramework).outerjoin(Framework)
    q = q.filter(Supplier.status != 'deleted', or_(Framework.slug == framework_slug, ~Supplier.frameworks.any()))
    tsquery = None
    if search_term:
        if ' ' in search_term:
            tsquery = func.plainto_tsquery(search_term)
        else:
            tsquery = func.to_tsquery(search_term + ":*")
        q = q.add_column(func.ts_headline(
            'english',
            func.concat(
                CaseStudy.data['approach'].astext,
                ' ',
                CaseStudy.data['role'].astext),
            tsquery,
            'MaxWords=150, MinWords=75, ShortWord=3, HighlightAll=FALSE, FragmentDelimiter=" ... " '
        ))
    else:
        q = q.add_column("''")
    q = q.add_column(Supplier.name)
    q = q.add_column(postgres.array_agg(Supplier.data))
    q = q.group_by(CaseStudy.id, Supplier.name)

    if domains:
        d_agg = postgres.array_agg(cast(Domain.name, TEXT))
        q = q.having(d_agg.contains(array(domains)))

    if seller_types:
        selected_seller_types = select(
            [postgres.array_agg(column('key'))],
            from_obj=func.json_each_text(Supplier.data[('seller_type',)]),
            whereclause=cast(column('value'), Boolean)
        ).as_scalar()

        q = q.filter(selected_seller_types.contains(array(seller_types)))

    if sort_dir in ('desc', 'z-a'):
        ob = [desc(CaseStudy.data['title'].astext)]
    else:
        ob = [asc(CaseStudy.data['title'].astext)]

    if search_term:
        ob = [desc(func.ts_rank_cd(func.to_tsvector(
            func.concat(Supplier.name, CaseStudy.data['title'].astext,
                        CaseStudy.data['approach'].astext)), tsquery))] + ob

        condition = func.to_tsvector(func.concat(Supplier.name,
                                                 CaseStudy.data['title'].astext,
                                                 CaseStudy.data['approach'].astext)).op('@@')(tsquery)

        q = q.filter(condition)
    q = q.order_by(*ob)

    raw_results = list(q)
    results = []

    for x in range(len(raw_results)):
        result = raw_results[x][0].serialize()
        if raw_results[x][1] is not None and raw_results[x][1] != '':
            result['approach'] = raw_results[x][1]
        if raw_results[x][2] is not None:
            result['supplierName'] = raw_results[x][2]
        if raw_results[x][3] is not None and raw_results[x][3][0] is not None:
            result['seller_type'] = raw_results[x][3][0].get('seller_type')
        results.append(result)

    total_results = len(results)

    sliced_results = results[offset:(offset + result_count)]

    result = {
        'hits': {
            'total': total_results,
            'hits': [{'_source': r} for r in sliced_results]
        }
    }

    try:
        response = jsonify(result), 200
    except Exception as e:
        response = jsonify(message=str(e)), 500

    return response
def get_project_json():
    json_payload = get_json_from_request()
    json_has_required_keys(json_payload, ['project'])
    return json_payload['project']