<commit_before># -*- coding: utf-8 -*-
"""
    flask.ext.security.recoverable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Flask-Security recoverable module

    :copyright: (c) 2012 by <NAME>.
    :license: MIT, see LICENSE for more details.
"""

from itsdangerous import BadSignature, SignatureExpired
from flask import current_app as app, request, url_for
from werkzeug.local import LocalProxy

from .exceptions import ResetPasswordError, UserNotFoundError
from .signals import password_reset, password_reset_requested, \
     reset_instructions_sent
from .utils import send_mail, get_max_age, md5, get_message, encrypt_password


# Convenient references
_security = LocalProxy(lambda: app.extensions['security'])

_datastore = LocalProxy(lambda: _security.datastore)


def send_reset_password_instructions(user, reset_token):
    """Sends the reset password instructions email for the specified user.

    :param user: The user to send the instructions to
    """
    url = url_for('flask_security.reset_password',
                  token=reset_token)

    reset_link = request.url_root[:-1] + url

    send_mail('Password reset instructions',
              user.email,
              'reset_instructions',
              dict(user=user, reset_link=reset_link))

    reset_instructions_sent.send(dict(user=user, token=reset_token),
                                 app=app._get_current_object())

    return True


def send_password_reset_notice(user):
    """Sends the password reset notice email for the specified user.

    :param user: The user to send the notice to
    """
    send_mail('Your password has been reset',
              user.email,
              'reset_notice',
              dict(user=user))


def generate_reset_password_token(user):
    """Generates a unique reset password token for the specified user.

    :param user: The user to work with
    """
    data = [user.id, md5(user.password)]
    return _security.reset_serializer.dumps(data)


def reset_by_token(token, password):
    """Resets the password of the user given the specified token, email and
    password. If the token is invalid a `ResetPasswordError` error will be
    raised. If the token is expired a `TokenExpiredError` error will be raised.

    :param token: The user's reset password token
    :param email: The user's email address
    :param password: The user'<PASSWORD>
    """
    serializer = _security.reset_serializer
    max_age = get_max_age('RESET_PASSWORD')

    try:
        data = serializer.loads(token, max_age=max_age)
        user = _datastore.find_user(id=data[0])

        if md5(user.password) != data[1]:
            raise UserNotFoundError()

        user.password = <PASSWORD>_password(password,
                                         salt=_security.password_salt,
                                         use_hmac=_security.password_hmac)
        print user.password
        _datastore._save_model(user)

        send_password_reset_notice(user)

        password_reset.send(user, app=app._get_current_object())

        return user<commit_msg>Remove stray print statement<commit_after># -*- coding: utf-8 -*-
"""
    flask.ext.security.recoverable
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Flask-Security recoverable module

    :copyright: (c) 2012 by <NAME>.
    :license: MIT, see LICENSE for more details.
"""

from itsdangerous import BadSignature, SignatureExpired
from flask import current_app as app, request, url_for
from werkzeug.local import LocalProxy

from .exceptions import ResetPasswordError, UserNotFoundError
from .signals import password_reset, password_reset_requested, \
     reset_instructions_sent
from .utils import send_mail, get_max_age, md5, get_message, encrypt_password


# Convenient references
_security = LocalProxy(lambda: app.extensions['security'])

_datastore = LocalProxy(lambda: _security.datastore)


def send_reset_password_instructions(user, reset_token):
    """Sends the reset password instructions email for the specified user.

    :param user: The user to send the instructions to
    """
    url = url_for('flask_security.reset_password',
                  token=reset_token)

    reset_link = request.url_root[:-1] + url

    send_mail('Password reset instructions',
              user.email,
              'reset_instructions',
              dict(user=user, reset_link=reset_link))

    reset_instructions_sent.send(dict(user=user, token=reset_token),
                                 app=app._get_current_object())

    return True


def send_password_reset_notice(user):
    """Sends the password reset notice email for the specified user.

    :param user: The user to send the notice to
    """
    send_mail('Your password has been reset',
              user.email,
              'reset_notice',
              dict(user=user))


def generate_reset_password_token(user):
    """Generates a unique reset password token for the specified user.

    :param user: The user to work with
    """
    data = [user.id, md5(user.password)]
    return _security.reset_serializer.dumps(data)


def reset_by_token(token, password):
    """Resets the password of the user given the specified token, email and
    password. If the token is invalid a `ResetPasswordError` error will be
    raised. If the token is expired a `TokenExpiredError` error will be raised.

    :param token: The user's reset password token
    :param email: The user's email address
    :param password: <PASSWORD>
    """
    serializer = _security.reset_serializer
    max_age = get_max_age('RESET_PASSWORD')

    try:
        data = serializer.loads(token, max_age=max_age)
        user = _datastore.find_user(id=data[0])

        if md5(user.password) != data[1]:
            raise UserNotFoundError()

        user.password = <PASSWORD>(password,
                                         salt=_security.password_salt,
                                         use_hmac=_security.password_hmac)

        _datastore._save_model(user)

        send_password_reset_notice(user)

        password_reset.send(user, app=app._get_current_object())

        return user
{'fraction_non_alphanumeric': 0.09281731715316498, 'fraction_numerical': 0.0036077402427025255, 'mean_word_length': 2.983670803396473, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6318231', 'n_tokens_mistral': 1728, 'n_tokens_neox': 1663, 'n_words': 475}