Exemple #1
0
 def test_a_unsuccessful_send_to_pub_sub_with_exception(self):
     with self.app.app_context():
         future = MagicMock()
         future.result.side_effect = Exception("bad")
         publisher = MagicMock()
         publisher.publish.return_value = future
         notify = NotifyController()
         notify.publisher = publisher
         with self.assertRaises(NotifyError):
             notify.request_to_notify(
                 email="*****@*****.**",
                 template_name="request_password_change",
                 personalisation=None)
Exemple #2
0
def send_create_account_email(email):
    """Sends an email through GovNotify to the specified address with an encoded link to verify their email

    :param email: The email address to send to
    """
    url_safe_serializer = URLSafeSerializer(app.config["SECRET_KEY"])

    response = uaa_controller.get_user_by_email(email)
    if response is None:
        return render_template("request-new-account-error.html")

    if response["totalResults"] == 0:
        internal_url = app.config["RESPONSE_OPERATIONS_UI_URL"]
        verification_url = f"{internal_url}/account/create-account/{token_decoder.generate_email_token(email)}"

        logger.info("Sending create account email", verification_url=verification_url)

        personalisation = {"CREATE_ACCOUNT_URL": verification_url, "EMAIL": email}

        try:
            NotifyController().request_to_notify(
                email=email, template_name="request_create_account", personalisation=personalisation
            )
        except NotifyError as e:
            logger.error("Error sending create account request email to Notify Gateway", msg=e.description)
            return render_template("request-new-account-error.html")

        logger.info("Successfully sent create account request email", encoded_email=url_safe_serializer.dumps(email))
    else:
        logger.info(
            "Requested account creation for email already in UAA", encoded_email=url_safe_serializer.dumps(email)
        )
        return render_template("request-new-account-exists.html", email=email)

    return render_template("request-new-account-check-email.html", email=email)
Exemple #3
0
def send_update_account_email(token_dict, first_name):
    """Sends an email through GovNotify to the specified address with an encoded
     link to verify their email when it has been changed

    :param token_dict: A dictionary containing the email address to send to and user id
    :param first_name: the name of the user the email is being sent to, used in email
    """
    response = uaa_controller.get_user_by_email(token_dict["email"])
    if response is None:
        return render_template("request-new-account-error.html")

    if response["totalResults"] == 0:
        internal_url = app.config["RESPONSE_OPERATIONS_UI_URL"]
        verification_url = (
            f"{internal_url}/account/verify-email/{token_decoder.generate_email_token(json.dumps(token_dict))}"
        )

        logger.info("Sending update account verification email", verification_url=verification_url)
        personalisation = {"CONFIRM_EMAIL_URL": verification_url, "first_name": first_name}
        NotifyController().request_to_notify(
            email=token_dict["email"], template_name="update_email", personalisation=personalisation
        )
    else:
        url_safe_serializer = URLSafeSerializer(app.config["SECRET_KEY"])
        logger.info(
            "Requested account creation for email already in UAA",
            encoded_email=url_safe_serializer.dumps(token_dict["email"]),
        )
        flash("Email already in use", category="error")
Exemple #4
0
    def test_a_successful_send_to_pub_sub(self):
        with self.app.app_context():
            publisher = MagicMock()
            publisher.topic_path.return_value = 'projects/test-project-id/topics/ras-rm-notify-test'
            notify = NotifyController()
            notify.publisher = publisher
            result = notify.request_to_notify(
                email='*****@*****.**',
                template_name='request_password_change',
                personalisation=None)
            data = b'{"notify": {"email_address": "*****@*****.**", ' \
                   b'"template_id": "request_password_change_id", "personalisation": {}}}'

            publisher.publish.assert_called()
            publisher.publish.assert_called_with(
                'projects/test-project-id/topics/ras-rm-notify-test',
                data=data)
            self.assertIsNone(result)
 def test_an_unsuccessful_send(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.POST,
                  url_send_notify,
                  json={'emailAddress': '*****@*****.**'},
                  status=500)
         with self.app.app_context():
             with self.assertRaises(NotifyError):
                 NotifyController().request_to_notify(
                     email='*****@*****.**',
                     template_name='request_password_change')
Exemple #6
0
def send_confirm_created_email(email, first_name):
    personalisation = {"FIRST_NAME": first_name}

    try:
        NotifyController().request_to_notify(
            email=email, template_name="confirm_create_account", personalisation=personalisation
        )
    except NotifyError as e:
        # This shouldn't show the client an error - the account creation was still successful.
        # They just won't get a confirmation email
        logger.error("Error sending account creation confirmation email to Notify Gateway", msg=e.description)
Exemple #7
0
    def test_a_successful_send_to_pub_sub_with_personalisation(self):
        with self.app.app_context():
            publisher = MagicMock()
            publisher.topic_path.return_value = "projects/test-project-id/topics/ras-rm-notify-test"
            notify = NotifyController()
            notify.publisher = publisher
            personalisation = {
                "first_name": "firstname",
                "last_name": "surname"
            }
            result = notify.request_to_notify(
                email="*****@*****.**",
                template_name="request_password_change",
                personalisation=personalisation)
            data = (
                b'{"notify": {"email_address": "*****@*****.**", '
                b'"template_id": "request_password_change_id", "personalisation": {"first_name": "firstname", '
                b'"last_name": "surname"}}}')

            publisher.publish.assert_called()
            publisher.publish.assert_called_with(
                "projects/test-project-id/topics/ras-rm-notify-test",
                data=data)
            self.assertIsNone(result)
def send_confirm_change_email(email):
    user = uaa_controller.get_user_by_email(email)
    first_name = user['resources'][0]['name']['givenName']
    if first_name != "":
        personalisation = {'FIRST_NAME': first_name}

        try:
            NotifyController().request_to_notify(
                email=email,
                template_name='confirm_password_change',
                personalisation=personalisation)
        except NotifyError as e:
            # This shouldn't show the client an error - the password change was still successful.
            # They just won't get a confirmation email
            logger.error(
                'Error sending password change confirmation email to Notify Gateway',
                msg=e.description)
 def test_a_successful_send(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.POST,
                  url_send_notify,
                  json={'emailAddress': '*****@*****.**'},
                  status=201)
         with self.app.app_context():
             try:
                 NotifyController().request_to_notify(
                     email='*****@*****.**',
                     template_name='request_password_change')
             except NotifyError:
                 self.fail('NotifyController didnt properly handle a 201')
             except KeyError:
                 self.fail(
                     'NotifyController couldnt find the template ID request_password_change'
                 )
Exemple #10
0
def change_password():
    form = ChangePasswordFrom()
    user_id = session["user_id"]
    user_from_uaa = uaa_controller.get_user_by_id(user_id)
    if request.method == "POST" and form.validate():
        password = form["password"].data
        new_password = form["new_password"].data
        if new_password == password:
            return render_template(
                "account/change-password.html",
                form=form,
                errors={"new_password": ["Your new password is the same as your old password"]},
            )
        logger.info("Sending account password acknowledgement email", user_id=user_id)
        personalisation = {"first_name": user_from_uaa["name"]["givenName"]}
        uaa_errors = uaa_controller.update_user_password(user_from_uaa, password, new_password)
        if uaa_errors is None:
            try:
                NotifyController().request_to_notify(
                    email=user_from_uaa["emails"][0]["value"],  # it's safe to assume that zeroth element is primary in
                    # RAS/RM case
                    template_name="update_account_password",
                    personalisation=personalisation,
                )
            except NotifyError as e:
                logger.error(
                    "Error sending change of password acknowledgement email to Notify Gateway", msg=e.description
                )
                flash("We were unable to send the password change acknowledgement email.", category="warn")
            flash("Your password has been changed", category="successful_signout")
            return redirect(url_for("logout_bp.logout"))
        else:
            logger.error("Error changing user password", msg=uaa_errors)
            if uaa_errors["status_code"] == 401:
                flash(
                    "your current password is incorrect. Please re-enter a correct current password.",
                    category="error",
                )
            else:
                flash(
                    "Something went wrong while updating your username. Please try again.",
                    category="error",
                )
    errors = form.errors
    return render_template("account/change-password.html", form=form, errors=errors)
Exemple #11
0
def change_username():
    form = UsernameChangeForm()
    user_id = session["user_id"]
    user_from_uaa = uaa_controller.get_user_by_id(user_id)
    username = user_from_uaa["userName"]
    username_exists = False
    if request.method == "POST" and form.validate():
        if form["username"].data != username:
            user_from_uaa["userName"] = form["username"].data
            logger.info("Sending update account details email", user_id=user_id)
            personalisation = {
                "first_name": user_from_uaa["name"]["givenName"],
                "value_name": "username",
                "changed_value": form["username"].data,
            }
            try:
                NotifyController().request_to_notify(
                    email=user_from_uaa["emails"][0]["value"],
                    template_name="update_account_details",
                    personalisation=personalisation,
                )
                uaa_errors = uaa_controller.update_user_account(user_from_uaa)
                if uaa_errors is None:
                    flash("Your username has been changed", category="successful_signout")
                    return redirect(url_for("logout_bp.logout"))
                elif uaa_errors["status_code"] == 400:
                    username_exists = True
                else:
                    logger.error("Error changing user information", msg=uaa_errors)
                    flash(
                        "Something went wrong. Please ignore the email you have received and try again",
                        category="error",
                    )
            except NotifyError as e:
                logger.error(
                    "Error sending change of username acknowledgement email to Notify Gateway", msg=e.description
                )
                flash("Something went wrong while updating your username. Please try again", category="error")
        else:
            return redirect(url_for("account_bp.get_my_account"))
    errors = form.errors
    if username_exists:
        errors = {"username": [uaa_errors["message"]]}
    return render_template("account/change-username.html", username=username, form=form, errors=errors)
def send_password_change_email(email):
    url_safe_serializer = URLSafeSerializer(app.config['SECRET_KEY'])

    response = uaa_controller.get_user_by_email(email)
    if response is None:
        return render_template('forgot-password-error.html')

    if response['totalResults'] > 0:
        first_name = response['resources'][0]['name']['givenName']
        internal_url = app.config['RESPONSE_OPERATIONS_UI_URL']
        verification_url = f'{internal_url}/passwords/reset-password/{token_decoder.generate_email_token(email)}'

        logger.info('Sending password change email',
                    verification_url=verification_url)

        personalisation = {
            'RESET_PASSWORD_URL': verification_url,
            'FIRST_NAME': first_name
        }

        try:
            NotifyController().request_to_notify(
                email=email,
                template_name='request_password_change',
                personalisation=personalisation)
        except NotifyError as e:
            logger.error(
                'Error sending password change request email to Notify Gateway',
                msg=e.description)
            return render_template('forgot-password-error.html')

        logger.info('Successfully sent password change request email',
                    email=url_safe_serializer.dumps(email))
    else:
        # We still want to render the template for an email without an account to avoid
        # people fishing for valid emails
        logger.info('Requested password reset for email not in UAA',
                    email=url_safe_serializer.dumps(email))

    return redirect(
        url_for('passwords_bp.forgot_password_check_email',
                email=url_safe_serializer.dumps(email)))
def send_password_change_email(email):
    url_safe_serializer = URLSafeSerializer(app.config["SECRET_KEY"])

    response = uaa_controller.get_user_by_email(email)
    if response is None:
        return render_template("forgot-password-error.html")

    if response["totalResults"] > 0:
        first_name = response["resources"][0]["name"]["givenName"]
        internal_url = app.config["RESPONSE_OPERATIONS_UI_URL"]
        verification_url = f"{internal_url}/passwords/reset-password/{token_decoder.generate_email_token(email)}"

        logger.info("Sending password change email",
                    verification_url=verification_url)

        personalisation = {
            "RESET_PASSWORD_URL": verification_url,
            "FIRST_NAME": first_name
        }

        try:
            NotifyController().request_to_notify(
                email=email,
                template_name="request_password_change",
                personalisation=personalisation)
        except NotifyError as e:
            logger.error(
                "Error sending password change request email to Notify Gateway",
                msg=e.description)
            return render_template("forgot-password-error.html")

        logger.info("Successfully sent password change request email",
                    email=url_safe_serializer.dumps(email))
    else:
        # We still want to render the template for an email without an account to avoid
        # people fishing for valid emails
        logger.info("Requested password reset for email not in UAA",
                    email=url_safe_serializer.dumps(email))

    return redirect(
        url_for("passwords_bp.forgot_password_check_email",
                email=url_safe_serializer.dumps(email)))
Exemple #14
0
def change_account_name():
    form = ChangeAccountName()
    user_id = session["user_id"]
    user_from_uaa = uaa_controller.get_user_by_id(user_id)
    user = {
        "first_name": f"{user_from_uaa['name']['givenName']}",
        "last_name": f"{user_from_uaa['name']['familyName']}",
    }
    if request.method == "POST" and form.validate():
        if (form.data["first_name"] != user["first_name"]) or (form.data["last_name"] != user["last_name"]):
            user_from_uaa["name"] = {"familyName": form.data["last_name"], "givenName": form.data["first_name"]}
            full_name = f"{form.data['first_name']} {form.data['last_name']}"
            logger.info("Sending update account details email", user_id=user_id)
            personalisation = {
                "first_name": user["first_name"],
                "value_name": "name",
                "changed_value": full_name,
            }
            try:
                NotifyController().request_to_notify(
                    email=user_from_uaa["emails"][0]["value"],
                    template_name="update_account_details",
                    personalisation=personalisation,
                )
                errors = uaa_controller.update_user_account(user_from_uaa)
                if errors is None:
                    flash("Your name has been changed", category="successful_signout")
                    return redirect(url_for("logout_bp.logout"))
                else:
                    logger.error("Error changing user information", msg=errors)
                    flash(
                        "Something went wrong. Please ignore the email you have received and try again",
                        category="error",
                    )
            except NotifyError as e:
                logger.error("Error sending change of name acknowledgement email to Notify Gateway", msg=e.description)
                flash("Something went wrong while updating your name. Please try again", category="error")
        else:
            return redirect(url_for("account_bp.get_my_account"))
    return render_template("account/change-account-name.html", user=user, form=form, errors=form.errors)
Exemple #15
0
def change_email():
    url_safe_serializer = URLSafeSerializer(app.config["SECRET_KEY"])
    form = ChangeEmailForm()
    user_id = session["user_id"]
    user_from_uaa = uaa_controller.get_user_by_id(user_id)
    if request.method == "POST" and form.validate():
        if form.data["email_address"] != user_from_uaa["emails"][0]["value"]:
            personalisation = {
                "first_name": user_from_uaa["name"]["givenName"],
                "value_name": "email",
                "changed_value": form.data["email_address"],
            }
            try:
                logger.info("Sending verification email", email=obfuscate_email(form.data["email_address"]))
                token_dict = {"email": form.data["email_address"], "user_id": user_id}
                send_update_account_email(token_dict, user_from_uaa["name"]["givenName"])
                logger.info("Sending notification email")
                NotifyController().request_to_notify(
                    email=user_from_uaa["emails"][0]["value"],
                    template_name="update_account_details",
                    personalisation=personalisation,
                )
                logger.info(
                    "Successfully sent email change email",
                    encoded_email=url_safe_serializer.dumps(form.data["email_address"]),
                )
                flash(
                    "A verification email has been sent. You will need to login to change your email",
                    category="successful_signout",
                )
                return redirect(url_for("logout_bp.logout"))
            except NotifyError as e:
                logger.error("Error sending 'email change' email to Notify Gateway", msg=e.description)
                flash("Something went wrong while updating your email. Please try again", category="error")
        else:
            return redirect(url_for("account_bp.get_my_account"))
    return render_template("account/change-email.html", form=form, errors=form.errors)
 def test_an_invalid_template_id(self):
     with self.app.app_context():
         with self.assertRaises(KeyError):
             NotifyController().request_to_notify(
                 email='*****@*****.**', template_name='fake-template-name')
Exemple #17
0
 def test_an_invalid_template_id(self):
     with self.app.app_context():
         with self.assertRaises(KeyError):
             notify = NotifyController()
             notify._get_template_id(template_name="invalid_template")