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
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
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 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 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_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']
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 get_application_json(): json_payload = get_json_from_request() json_has_required_keys(json_payload, ['application']) return json_payload['application']
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)
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
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 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 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 get_project_json(): json_payload = get_json_from_request() json_has_required_keys(json_payload, ['project']) return json_payload['project']
def get_case_study_json(): json_payload = get_json_from_request() json_has_required_keys(json_payload, ['caseStudy']) return json_payload['caseStudy']
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 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)
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)