Example #1
0
def update_borrower(borrower, idx, borrowers, deed_token):
    borrower_service = BorrowerService()

    borrower_json = {
        "id": "",
        "token": "",
        "forename": borrower['forename'],
        "surname": borrower['surname']
    }

    if 'middle_name' in borrower:
        borrower_json["middle_name"] = borrower["middle_name"]

    if 'id' not in borrower:
        created_borrower = borrower_service.saveBorrower(borrower, deed_token)

        borrower_json["id"] = created_borrower.id
        borrower_json["token"] = created_borrower.token
    else:
        borrower_updater = BorrowerModel()
        updated_borrower = borrower_updater.update_borrower_by_id(borrower)

        borrower_json["id"] = int(borrower["id"])
        borrower_json["token"] = updated_borrower.token

    return borrower_json
    def test_update_borrower_by_id_no_borrower(self, mock_db, mock_query):

        updated_borrower = copy.deepcopy(
            DeedHelper._valid_single_borrower_update)

        mock_query.return_value = None
        borrower = Borrower()

        res = borrower.update_borrower_by_id(updated_borrower)

        self.assertEqual(res, "Error No Borrower")
Example #3
0
def delete_orphaned_borrowers(deed):
    borrower_list = []

    for borrower in deed.deed["borrowers"]:
        borrower_list.append(borrower["id"])

        borrower_model_delete = BorrowerModel()

    borrower_model_delete.delete_borrowers_not_on_deed(borrower_list,
                                                       deed.token)
    return True
Example #4
0
def delete_borrower(borrower_id):
    borrower = None
    borrowerModel = Borrower()
    try:
        borrower = borrowerModel.delete(borrower_id)
    except Exception as inst:
        application.app.logger.error(str(type(inst)) + ":" + str(inst))

    if borrower is None:
        abort(status.HTTP_404_NOT_FOUND)
    else:
        return jsonify({"id": borrower_id}), status.HTTP_200_OK
Example #5
0
def delete_borrower(borrower_id):
    borrower = None
    borrowerModel = Borrower()
    try:
        borrower = borrowerModel.delete(borrower_id)
    except Exception as inst:
        LOGGER.error(str(type(inst)) + ":" + str(inst))

    if borrower is None:
        abort(status.HTTP_404_NOT_FOUND)
    else:
        return jsonify({"id": borrower_id}), status.HTTP_200_OK
    def test_update_borrower_by_id(self, mock_db, mock_query):

        updated_borrower = copy.deepcopy(
            DeedHelper._valid_single_borrower_update)

        testBorrower = borrower_object_helper(updated_borrower)

        mock_query.return_value = testBorrower

        updated_borrower["forename"] = "Frank"

        borrower = Borrower()
        res = borrower.update_borrower_by_id(updated_borrower)

        self.assertEqual(res.forename, "Frank")
Example #7
0
def issue_sms(deed_reference, borrower_token):
    deed_instance = Deed()
    deed = deed_instance.get_deed(deed_reference)
    esec_client = make_esec_client()

    if deed is None:
        application.app.logger.error(
            "Database Exception 404 for deed reference - %s" % deed_reference)
        abort(status.HTTP_404_NOT_FOUND)
    else:
        application.app.logger.info(
            "Signing deed for borrower_token %s against deed reference %s" %
            (borrower_token, deed_reference))

        try:
            application.app.logger.info("getting existing XML")
            borrower = Borrower.get_by_token(borrower_token)

            if not borrower.esec_user_name:
                application.app.logger.info(
                    "creating esec user for borrower[token:%s]",
                    borrower.token)

                forenames = ' '.join(
                    filter(bool, (borrower.forename, borrower.middlename)))

                user_id, status_code = esec_client.issue_sms(
                    forenames, borrower.surname, deed.organisation_name,
                    borrower.phonenumber)
                if status_code == 200:
                    application.app.logger.info(
                        "Created new esec user: %s for borrower[token:%s]",
                        str(user_id.decode()), borrower.token)
                    borrower.esec_user_name = user_id.decode()
                    borrower.save()
                else:
                    application.app.logger.error(
                        "Unable to create new e-sec user for borrower [token:%s]",
                        borrower.token)
                    abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

            else:
                result, status_code = esec_client.reissue_sms(
                    borrower.esec_user_name)

            if status_code != 200:
                application.app.logger.error(
                    "Unable to reissue new sms code for esec user: %s",
                    borrower.esec_user_name)
                abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        except:
            msg = str(sys.exc_info())
            application.app.logger.error(
                "Failed to issue auth code via sms: %s" % msg)
            abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

    return status.HTTP_200_OK
    def test_update_borrower_signing_in_progress(self, mock_borrower,
                                                 mock_borrower_save):
        class ReturnedBorrower:
            id = 0000000
            token = "aaaaaa"
            deed_token = "aaaaaa"
            dob = "02/02/1922"
            phonenumber = "07777777777"
            signing_in_progress = False

        mock_borrower.return_value = None
        mock_borrower_save.signing_in_progress = False
        with self.assertRaises(BorrowerNotFoundException):
            Borrower.update_borrower_signing_in_progress('bbbbbb')

        mock_borrower.return_value = BorrowerModelMock()
        mock_borrower.return_value.signing_in_progress = True
        self.assertEqual(
            Borrower.update_borrower_signing_in_progress('aaaaaa'), True)
    def test_borrower_token(self):
        token = Borrower.generate_token()
        char_list = ['I', 'O', 'W', 'Z']
        res = False

        if any((c in char_list) for c in token):
            res = True

        self.assertTrue(token.isupper())
        self.assertFalse(res)
Example #10
0
def auth_sms(deed_reference, borrower_token, borrower_code):
    deed = Deed.get_deed(deed_reference)

    if deed is None:
        LOGGER.error("Database Exception 404 for deed reference - %s" %
                     deed_reference)
        abort(status.HTTP_404_NOT_FOUND)
    else:
        LOGGER.info(
            "Signing deed for borrower_token %s against deed reference %s" %
            (borrower_token, deed_reference))

        # check if XML already exist
        if deed.deed_xml is None:
            LOGGER.info("Generating DEED_XML")
            deed_XML = convert_json_to_xml(deed.deed)
            deed.deed_xml = deed_XML.encode("utf-8")

        try:
            LOGGER.info("getting existing XML")
            modify_xml = copy.deepcopy(deed.deed_xml)
            borrower_pos = deed.get_borrower_position(borrower_token)
            borrower = Borrower.get_by_token(borrower_token)
            esec_id = borrower.esec_user_name

            if esec_id:
                result_xml, status_code = esec_client.auth_sms(
                    modify_xml, borrower_pos, esec_id, borrower_code)
                LOGGER.info("signed status code: %s", str(status_code))
                LOGGER.info("signed XML: %s" % result_xml)

                if status_code == 200:
                    deed.deed_xml = result_xml

                    LOGGER.info("Saving XML to DB")
                    deed.save()

                    LOGGER.info("updating JSON with Signature")
                    deed.deed = update_deed_signature_timestamp(
                        deed, borrower_token)
                else:
                    LOGGER.error("Failed to sign Mortgage document")
                    return "Failed to sign Mortgage document", status_code
            else:
                LOGGER.error(
                    "Failed to sign Mortgage document - unable to create user")
                abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        except:
            msg = str(sys.exc_info())
            LOGGER.error("Failed to sign Mortgage document: %s" % msg)
            abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

    return jsonify({"deed": deed.deed}), status.HTTP_200_OK
Example #11
0
def auth_sms(deed_reference, borrower_token, borrower_code):
    deed = Deed.get_deed(deed_reference)

    if deed is None:
        LOGGER.error("Database Exception 404 for deed reference - %s" % deed_reference)
        abort(status.HTTP_404_NOT_FOUND)
    else:
        LOGGER.info("Signing deed for borrower_token %s against deed reference %s" % (borrower_token, deed_reference))

        # check if XML already exist
        if deed.deed_xml is None:
            LOGGER.info("Generating DEED_XML")
            deed_XML = convert_json_to_xml(deed.deed)
            deed.deed_xml = deed_XML.encode("utf-8")

        try:
            LOGGER.info("getting existing XML")
            modify_xml = copy.deepcopy(deed.deed_xml)
            borrower_pos = deed.get_borrower_position(borrower_token)
            borrower = Borrower.get_by_token(borrower_token)
            esec_id = borrower.esec_user_name

            if esec_id:
                result_xml, status_code = esec_client.auth_sms(modify_xml, borrower_pos,
                                                               esec_id, borrower_code)
                LOGGER.info("signed status code: %s", str(status_code))
                LOGGER.info("signed XML: %s" % result_xml)

                if status_code == 200:
                    deed.deed_xml = result_xml

                    LOGGER.info("Saving XML to DB")
                    deed.save()

                    LOGGER.info("updating JSON with Signature")
                    deed.deed = update_deed_signature_timestamp(deed, borrower_token)
                else:
                    LOGGER.error("Failed to sign Mortgage document")
                    return "Failed to sign Mortgage document", status_code
            else:
                LOGGER.error("Failed to sign Mortgage document - unable to create user")
                abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        except:
            msg = str(sys.exc_info())
            LOGGER.error("Failed to sign Mortgage document: %s" % msg)
            abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

    return jsonify({"deed": deed.deed}), status.HTTP_200_OK
Example #12
0
def get_borrower_details_by_verify_pid(verify_pid):
    borrower = Borrower.get_by_verify_pid(verify_pid)

    if borrower is not None:
        return json.dumps(
            {
                "borrower_token": borrower.token,
                "deed_token": borrower.deed_token,
                "phone_number": borrower.phonenumber,
                "borrower_id": borrower.id,
                "signing_in_progress": borrower.signing_in_progress
            }
        ), status.HTTP_200_OK

    return "Matching borrower not found", status.HTTP_404_NOT_FOUND
Example #13
0
def validate_borrower():
    payload = request.get_json()

    if 'borrower_token' in payload:
        borrower = Borrower.get_by_token(payload['borrower_token'].strip())
        if borrower is not None:
            input_dob = datetime.strptime(payload['dob'], "%d/%m/%Y")
            db_dob = datetime.strptime(borrower.dob, "%d/%m/%Y")

            if input_dob == db_dob:
                stripped_number = strip_number_to_four_digits(borrower.phonenumber)
                return json.dumps({"deed_token": borrower.deed_token, "phone_number": stripped_number}),\
                    status.HTTP_200_OK

    return "Matching deed not found", status.HTTP_404_NOT_FOUND
Example #14
0
def validate_borrower():
    payload = request.get_json()

    if 'borrower_token' in payload:
        borrower = Borrower.get_by_token(payload['borrower_token'].strip())
        if borrower is not None:
            input_dob = datetime.strptime(payload['dob'], "%d/%m/%Y")
            db_dob = datetime.strptime(borrower.dob, "%d/%m/%Y")

            if input_dob == db_dob:
                stripped_number = strip_number_to_four_digits(
                    borrower.phonenumber)
                return json.dumps({"deed_token": borrower.deed_token, "phone_number": stripped_number}),\
                    status.HTTP_200_OK

    return "Matching deed not found", status.HTTP_404_NOT_FOUND
Example #15
0
def validate_borrower():
    payload = request.get_json()

    if 'borrower_token' in payload:
        borrower = Borrower.get_by_token(payload['borrower_token'].strip())
        if borrower:
            input_dob = datetime.strptime(payload['dob'], "%d/%m/%Y")
            db_dob = datetime.strptime(borrower.dob, "%d/%m/%Y")

            if input_dob == db_dob:
                borrower_id = borrower.id
                return json.dumps({"deed_token": borrower.deed_token, "phone_number": borrower.phonenumber, "borrower_id": borrower_id}),\
                    status.HTTP_200_OK
            else:
                application.app.logger.error("Matching DOB not found for provided borrower.")

    return "Matching deed not found", status.HTTP_404_NOT_FOUND
Example #16
0
def issue_sms(deed_reference, borrower_token):
    deed = Deed.get_deed(deed_reference)

    if deed is None:
        LOGGER.error("Database Exception 404 for deed reference - %s" % deed_reference)
        abort(status.HTTP_404_NOT_FOUND)
    else:
        LOGGER.info("Signing deed for borrower_token %s against deed reference %s" % (borrower_token, deed_reference))

        try:
            LOGGER.info("getting existing XML")
            borrower = Borrower.get_by_token(borrower_token)

            if not borrower.esec_user_name:
                LOGGER.info("creating esec user for borrower[token:%s]", borrower.token)
                user_id, status_code = esec_client.issue_sms(borrower.forename, borrower.surname,
                                                             deed.organisation_id, borrower.phonenumber)
                if status_code == 200:
                    LOGGER.info("Created new esec user: %s for borrower[token:%s]", str(user_id.decode()),
                                borrower.token)
                    borrower.esec_user_name = user_id.decode()
                    borrower.save()
                else:
                    LOGGER.error("Unable to create new e-sec user for borrower [token:%s]", borrower.token)
                    abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

            else:
                result, status_code = esec_client.reissue_sms(borrower.esec_user_name)

                if status_code != 200:
                    LOGGER.error("Unable to reissue new sms code for esec user: %s", borrower.esec_user_name)
                    abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        except:
            msg = str(sys.exc_info())
            LOGGER.error("Failed to issue auth code via sms: %s" % msg)
            abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

    return status.HTTP_200_OK
Example #17
0
    def saveBorrower(self, borrower, deed_token):
        borrowerModel = Borrower()
        borrowerModel.forename = borrower['forename']

        if 'middle_name' in borrower:
            borrowerModel.middlename = borrower['middle_name']

        borrowerModel.surname = borrower['surname']
        borrowerModel.dob = borrower['dob']
        borrowerModel.deed_token = deed_token

        if 'gender' in borrower:
            borrowerModel.gender = borrower['gender']

        borrowerModel.phonenumber = borrower['phone_number']
        borrowerModel.address = borrower['address']

        borrowerModel.token = borrowerModel.generate_token()

        borrowerModel.save()

        return borrowerModel
def auth_sms(deed, borrower_pos, user_id, borrower_auth_code, borrower_token):  # pragma: no cover

    application.app.logger.info("Calling dm-esec-client to verify OTP code and sign the deed")
    element_id = 'deedData'
    borrower_path = "/dm-application/operativeDeed/signatureSlots"

    parameters = {
        'borrower-pos': borrower_pos,
        'element-id': element_id,
        'borrowers-path': borrower_path,
        'user-id': user_id,
        'otp-code': borrower_auth_code,
        'service-id': 1
    }

    extra_parameters = {
        'borrower-token': borrower_token,
        'datetime': datetime.datetime.now().strftime("%d %B %Y %I:%M%p"),
        'deed-id': deed.token
    }

    application.app.logger.info("Calling esec_client to hit validateSMSOTP...")

    request_url = config.ESEC_CLIENT_BASE_HOST + "/esec/auth_sms"

    resp = requests.post(request_url, params=parameters, data=deed.deed_xml)

    if resp.status_code == status.HTTP_401_UNAUTHORIZED:
        application.app.logger.info("Response status = %s" % resp.status_code)
        return jsonify({"status": "SMS Invalid"}), resp.status_code

    elif resp.status_code == status.HTTP_200_OK:
        application.app.logger.info("Response status = %s" % resp.status_code)

        deed_xml_to_send = deed.deed_xml.decode('utf-8')

        application.app.logger.info("Hashing deed prior to sending message to queue...")
        tree = etree.fromstring(deed.deed_xml)
        deed_data_xml = tree.xpath('.//deedData')[0]

        deed.deed_hash = Deed().generate_hash(etree.tostring(deed_data_xml))
        deed.save()

        application.app.logger.info("Preparing to send message to the queue...")

        try:
            url = broker_url(config.RABBIT_HOST, config.EXCHANGE_USER, config.EXCHANGE_PASS, 5672, config.RABBIT_VHOST)
            with Emitter(url, config.EXCHANGE_NAME, config.ROUTING_KEYS) as emitter:
                emitter.send_message({'params': parameters, 'extra-parameters': extra_parameters, 'data': deed_xml_to_send})
                application.app.logger.info("Message sent to the queue...")

            Borrower.update_borrower_signing_in_progress(borrower_token)
            return jsonify({"status": "Message successfully sent to the queue"}), status.HTTP_200_OK

        except Exception as e:
            application.app.logger.info('Error returned when trying to place an item on the queue: %s' % e)
            raise Exception

    else:
        application.app.logger.error("ESecurity Client Exception when trying to verify the OTP code")
        abort(status.HTTP_500_INTERNAL_SERVER_ERROR)
Example #19
0
def remove_borrower_row(self, borrower_id):
    with self.app.app_context():
        borrower = Borrower()
        borrower.delete(999)
Example #20
0
def insert_borrower_row(self, verify_pid, borrower_id):
    with self.app.app_context():
        remove_verify_match_row(self, 999)
        remove_borrower_row(self, 999)
        borrower = Borrower()
        borrower.id = 999
        borrower.forename = 'some'
        borrower.middlename = 'nice'
        borrower.surname = 'guy'
        borrower.dob = 'a date'
        borrower.gender = 'a gender'
        borrower.phonenumber = '07777777777'
        borrower.address = 'an address'
        borrower.token = 'a token'
        borrower.deed_token = 'a deed token'
        borrower.esec_user_name = 'an esec user name'
        borrower.save()
Example #21
0
def borrower_object_helper(borrower):
    new_borrower = Borrower()

    new_borrower.id = borrower['id']
    new_borrower.token = "AAAA"
    new_borrower.deed_token = "AAAA"
    new_borrower.forename = borrower['forename']
    new_borrower.middlename = borrower['middle_name']
    new_borrower.surname = borrower['surname']
    new_borrower.dob = borrower['dob']
    new_borrower.gender = borrower['gender']
    new_borrower.phonenumber = borrower['phone_number']
    new_borrower.address = borrower['address']
    new_borrower.esec_user_name = ""

    return new_borrower
Example #22
0
def check_borrower_signing_in_progress(borrower_token):
    borrower = Borrower.get_by_token(borrower_token)
    if borrower:
        return jsonify({'result': borrower.signing_in_progress}), status.HTTP_200_OK

    return "Matching borrower not found", status.HTTP_404_NOT_FOUND
Example #23
0
def get_existing_deed_and_update(deed_reference):
    deed = Deed()
    deed_update_json = request.get_json()

    validator = Validation()

    credentials = validator.validate_organisation_credentials()
    if credentials is None:
        return '', status.HTTP_401_UNAUTHORIZED

    schema_errors = validator.validate_payload(deed_update_json)

    ids = []
    for borrower in deed_update_json["borrowers"]:
        if 'id' in borrower:
            ids.append(borrower['id'])

    duplicates = [
        item for item, count in collections.Counter(ids).items() if count > 1
    ]
    if duplicates:
        schema_errors.append("A borrower ID must be unique to an individual.")

    if schema_errors:
        compiled_list = send_error_list(schema_errors)
        return compiled_list

    error_list = []

    result_deed = deed.get_deed(deed_reference)
    if result_deed is None:
        error_list.append("There is no deed associated with - %s deed id." %
                          str(deed_reference))
        application.app.logger.error("Deed with reference - %s not found" %
                                     str(deed_reference))
        return_error_list = send_error_list(error_list)
        return return_error_list

    # Deed Status checks
    if str(result_deed.status) != "DRAFT":
        error_list.append(
            "This deed is not in the correct state to be modified.")
        return_error_list = send_error_list(error_list)
        return return_error_list

    for borrower_id in ids:
        borrower_check = Borrower.get_by_id(borrower_id)

        if borrower_check is None or borrower_check.deed_token != deed_reference:
            error_list.append(
                "Borrowers provided do not match the selected deed.")
            return_error_list = send_error_list(error_list)
            return return_error_list

    validate_title_number = validator.validate_title_number(deed_update_json)
    if validate_title_number != "title OK":
        error_list.append(validate_title_number)
        return_error_list = send_error_list(error_list)
        return return_error_list

    # From here - errors are grouped
    error_list = []

    validate_borrower_names, msg = validator.validate_borrower_names(
        deed_update_json)
    if not validate_borrower_names:
        error_list.append(msg)

    modify_deed_akuma = validator.call_akuma(
        deed_update_json,
        result_deed.token,
        credentials['organisation_name'],
        credentials['organisation_locale'],
        deed_type="modify deed")

    if modify_deed_akuma['result'] == "Z":
        return jsonify({"message": "Unable to use this service. "
                                   "This might be because of technical difficulties or entries on the register not "
                                   "being suitable for digital applications. "
                                   "You will need to complete this transaction using a paper deed."}), \
            status.HTTP_403_FORBIDDEN

    dob_validate, msg = validator.validate_dob(deed_update_json)
    if not dob_validate:
        error_list.append(msg)

    phone_validate, msg = validator.validate_phonenumbers(deed_update_json)
    if not phone_validate:
        error_list.append(msg)

    md_validate, msg = validator.validate_md_exists(deed_update_json['md_ref'])
    if not md_validate:
        error_list.append(msg)

    # Error List Print Out
    if len(error_list) > 0:
        compiled_list = send_error_list(error_list)
        return compiled_list

    success, msg = update_deed(result_deed, deed_update_json)
    if not success:
        application.app.logger.error("Update deed 400_BAD_REQUEST")
        return msg, status.HTTP_400_BAD_REQUEST
    else:
        application.app.logger.info("Deed has been updated successfully.")

    return jsonify({"path":
                    '/deed/' + str(deed_reference)}), status.HTTP_200_OK
Example #24
0
def auth_sms(deed_reference, borrower_token, borrower_code):
    deed_instance = Deed()
    deed = deed_instance.get_deed(deed_reference)

    if deed is None:
        application.app.logger.error(
            "Database Exception 404 for deed reference - %s" % deed_reference)
        abort(status.HTTP_404_NOT_FOUND)
    else:
        application.app.logger.info(
            "Signing deed for borrower_token %s against deed reference %s" %
            (borrower_token, deed_reference))

        signing_deed_akuma = Akuma.do_check(deed.deed, "borrower sign",
                                            deed.organisation_name, "",
                                            deed.token)
        application.app.logger.info("Check ID - Borrower SIGNING: " +
                                    signing_deed_akuma['id'])

        if signing_deed_akuma["result"] == "Z":
            application.app.logger.error("Failed to sign Mortgage document")
            return "Failed to sign Mortgage document"

        # check if XML already exist
        if deed.deed_xml is None:
            application.app.logger.info("Generating DEED_XML")
            deed_XML = convert_json_to_xml(deed.deed)
            deed.deed_xml = deed_XML.encode("utf-8")

        try:
            application.app.logger.info("getting existing XML")
            borrower_pos = deed.get_borrower_position(borrower_token)
            borrower = Borrower.get_by_token(borrower_token)
            esec_id = borrower.esec_user_name

            if esec_id:
                esec_client = make_esec_client()
                response, status_code = esec_client.auth_sms(
                    deed, borrower_pos, esec_id, borrower_code, borrower_token)
                application.app.logger.info("auth_sms status code: %s",
                                            str(status_code))

                if status_code == 200:
                    return jsonify({"deed": deed.deed}), status.HTTP_200_OK

                else:
                    application.app.logger.error(
                        "Failed to authenticate sms code")
                    return jsonify({
                        "status": "Failed to authenticate sms code"
                    }), status.HTTP_401_UNAUTHORIZED

            else:
                application.app.logger.error(
                    "Failed to sign Mortgage document - unable to create user")
                abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        except:
            msg = str(sys.exc_info())
            application.app.logger.error(
                "Failed to sign Mortgage document: %s" % msg)
            abort(status.HTTP_500_INTERNAL_SERVER_ERROR)

        return jsonify({"deed": deed.deed}), status.HTTP_200_OK