Beispiel #1
0
 def test_get_respondent_by_party_id_fail(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.GET, url_get_respondent_party, status=500)
         with app.app_context():
             with self.assertRaises(ApiError):
                 party_controller.get_respondent_party_by_id(
                     respondent_party['id'])
def change_account_details(session):
    form = ContactDetailsChangeForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    update_required_flag = False
    attributes_changed = []
    if request.method == 'POST' and form.validate():
        logger.info('Attempting to update contact details changes on the account')
        update_required_flag = check_attribute_change(form,
                                                      attributes_changed,
                                                      respondent_details,
                                                      update_required_flag)
        if update_required_flag:
            try:
                party_controller.update_account(respondent_details)
            except ApiError as exc:
                logger.error('Failed to updated account', status=exc.status_code)
                raise exc
            logger.info('Successfully updated account')
            success_panel = create_success_message(attributes_changed, "We've updated your ")
            flash(success_panel)
            return redirect(url_for('surveys_bp.get_survey_list', tag='todo'))
        else:
            return redirect(url_for('surveys_bp.get_survey_list', tag='todo'))
    else:
        return render_template('account/account-contact-detail-change.html',
                               form=form, errors=form.errors, respondent=respondent_details)
Beispiel #3
0
def change_account_details(session):
    form = ContactDetailsChangeForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    is_contact_details_update_required = False
    attributes_changed = []
    if request.method == "POST" and form.validate():
        logger.info("Attempting to update contact details changes on the account", party_id=party_id)
        # check_attribute changes also magically updates the respondent_details as a side effect of running this
        # function
        is_contact_details_update_required = check_attribute_change(
            form, attributes_changed, respondent_details, is_contact_details_update_required
        )
        if is_contact_details_update_required:
            try:
                party_controller.update_account(respondent_details)
            except ApiError as exc:
                logger.error("Failed to updated account", status=exc.status_code)
                raise exc
            logger.info("Successfully updated account", party_id=party_id)
            success_panel = create_success_message(attributes_changed, "We have updated your ")
            flash(success_panel)
        is_email_update_required = form["email_address"].data != respondent_details["emailAddress"]
        if is_email_update_required:
            return render_template(
                "account/account-change-email-address.html",
                new_email=form["email_address"].data,
                form=ConfirmEmailChangeForm(),
            )
        return redirect(url_for("surveys_bp.get_survey_list", tag="todo"))
    else:
        return render_template(
            "account/account-contact-detail-change.html", form=form, errors=form.errors, respondent=respondent_details
        )
Beispiel #4
0
def change_password(session):
    form = ChangePasswordFrom(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if request.method == 'POST' and form.validate():
        username = respondent_details['emailAddress']
        password = request.form.get('password')
        new_password = request.form.get('new_password')
        if new_password == password:
            return render_template('account/account-change-password.html', form=form,
                                   errors={"new_password": ["Your new password is the same as your old password"]})
        bound_logger = logger.bind(email=obfuscate_email(username))
        bound_logger.info("Attempting to find user in auth service")
        try:
            # We call the sign in function to verify that the password provided is correct
            auth_controller.sign_in(username, password)
            bound_logger.info("Attempting to change password via party service")
            party_controller.change_password(username, new_password)
            bound_logger.info("password changed via party service")
            flash('Your password has been changed.')
            return redirect(url_for('surveys_bp.get_survey_list', tag='todo'))
        except AuthError as exc:
            error_message = exc.auth_error
            if BAD_CREDENTIALS_ERROR in error_message:
                bound_logger.info('Bad credentials provided')
                return render_template('account/account-change-password.html', form=form,
                                       errors={"password": ["Incorrect current password"]})
    else:
        errors = form.errors

    return render_template('account/account-change-password.html', form=form, errors=errors)
def accept_share_surveys_existing_account(session, batch):
    """
    Accept redirect endpoint for accepting share surveys for existing account
    :param session:
    :type session:
    :param batch: batch number
    :type batch: str
    """
    logger.info("Attempting to confirm share surveys for existing account",
                batch_number=batch)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    response = party_controller.get_pending_surveys_batch_number(batch)
    if respondent_details["emailAddress"].lower() != response.json(
    )[0]["email_address"].lower():
        logger.warning("The user has entered invalid login for share survey.")
        flash(
            "Invalid share survey login. This share survey is not assigned to you.",
            "error")
        return redirect(url_for("surveys_bp.get_survey_list", tag="todo"))
    try:
        party_controller.confirm_pending_survey(batch)
    except ApiError as exc:
        logger.error("Failed to confirm share survey for existing account",
                     status=exc.status_code,
                     batch_number=batch)
        raise exc
    logger.info("Successfully completed share survey for existing account",
                batch_number=batch)
    return render_template(
        "surveys/surveys-share/share-survey-complete-thank-you.html")
Beispiel #6
0
    def test_get_respondent_by_party_id_not_found(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_respondent_party, status=404)
            with app.app_context():
                party = party_controller.get_respondent_party_by_id(
                    respondent_party['id'])

                self.assertTrue(party is None)
Beispiel #7
0
def get_account(session):
    form = OptionsForm()
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    is_share_survey_enabled = app.config['SHARE_SURVEY_ENABLED']
    return render_template('account/account.html',
                           form=form,
                           respondent=respondent_details,
                           is_share_survey_enabled=is_share_survey_enabled)
Beispiel #8
0
def send_instruction(session):
    form = ConfirmEmailChangeForm(request.values)
    email = flask_session['share_survey_recipient_email_address']
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if form['email_address'].data != email:
        raise ShareSurveyProcessError('Process failed due to session error')
    json_data = build_payload(respondent_details['id'])
    register_pending_shares(json_data)
    return render_template('surveys/surveys-share/almost-done.html')
Beispiel #9
0
    def test_get_respondent_by_party_id_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET,
                     url_get_respondent_party,
                     json=respondent_party,
                     status=200)

            with app.app_context():
                party = party_controller.get_respondent_party_by_id(
                    respondent_party['id'])

                self.assertEqual(party['id'], respondent_party['id'])
                self.assertEqual(party['emailAddress'],
                                 respondent_party['emailAddress'])
Beispiel #10
0
def change_email_address(session):
    form = ConfirmEmailChangeForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    respondent_details['email_address'] = respondent_details['emailAddress']
    respondent_details['new_email_address'] = form['email_address'].data
    respondent_details['change_requested_by_respondent'] = True
    logger.info('Attempting to update email address changes on the account', party_id=party_id)
    try:
        party_controller.update_account(respondent_details)
    except ApiError as exc:
        logger.error('Failed to updated email on account', status=exc.status_code, party_id=party_id)
        raise exc
    logger.info('Successfully updated email on account', party_id=party_id)
    return render_template('account/account-change-email-address-almost-done.html')
Beispiel #11
0
def send_instruction(session):
    form = ConfirmEmailChangeForm(request.values)
    email = flask_session["share_survey_recipient_email_address"]
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if form["email_address"].data != email:
        raise ShareSurveyProcessError("Process failed due to session error")
    json_data = build_payload(respondent_details["id"])
    response = register_pending_shares(json_data)
    if response.status_code == 400:
        flash(
            "You have already transferred or shared these surveys with someone with this email address. They have 72 "
            "hours to accept your request. If you have made an error then wait for the transfer/share to expire or "
            "contact us.", )
        return redirect(url_for("account_bp.send_instruction_get"))
    return render_template("surveys/surveys-share/almost-done.html")
Beispiel #12
0
def delete_user_account(session):
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if "associations" in respondent_details:
        for association in respondent_details["associations"]:
            for enrolment in association["enrolments"]:
                if enrolment["enrolmentStatus"] == "ENABLED":
                    flash(
                        "This operation is not allowed as you are currently assigned to a survey.",
                        "info")
                    return render_template("account/account-delete.html",
                                           is_validated=False)
    if request.method == "POST":
        delete_account(respondent_details["emailAddress"])
        return redirect(url_for("sign_in_bp.logout"))

    return render_template("account/account-delete.html", is_validated=True)
Beispiel #13
0
def change_email_address(session):
    form = ConfirmEmailChangeForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    respondent_details["email_address"] = respondent_details["emailAddress"]
    respondent_details["new_email_address"] = form["email_address"].data
    respondent_details["change_requested_by_respondent"] = True
    logger.info("Attempting to update email address changes on the account", party_id=party_id)
    try:
        party_controller.update_account(respondent_details)

    except ApiError as exc:
        logger.error("Failed to updated email on account", status=exc.status_code, party_id=party_id)
        if exc.status_code == 409:
            logger.info("The email requested already registered in our system. Request denied", party_id=party_id)
            return render_template("account/account-change-email-address-conflict.html")
        else:
            raise exc
    logger.info("Successfully updated email on account", party_id=party_id)
    return render_template("account/account-change-email-address-almost-done.html")
Beispiel #14
0
def change_password(session):
    form = ChangePasswordFrom(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if request.method == "POST" and form.validate():
        username = respondent_details["emailAddress"]
        password = request.form.get("password")
        new_password = request.form.get("new_password")
        if new_password == password:
            return render_template(
                "account/account-change-password.html",
                form=form,
                errors={"new_password": ["Your new password is the same as your old password"]},
            )
        bound_logger = logger.bind(email=obfuscate_email(username))
        bound_logger.info("Attempting to find user in auth service")
        try:
            # We call the sign in function to verify that the password provided is correct
            auth_controller.sign_in(username, password)
            bound_logger.info("Attempting to change password via party service")
            party_controller.change_password(username, new_password)
            bound_logger.info("password changed via party service")
            flash("Your password has been changed. Please login with your new password.", "success")
            return redirect(url_for("sign_in_bp.logout"))
        except AuthError as exc:
            error_message = exc.auth_error
            if BAD_CREDENTIALS_ERROR in error_message:
                bound_logger.info("Bad credentials provided")
                return render_template(
                    "account/account-change-password.html",
                    form=form,
                    errors={"password": ["Incorrect current password"]},
                )
    else:
        errors = form.errors

    return render_template("account/account-change-password.html", form=form, errors=errors)
Beispiel #15
0
def change_account_details(session):
    form = ContactDetailsChangeForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    is_contact_details_update_required = False
    attributes_changed = []
    # TODO: is_account_detail_change_enabled to be removed once account change is worked again
    is_account_email_change_enabled = app.config['ACCOUNT_EMAIL_CHANGE_ENABLED']
    if request.method == 'POST' and form.validate():
        logger.info('Attempting to update contact details changes on the account', party_id=party_id)
        # check_attribute changes also magically updates the respondent_details as a side effect of running this
        # function
        is_contact_details_update_required = check_attribute_change(form,
                                                                    attributes_changed,
                                                                    respondent_details,
                                                                    is_contact_details_update_required)
        if is_contact_details_update_required:
            try:
                party_controller.update_account(respondent_details)
            except ApiError as exc:
                logger.error('Failed to updated account', status=exc.status_code)
                raise exc
            logger.info('Successfully updated account', party_id=party_id)
            success_panel = create_success_message(attributes_changed, "We have updated your ")
            flash(success_panel)
        if is_account_email_change_enabled:
            is_email_update_required = form['email_address'].data != respondent_details['emailAddress']
            if is_email_update_required:
                return render_template('account/account-change-email-address.html',
                                       new_email=form['email_address'].data,
                                       form=ConfirmEmailChangeForm())
        return redirect(url_for('surveys_bp.get_survey_list', tag='todo'))
    else:
        return render_template('account/account-contact-detail-change.html',
                               form=form, errors=form.errors, respondent=respondent_details,
                               is_email_change_enabled=is_account_email_change_enabled)
Beispiel #16
0
def share_survey_post_email_entry(session):
    form = AccountSurveyShareRecipientEmailForm(request.values)
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    if not form.validate():
        errors = form.errors
        return render_template(
            "surveys/surveys-share/recipient-email-address.html",
            form=form,
            errors=errors)

    if "emailAddress" in respondent_details:
        if respondent_details["emailAddress"].lower(
        ) == form.data["email_address"].lower():
            errors = {
                "email_address": ["You can not share surveys with yourself."]
            }
            return render_template(
                "surveys/surveys-share/recipient-email-address.html",
                form=form,
                errors=errors)
    flask_session["share_survey_recipient_email_address"] = form.data[
        "email_address"]
    return redirect(url_for("account_bp.send_instruction_get"))
def get_share_survey_summary(token):
    """
    Endpoint to verify token and retrieve the summary page
    :param token: share survey token
    :type token: str
    """
    logger.info("Getting share survey summary", token=token)
    try:
        response = party_controller.verify_pending_survey_token(token)
        pending_share_surveys = response.json()
        share_dict = {}
        distinct_businesses = set()
        batch_number = pending_share_surveys[0]["batch_no"]
        originator_party = party_controller.get_respondent_party_by_id(
            pending_share_surveys[0]["shared_by"])
        shared_by = originator_party["emailAddress"]
        for pending_share_survey in pending_share_surveys:
            distinct_businesses.add(pending_share_survey["business_id"])
        for business_id in distinct_businesses:
            business_surveys = []
            for pending_share_survey in pending_share_surveys:
                if pending_share_survey["business_id"] == business_id:
                    business_surveys.append(
                        survey_controller.get_survey(
                            app.config["SURVEY_URL"], app.config["BASIC_AUTH"],
                            pending_share_survey["survey_id"]))
            selected_business = get_business_by_id(business_id)
            share_dict[selected_business[0]["id"]] = {
                "name": selected_business[0]["name"],
                "trading_as": selected_business[0]["trading_as"],
                "surveys": business_surveys,
            }
        return render_template("surveys/surveys-share/summary.html",
                               share_dict=share_dict,
                               batch_no=batch_number,
                               shared_by=shared_by)

    except ApiError as exc:
        # Handle api errors
        if exc.status_code == 409:
            logger.info(
                "Expired share survey email verification token",
                token=token,
                api_url=exc.url,
                api_status_code=exc.status_code,
            )
            return render_template("surveys/surveys-link-expired.html",
                                   is_transfer=False)
        elif exc.status_code == 404:
            logger.warning(
                "Unrecognised share survey email verification token",
                token=token,
                api_url=exc.url,
                api_status_code=exc.status_code,
            )
            return render_template("surveys/surveys-link-not-valid.html",
                                   is_transfer=False)
        else:
            logger.info("Failed to verify share survey email",
                        token=token,
                        api_url=exc.url,
                        api_status_code=exc.status_code)
            raise exc
def get_survey_list(session, tag):
    """
    Displays the list of surveys for the respondent by tag.  A tag represents the state the
    survey is in (e.g., todo, history, etc)
    """
    flask_session.pop("help_survey_ref", None)
    flask_session.pop("help_ru_ref", None)
    party_id = session.get_party_id()
    business_id = request.args.get("business_party_id")
    survey_id = request.args.get("survey_id")
    already_enrolled = request.args.get("already_enrolled")
    logger.info(
        "Retrieving survey list",
        party_id=party_id,
        business_id=business_id,
        survey_id=survey_id,
        already_enrolled=already_enrolled,
        tag=tag,
    )

    # This logic is added to make sure a user is provided an option to delete an account if there is no
    # active enrolment which is ENABLED
    respondent = party_controller.get_respondent_party_by_id(party_id)
    delete_option_allowed = is_delete_account_respondent_allowed(respondent)

    survey_list = party_controller.get_survey_list_details_for_party(
        respondent, tag, business_party_id=business_id, survey_id=survey_id)
    sorted_survey_list = sorted(
        survey_list,
        key=lambda k: datetime.strptime(k["submit_by"], "%d %b %Y"),
        reverse=True)
    logger.info(
        "Successfully retrieved survey list",
        party_id=party_id,
        business_id=business_id,
        survey_id=survey_id,
        already_enrolled=already_enrolled,
        tag=tag,
    )

    unread_message_count = {
        "unread_message_count":
        conversation_controller.try_message_count_from_session(session)
    }
    if tag == "todo":
        added_survey = True if business_id and survey_id and not already_enrolled else None
        response = make_response(
            render_template(
                "surveys/surveys-todo.html",
                sorted_surveys_list=sorted_survey_list,
                added_survey=added_survey,
                already_enrolled=already_enrolled,
                unread_message_count=unread_message_count,
                delete_option_allowed=delete_option_allowed,
            ))

        # Ensure any return to list of surveys (e.g. browser back) round trips the server to display the latest statuses
        response.headers.set("Cache-Control",
                             "no-cache, max-age=0, must-revalidate, no-store")

        return response
    else:
        return render_template(
            "surveys/surveys-history.html",
            sorted_surveys_list=sorted_survey_list,
            history=True,
            unread_message_count=unread_message_count,
        )
Beispiel #19
0
def get_account(session):
    form = OptionsForm()
    party_id = session.get_party_id()
    respondent_details = party_controller.get_respondent_party_by_id(party_id)
    return render_template("account/account.html", form=form, respondent=respondent_details)