Exemple #1
0
    def reset_request(self):
        """Sends a reset password email"""

        schema = RELS['v1.AuthView:reset'][request.method]
        args = request_reset_password_options.parse_args()
        email = args.get('email')

        user = User.find(email=email).first()

        if not user:
            return dict(status=409, message="Invalid email address"), 409

        token = generate_reset_password_token(user)

        reset_link = urljoin(current_app.config['CLIENT_DOMAIN'], '/#/reset/'+token)

        #TODO this mail send should be performed asynchronously using celery, see issue #88850472
        send_message(
            subject='FogMine Reset Request',
            sender="*****@*****.**",
            recipients = [user.email],
            html_body=render_template('email/reset.html', user=user, reset_link=reset_link),
            text_body=render_template('email/reset.txt', user=user, reset_link=reset_link)
        )

        return dict(status=200, message="Reset instructions sent")
Exemple #2
0
def send_migration_instructions(email):
    '''
    Send migration instructions to the user with the given email.
    '''

    user = get_user_with_email(email)
    token = generate_reset_password_token(user)

    path = url_for_security('reset_password', token=token)
    reset_link = '%s%s' % (get_origin(), path)
    context = dict(
        user=user,
        reset_link=reset_link
    )
    subject = render_template('noi1/migration_email_subject.txt', **context)

    msg = Message(
        subject.strip(),
        sender=current_app.config['SECURITY_EMAIL_SENDER'],
        recipients=[user.email]
    )
    msg.body = render_template('noi1/migration_email.txt', **context)

    mail = current_app.extensions.get('mail')
    mail.send(msg)

    if user.noi1_migration_info:
        user.noi1_migration_info.email_sent_at = datetime.datetime.now()
        db.session.add(user)
        db.session.commit()
Exemple #3
0
def send_migration_instructions(email):
    '''
    Send migration instructions to the user with the given email.
    '''

    user = get_user_with_email(email)
    token = generate_reset_password_token(user)

    path = url_for_security('reset_password', token=token)
    reset_link = '%s%s' % (get_origin(), path)
    context = dict(user=user, reset_link=reset_link)
    subject = render_template('noi1/migration_email_subject.txt', **context)

    msg = Message(subject.strip(),
                  sender=current_app.config['SECURITY_EMAIL_SENDER'],
                  recipients=[user.email])
    msg.body = render_template('noi1/migration_email.txt', **context)

    mail = current_app.extensions.get('mail')
    mail.send(msg)

    if user.noi1_migration_info:
        user.noi1_migration_info.email_sent_at = datetime.datetime.now()
        db.session.add(user)
        db.session.commit()
def test_reset_password_view(api):
    from flask_security.recoverable import generate_reset_password_token
    app = api
    with app.app_context():
        normal_user = create_test_user(email='*****@*****.**')
        # Generate token
        token = generate_reset_password_token(normal_user)
        db.session.commit()
        with app.test_client() as client:
            url = url_for('invenio_accounts_rest_auth.reset_password')
            res = client.post(url,
                              data=dict(password='******', token=token))
            payload = get_json(res)
            assert res.status_code == 200
            assert 'You successfully reset your password' in payload['message']

            # Login using new password
            res = client.post(url,
                              data=dict(email='*****@*****.**',
                                        password='******'))
            payload = get_json(res)
            assert res.status_code == 200
            assert payload['id'] == normal_user.id
            assert payload['email'] == normal_user.email
            session_cookie = next(c for c in client.cookie_jar
                                  if c.name == 'session')
            assert session_cookie is not None
            assert session_cookie.value
Exemple #5
0
def default_reset_password_link_func(user):
    """Return the reset password link that will be sent to a user via email."""
    token = generate_reset_password_token(user)
    endpoint = current_app.config[
        "ACCOUNTS_RESET_PASSWORD_ENDPOINT"] or get_security_endpoint_name(
            "reset_password")
    return token, _generate_token_url(endpoint, token)
Exemple #6
0
def send_welcome_email(user_record, user):
    """Send this email when user is created from backend.

    :param user_record: User record.
    :param user: User account.
    """
    user_record = user_record.replace_refs()
    code = user_record['organisation'].get('code', '')
    plain_platform_name = 'SONAR'
    pname = platform_name(user_record['organisation'])
    if pname:
        plain_platform_name = pname

    token = generate_reset_password_token(user)
    reset_link = url_for_security(
        'reset_password',
        token=token,
        next=f'/{code}',
        _external=True
    )

    send_email(
        [user_record['email']],
        f'{_("Welcome to")} {plain_platform_name}',
        'users/email/welcome', {
            'user': user_record,
            'reset_link': reset_link,
            'platform_name': plain_platform_name
        }
    )
Exemple #7
0
    def user_postprocessor_post(result=None, **kw):
        """Create an User specific POST postprocessor.

        Accepts a single argument, `result`, which is the dictionary
        representation of the created instance of the model.
        """
        logger.info('`user_postprocessor_post` used for endpoint')

        authorization = verify_authorization()
        role = verify_roles(authorization, ['admin'])
        """
        HACK: We really shouldn't be doing this, however, it's quicker and
              more straight forward than converting the <dict> to enable
              dot sytnax that is compatible with Flask-Security

        """
        user = db.session.query(Model).get(result['id'])
        """
        Sends the reset password instructions email for the specified user.

        :param user: The user to send the instructions to

        """
        token = generate_reset_password_token(user)
        reset_link = url_for_security('reset_password',
                                      token=token,
                                      _external=True)

        send_mail('An administrator has created an account for you',
                  user.email,
                  'staff',
                  user=user,
                  confirmation_link=reset_link)
Exemple #8
0
def resend_invitation(user_id):
    """
    For the purpose of re-sending a lost "activation" email, this endpoint allows 
    an admin to re-send that message. 
    This is a convenience option in the admin's dashboard (on the individual user's profile) but it 
    is no different than the reset password flow. We simply generate a reset password token and send the 
    email using our "invite" custom template. 
    Something to note: You can instruct your users who might have misplaced their "activation" email to just 
    use the password reset link from the login page. It's the same flow and they can request a new password 
    with their email address. 
    """
    user = Users.query.get(user_id)
    try:
        link = url_for_security('reset_password',
                                token=generate_reset_password_token(user),
                                _external=True)
        subject = 'Activate your account for the Health Tracker'
        if Config.ORG:
            subject = f'Activate your account for the {Config.ORG} Health Tracker'
        send_mail(subject, user.email, 'invite_new_user', reset_link=link)
        flash('User invitation email was sent.', category='success')
    except Exception as e:
        app.logger.debug(e)
        db.session.rollback()
        flash('User invitation email was not sent, there was an error',
              category='error')
    return redirect(url_for('single_user', id=user_id))
Exemple #9
0
def reset_password(email):
    """Sends the reset password instructions email for the specified email.
    :param email: The email to send the instructions to
    """
    user = User.query.filter_by(email=email).first()
    token = generate_reset_password_token(user) if user else None
    name = user.name if user else None
    send_reset_mail(email, token, name)
Exemple #10
0
    def send_reset_password_instructions(user):
        """Sends the reset password instructions email for the specified user.

        :param user: The user to send the instructions to
        """
        token = generate_reset_password_token(user)
        reset_link = url_for('browser.reset_password', token=token,
                             _external=True)

        send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'), user.email,
                  'reset_instructions',
                  user=user, reset_link=reset_link)

        reset_password_instructions_sent.send(
            current_app._get_current_object(),
            user=user, token=token)
Exemple #11
0
    def send_reset_password_instructions(user):
        """Sends the reset password instructions email for the specified user.

        :param user: The user to send the instructions to
        """
        token = generate_reset_password_token(user)
        reset_link = url_for('browser.reset_password', token=token,
                             _external=True)

        send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'), user.email,
                  'reset_instructions',
                  user=user, reset_link=reset_link)

        reset_password_instructions_sent.send(
            current_app._get_current_object(),
            user=user, token=token)
Exemple #12
0
def test_forgot_password_token(app, users, sleep, expired):
    """Test expiration of token for password reset."""
    token = generate_reset_password_token(users[0]["obj"])
    reset_link = url_for_security("reset_password", token=token)

    with app.test_client() as client:
        res = client.get(reset_link, follow_redirects=True)
        time.sleep(sleep)
        if expired:
            app.config["SECURITY_MSG_PASSWORD_RESET_EXPIRED"][0] % {
                "within": app.config["SECURITY_RESET_PASSWORD_WITHIN"],
                "email": users[0]["email"],
            } in res.get_data(as_text=True)
        else:
            assert ('<button type="submit" class="btn btn-primary btn-lg '
                    'btn-block">Reset Password</button>') in res.get_data(
                        as_text=True)
Exemple #13
0
def send_reset_password_instructions(user):
    """Sends the reset password instructions email for the specified user.
    :param user: The user to send the instructions to
    """
    token = generate_reset_password_token(user)

    url_data = urlparse(request.base_url)
    reset_link = f"{url_data.scheme}://{url_data.netloc}/#resetpass/{token}/"

    if config_value('SEND_PASSWORD_RESET_EMAIL'):
        send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'),
                            user.email, 'reset_instructions',
                            user=user, reset_link=reset_link)

    reset_password_instructions_sent.send(
        app._get_current_object(), user=user, token=token
    )
Exemple #14
0
def test_disabled_forgot_password_view(api):
    from flask_security.recoverable import generate_reset_password_token
    app = api
    app.config["SECURITY_RECOVERABLE"] = False
    app.extensions["security"].recoverable = False

    with app.app_context():
        user = create_test_user(email='*****@*****.**')
        token = generate_reset_password_token(user)
        db.session.commit()
        with app.test_client() as client:
            url = url_for('invenio_accounts_rest_auth.forgot_password')
            res = client.post(url, data={"email": user.email})
            payload = get_json(res)

            assert res.status_code != 200
            expected = app.config["SECURITY_MSG_PASSWORD_RECOVERY_DISABLED"][0]
            assert payload["message"] == expected
Exemple #15
0
def send_welcome_email(user_record, user):
    """Send this email when user is created from backend.

    :param user_record: User record.
    :param user: User account.
    """
    user_record = user_record.replace_refs()

    token = generate_reset_password_token(user)
    reset_link = url_for_security('reset_password',
                                  token=token,
                                  _external=True)

    send_email([user_record['email']], _('Welcome on SONAR'),
               'users/email/welcome', {
                   'user': user_record,
                   'reset_link': reset_link
               })
def test_forgot_password_token(app, users, sleep, expired):
    """Test expiration of token for password reset."""
    token = generate_reset_password_token(users[0]['obj'])
    reset_link = url_for_security('reset_password', token=token)

    with app.test_client() as client:
        res = client.get(reset_link, follow_redirects=True)
        time.sleep(sleep)
        if expired:
            app.config['SECURITY_MSG_PASSWORD_RESET_EXPIRED'][0] % {
                'within': app.config['SECURITY_RESET_PASSWORD_WITHIN'],
                'email': users[0]['email']
            } in res.get_data(as_text=True)
        else:
            assert (
                '<button type="submit" class="btn btn-primary btn-lg '
                'btn-block">Reset Password</button>'
            ) in res.get_data(as_text=True)
Exemple #17
0
def send_reset_password_instructions(user):
    """Sends the reset password instructions email for the specified user.
    :param user: The user to send the instructions to
    """
    token = generate_reset_password_token(user)
    reset_link = frontend_url('reset-password', token=token)

    print(f"[+] The security is {_security}")

    if config_value('SEND_PASSWORD_RESET_EMAIL'):
        send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'),
                  user.email,
                  'reset_instructions',
                  user=user,
                  reset_link=reset_link)

    reset_password_instructions_sent.send(app._get_current_object(),
                                          user=user,
                                          token=token)
Exemple #18
0
def new_user():
    """
    new_user is a route used exclusively by system admins to add new users to the system. 
    There is no public registration page for this application (per the flask-security settings), 
    users must be added by an admin. 
    We will prompt for an email, username, and role, then create the user and send an email 
    informing them that they have been added to the system and must change their password. 
    The change password step is required as the temp password we generated for them is never 
    revealed, just hashed and stored to protect the account from un-authorized logins while the 
    confirmation process plays out. 
    """
    form = AddUser()
    if form.validate_on_submit():
        new_user = user_datastore.find_user(email=form.email.data)
        if new_user:
            flash(
                'User with given email address already exists. User not created.',
                category='error')
            return redirect(url_for('new_user'))
        """
        Try and create the new user with given email, username, and role. 
        Assign them a temp password. 
        Users should be activated by default but for some reason we needed to 
        manually activate. 
        """
        try:
            new_user = user_datastore.create_user(email=form.email.data,
                                                  username=form.username.data,
                                                  password=hash_password(
                                                      Users.random_password()))
            role = user_datastore.find_role(form.roles.data)
            user_datastore.add_role_to_user(new_user, role)
            user_datastore.activate_user(new_user)
            db.session.commit()
        except Exception as e:
            app.logger.debug(e)
            db.session.rollback()
            flash(
                'There was an error creating this user. Please try again before reporting.',
                category='error')
            return redirect(url_for('new_user'))
        """
        Now that we have a new user, we're going to try and send them their "activation" link via email. 
        We're really just making use of the built-in password reset function, so generate a new reset token 
        and send the mail via the flask-security send_mail func. 
        This sequence makes use of a custom email template.
        """
        try:
            link = url_for_security(
                'reset_password',
                token=generate_reset_password_token(new_user),
                _external=True)
            subject = 'Activate your account for the Health Tracker'

            if Config.ORG:
                subject = f'Activate your account for the {Config.ORG} Health Tracker'
            send_mail(subject,
                      new_user.email,
                      'invite_new_user',
                      reset_link=link)
        except Exception as e:
            db.session.rollback()
            flash('New user was created but invitation email was not sent.',
                  category='error')
            return redirect(url_for('new_user'))

        flash(
            f'New user "{new_user.username}" was created and invitation email sent.',
            category='success')
        return redirect(url_for('new_user'))
    return render_template('new_user.html', form=form)