Пример #1
0
def recover():
    """
    Enables the user to recover its account when he has forgotten
    its password.
    """
    form = RecoverPasswordForm()
    user_contr = UserController()

    if request.method == 'POST':
        if form.validate():
            user = user_contr.get(email=form.email.data)
            characters = string.ascii_letters + string.digits
            password = "".join(
                random.choice(characters)
                for x in range(random.randint(8, 16)))
            user.set_password(password)
            user_contr.update({'id': user.id}, {'password': password})

            # Send the confirmation email
            try:
                notifications.new_password_notification(user, password)
                flash(gettext('New password sent to your address.'), 'success')
            except Exception as error:
                flash(
                    gettext(
                        'Problem while sending your new password: '******'%(error)s',
                        error=error), 'danger')

            return redirect(url_for('login'))
        return render_template('recover.html', form=form)

    if request.method == 'GET':
        return render_template('recover.html', form=form)
Пример #2
0
def profile_update(user_id):
    ucontr = None
    if admin_permission.can():
        ucontr = UserController()
    elif Permission(UserNeed(user_id)).can():
        ucontr = UserController(user_id)
    else:
        flash(gettext('You do not have rights on this user'), 'danger')
        raise Forbidden(gettext('You do not have rights on this user'))
    user = ucontr.get(id=user_id)
    profile_form, pass_form = ProfileForm(obj=user), PasswordModForm()
    if profile_form.validate():
        values = {'login': profile_form.login.data,
                  'email': profile_form.email.data}
        if admin_permission.can():
            values['is_active'] = profile_form.is_active.data
            values['is_admin'] = profile_form.is_admin.data
            values['is_api'] = profile_form.is_api.data
        ucontr.update({'id': user_id}, values)

        flash(gettext('User %(login)s successfully updated',
                      login=user.login), 'success')
        return redirect(url_for('user.profile', user_id=user.id))

    return render_template('profile.html', user=user,
            admin_permission=admin_permission,
            form=profile_form, pass_form=pass_form)
Пример #3
0
def profile():
    """
    Edit the profile of the currently logged user.
    """
    user_contr = UserController(current_user.id)
    user = user_contr.get(id=current_user.id)
    form = ProfileForm()

    if request.method == 'POST':
        if form.validate():
            try:
                user_contr.update({'id': current_user.id},
                        {'nickname': form.nickname.data,
                        'email': form.email.data,
                        'password': form.password.data,
                        'automatic_crawling': form.automatic_crawling.data,
                        'is_public_profile': form.is_public_profile.data,
                        'bio': form.bio.data,
                        'webpage': form.webpage.data,
                        'twitter': form.twitter.data})
            except Exception as error:
                flash(gettext('Problem while updating your profile: '
                              '%(error)s', error=error), 'danger')
            else:
                flash(gettext('User %(nick)s successfully updated',
                          nick=user.nickname), 'success')
            return redirect(url_for('user.profile'))
        else:
            return render_template('profile.html', user=user, form=form)

    if request.method == 'GET':
        form = ProfileForm(obj=user)
        return render_template('profile.html', user=user, form=form)
Пример #4
0
def process_user_form(user_id=None):
    """
    Create or edit a user.
    """
    form = UserForm()
    user_contr = UserController()

    if not form.validate():
        return render_template('/admin/create_user.html', form=form,
                               message=gettext('Some errors were found'))

    role_user = Role.query.filter(Role.name == "user").first()
    if user_id is not None:
        # Edit a user
        user_contr.update({'id': user_id},
                          {'nickname': form.nickname.data,
                           'email': form.email.data,
                           'password': form.password.data,
                           'refresh_rate': form.refresh_rate.data})
        user = user_contr.get(id=user_id)
        flash(gettext('User %(nick)s successfully updated',
                      nick=user.nickname), 'success')
    else:
        # Create a new user
        user = user_contr.create(nickname=form.nickname.data,
                                 email=form.email.data,
                                 password=form.password.data,
                                 roles=[role_user],
                                 refresh_rate=form.refresh_rate.data,
                                 activation_key="")
        flash(gettext('User %(nick)s successfully created',
                      nick=user.nickname), 'success')
    return redirect(url_for('admin.user_form', user_id=user.id))
Пример #5
0
def profile_update(user_id):
    ucontr = None
    if admin_permission.can():
        ucontr = UserController()
    elif Permission(UserNeed(user_id)).can():
        ucontr = UserController(user_id)
    else:
        flash(gettext('You do not have rights on this user'), 'danger')
        raise Forbidden(gettext('You do not have rights on this user'))
    user = ucontr.get(id=user_id)
    profile_form, pass_form = ProfileForm(obj=user), PasswordModForm()
    if profile_form.validate():
        values = {
            'login': profile_form.login.data,
            'email': profile_form.email.data
        }
        if admin_permission.can():
            values['is_active'] = profile_form.is_active.data
            values['is_admin'] = profile_form.is_admin.data
            values['is_api'] = profile_form.is_api.data
        ucontr.update({'id': user_id}, values)

        flash(gettext('User %(login)s successfully updated', login=user.login),
              'success')
        return redirect(url_for('user.profile', user_id=user.id))

    return render_template('profile.html',
                           user=user,
                           admin_permission=admin_permission,
                           form=profile_form,
                           pass_form=pass_form)
Пример #6
0
def recover():
    """
    Enables the user to recover its account when he has forgotten
    its password.
    """
    form = RecoverPasswordForm()
    user_contr = UserController()

    if request.method == 'POST':
        if form.validate():
            user = user_contr.get(email=form.email.data)
            characters = string.ascii_letters + string.digits
            password = "".join(random.choice(characters)
                               for x in range(random.randint(8, 16)))
            user.set_password(password)
            user_contr.update({'id': user.id}, {'password': password})

            # Send the confirmation email
            try:
                notifications.new_password_notification(user, password)
                flash(gettext('New password sent to your address.'), 'success')
            except Exception as error:
                flash(gettext('Problem while sending your new password: '******'%(error)s', error=error), 'danger')

            return redirect(url_for('login'))
        return render_template('recover.html', form=form)

    if request.method == 'GET':
        return render_template('recover.html', form=form)
Пример #7
0
def process_user_form(user_id=None):
    """
    Create or edit a user.
    """
    form = UserForm()
    user_contr = UserController()

    if not form.validate():
        return render_template('/admin/create_user.html',
                               form=form,
                               message=gettext('Some errors were found'))

    if user_id is not None:
        # Edit a user
        user_contr.update({'id': user_id}, {
            'nickname': form.nickname.data,
            'password': form.password.data,
            'automatic_crawling': form.automatic_crawling.data
        })
        user = user_contr.get(id=user_id)
        flash(
            gettext('User %(nick)s successfully updated', nick=user.nickname),
            'success')
    else:
        # Create a new user (by the admin)
        user = user_contr.create(
            nickname=form.nickname.data,
            pwdhash=generate_password_hash(form.password.data),
            automatic_crawling=form.automatic_crawling.data,
            is_admin=False,
            is_active=True)
        flash(
            gettext('User %(nick)s successfully created', nick=user.nickname),
            'success')
    return redirect(url_for('admin.user_form', user_id=user.id))
Пример #8
0
def profile():
    """
    Edit the profile of the currently logged user.
    """
    user_contr = UserController(g.user.id)
    user = user_contr.get(id=g.user.id)
    form = ProfileForm()

    if request.method == 'POST':
        if form.validate():
            user_contr.update({'id': g.user.id}, {
                'nickname': form.nickname.data,
                'email': form.email.data,
                'password': form.password.data,
                'refresh_rate': form.refresh_rate.data
            })

            flash(
                gettext('User %(nick)s successfully updated',
                        nick=user.nickname), 'success')
            return redirect(url_for('user.profile'))
        else:
            return render_template('profile.html', user=user, form=form)

    if request.method == 'GET':
        form = ProfileForm(obj=user)
        return render_template('profile.html', user=user, form=form)
Пример #9
0
Файл: user.py Проект: bzero/JARR
def profile():
    """
    Edit the profile of the currently logged user.
    """
    user_contr = UserController(g.user.id)
    user = user_contr.get(id=g.user.id)
    form = ProfileForm()

    if request.method == "POST":
        if form.validate():
            user_contr.update(
                {"id": g.user.id},
                {
                    "nickname": form.nickname.data,
                    "email": form.email.data,
                    "password": form.password.data,
                    "refresh_rate": form.refresh_rate.data,
                },
            )

            flash(gettext("User %(nick)s successfully updated", nick=user.nickname), "success")
            return redirect(url_for("user.profile"))
        else:
            return render_template("profile.html", user=user, form=form)

    if request.method == "GET":
        form = ProfileForm(obj=user)
        return render_template("profile.html", user=user, form=form)
Пример #10
0
Файл: user.py Проект: bzero/JARR
def recover():
    """
    Enables the user to recover its account when he has forgotten
    its password.
    """
    form = RecoverPasswordForm()
    user_contr = UserController()

    if request.method == "POST":
        if form.validate():
            user = user_contr.get(email=form.email.data)
            characters = string.ascii_letters + string.digits
            password = "".join(random.choice(characters) for x in range(random.randint(8, 16)))
            user.set_password(password)
            user_contr.update({"id": user.id}, {"password": password})

            # Send the confirmation email
            try:
                notifications.new_password_notification(user, password)
                flash(gettext("New password sent to your address."), "success")
            except Exception as error:
                flash(gettext("Problem while sending your new password: "******"%(error)s", error=error), "danger")

            return redirect(url_for("login"))
        return render_template("recover.html", form=form)

    if request.method == "GET":
        return render_template("recover.html", form=form)
Пример #11
0
def process_user_form(user_id=None):
    """
    Create or edit a user.
    """
    form = UserForm()
    user_contr = UserController()

    if not form.validate():
        return render_template('/admin/create_user.html', form=form,
                               message=gettext('Some errors were found'))

    if user_id is not None:
        # Edit a user
        user_contr.update({'id': user_id},
                          {'nickname': form.nickname.data,
                           'email': form.email.data,
                           'password': form.password.data,
                           'automatic_crawling': form.automatic_crawling.data})
        user = user_contr.get(id=user_id)
        flash(gettext('User %(nick)s successfully updated',
                      nick=user.nickname), 'success')
    else:
        # Create a new user (by the admin)
        user = user_contr.create(nickname=form.nickname.data,
                            email=form.email.data,
                            pwdhash=generate_password_hash(form.password.data),
                            automatic_crawling=form.automatic_crawling.data,
                            is_admin=False,
                            is_active=True)
        flash(gettext('User %(nick)s successfully created',
                      nick=user.nickname), 'success')
    return redirect(url_for('admin.user_form', user_id=user.id))
Пример #12
0
def confirm_account(activation_key=None):
    """
    Confirm the account of a user.
    """
    user_contr = UserController()
    if activation_key != "":
        user = user_contr.read(activation_key=activation_key).first()
        if user is not None:
            user_contr.update({'id': user.id}, {'activation_key': ''})
            flash(gettext('Your account has been confirmed.'), 'success')
        else:
            flash(gettext('Impossible to confirm this account.'), 'danger')
    return redirect(url_for('login'))
Пример #13
0
Файл: user.py Проект: bzero/JARR
def confirm_account(activation_key=None):
    """
    Confirm the account of a user.
    """
    user_contr = UserController()
    if activation_key != "":
        user = user_contr.read(activation_key=activation_key).first()
        if user is not None:
            user_contr.update({"id": user.id}, {"activation_key": ""})
            flash(gettext("Your account has been confirmed."), "success")
        else:
            flash(gettext("Impossible to confirm this account."), "danger")
    return redirect(url_for("login"))
Пример #14
0
 def test_password(self):
     passwd = 'test_password'
     ucontr = UserController()
     user = ucontr.create(login=passwd, password=passwd)
     self.assertNotEquals(passwd, user.password)
     self.assertTrue(ucontr.check_password(user, passwd))
     self.assertFalse(ucontr.check_password(user, passwd * 2))
     passwd *= 2
     ucontr.update({'id': user.id}, {'password': passwd})
     user = ucontr.get(id=user.id)
     self.assertNotEquals(passwd, user.password)
     self.assertTrue(ucontr.check_password(user, passwd))
     self.assertFalse(ucontr.check_password(user, passwd * 2))
Пример #15
0
def recover(token):
    form = PasswordModForm()
    ucontr = UserController()
    try:
        user = ucontr.get(renew_password_token=token)
    except NotFound:
        return gettext("Token is not valid, please regenerate one")
    if request.method == 'GET':
        return render_template('recover.html', form=form, token=token)

    if form.validate():
        ucontr.update({'id': user.id},
                {'renew_password_token': '', 'password': form.password.data})
        login_user_bundle(user)
        return redirect(url_for('home'))
    return render_template('recover.html', form=form, token=token)
Пример #16
0
def gen_recover_token():
    form = RecoverPasswordForm()
    ucontr = UserController()
    if request.method == 'GET':
        return render_template('recover.html', form=form)

    if form.validate():
        token = str(random.getrandbits(128))
        changed = ucontr.update({'email': form.email.data},
                                {'renew_password_token': token})
        if not changed:
            flash(gettext("No user with %(email)r was found",
                          form.email.data), "danger")
        else:
            body = gettext("""Hello,

A password change request has been made for your account on %(plateform)s.
If you have made that request please follow the link below to renew your
account, otherwise, disregard this email.

%(renew_password_link)s

Regards,

The JARR administrator""", plateform=conf.PLATFORM_URL,
                    renew_password_link=url_for('user.recover',
                        token=token, _external=True))
            emails.send(to=form.email.data, bcc=conf.NOTIFICATION_EMAIL,
                        subject="[jarr] Password renew", plaintext=body)
            flash(gettext("A mail has been sent with a token to renew your "
                          "password"), "info")
    return render_template('recover.html', form=form)
Пример #17
0
def confirm_account(token=None):
    """
    Confirm the account of a user.
    """
    user_contr = UserController()
    user, nickname = None, None
    if token != "":
        nickname = confirm_token(token)
    if nickname:
        user = user_contr.read(nickname=nickname).first()
    if user is not None:
        user_contr.update({'id': user.id}, {'is_active': True})
        flash(gettext('Your account has been confirmed.'), 'success')
    else:
        flash(gettext('Impossible to confirm this account.'), 'danger')
    return redirect(url_for('login'))
Пример #18
0
def confirm_account(token=None):
    """
    Confirm the account of a user.
    """
    user_contr = UserController()
    user, email = None, None
    if token != "":
        email = confirm_token(token)
    if email:
        user = user_contr.read(email=email).first()
    if user is not None:
        user_contr.update({'id': user.id}, {'is_active': True})
        flash(gettext('Your account has been confirmed.'), 'success')
    else:
        flash(gettext('Impossible to confirm this account.'), 'danger')
    return redirect(url_for('login'))
Пример #19
0
def confirm_account(token=None):
    """
    Confirm the account of a user.
    """
    user_contr = UserController()
    user, nickname = None, None
    if token != "":
        nickname = confirm_token(token)
    if nickname:
        user = user_contr.read(nickname=nickname).first()
    if user is not None:
        user_contr.update({"id": user.id}, {"is_active": True})
        flash(gettext("Your account has been confirmed."), "success")
    else:
        flash(gettext("Impossible to confirm this account."), "danger")
    return redirect(url_for("login"))
Пример #20
0
def recover(token):
    form = PasswordModForm()
    ucontr = UserController()
    try:
        user = ucontr.get(renew_password_token=token)
    except NotFound:
        return gettext("Token is not valid, please regenerate one")
    if request.method == 'GET':
        return render_template('recover.html', form=form, token=token)

    if form.validate():
        ucontr.update({'id': user.id}, {
            'renew_password_token': '',
            'password': form.password.data
        })
        login_user_bundle(user)
        return redirect(url_for('home'))
    return render_template('recover.html', form=form, token=token)
Пример #21
0
def login():
    if current_user.is_authenticated:
        return redirect(url_for('home'))
    if request.args.get('code'):
        code = request.args.get('code')
        data = {
            'grant_type': 'authorization_code',
            'client_id': conf.OPENIDC_CLIENT_ID,
            'client_secret': conf.OPENIDC_CLIENT_SECRET,
            'redirect_uri': url_for('login', _external=True),
            'code': code
        }
        r = requests.post(conf.OPENIDC_TOKEN_ENDPOINT, data=data)
        tokens = r.json()
        if 'error' not in tokens:
            headers = {
                'Authorization': 'Bearer ' + tokens['access_token'],
            }
            r = requests.post(conf.OPENIDC_USERINFO_ENDPOINT, headers=headers)
            userinfo = r.json()

            ucontr = UserController()
            try:
                user = ucontr.get(**{'external_id': userinfo['sub']})
                ucontr.update({'id': user.id}, {
                    'nickname': userinfo['preferred_username'],
                    'email': userinfo['email'],
                })
            except NotFound:
                user = ucontr.create(nickname=userinfo['preferred_username'],
                                     email=userinfo['email'],
                                     external_id=userinfo['sub'],
                                     is_active=True,
                                     is_api=True)
            login_user_bundle(user)
            return redirect(url_for('home'))

    auth = URL(conf.OPENIDC_AUTHORIZATION_ENDPOINT)
    auth = auth.with_query(client_id=conf.OPENIDC_CLIENT_ID,
                           redirect_uri=url_for('login', _external=True),
                           response_type='code',
                           scope='openid profile email')
    return render_template('login.html', authorization=auth)
Пример #22
0
def profile():
    """
    Edit the profile of the currently logged user.
    """
    user_contr = UserController(current_user.id)
    user = user_contr.get(id=current_user.id)
    form = ProfileForm()

    if request.method == "POST":
        if form.validate():
            try:
                user_contr.update(
                    {"id": current_user.id},
                    {
                        "nickname": form.nickname.data,
                        "password": form.password.data,
                        "automatic_crawling": form.automatic_crawling.data,
                        "is_public_profile": form.is_public_profile.data,
                        "bio": form.bio.data,
                        "webpage": form.webpage.data,
                        "twitter": form.twitter.data,
                    },
                )
            except Exception as error:
                flash(
                    gettext(
                        "Problem while updating your profile: " "%(error)s", error=error
                    ),
                    "danger",
                )
            else:
                flash(
                    gettext("User %(nick)s successfully updated", nick=user.nickname),
                    "success",
                )
            return redirect(url_for("user.profile"))
        else:
            return render_template("profile.html", user=user, form=form)

    if request.method == "GET":
        form = ProfileForm(obj=user)
        return render_template("profile.html", user=user, form=form)
Пример #23
0
def process_user_form(user_id=None):
    """
    Create or edit a user.
    """
    form = UserForm()
    user_contr = UserController()

    if not form.validate():
        return render_template(
            "/admin/create_user.html",
            form=form,
            message=gettext("Some errors were found"),
        )

    if user_id is not None:
        # Edit a user
        user_contr.update(
            {"id": user_id},
            {
                "nickname": form.nickname.data,
                "password": form.password.data,
                "automatic_crawling": form.automatic_crawling.data,
            },
        )
        user = user_contr.get(id=user_id)
        flash(
            gettext("User %(nick)s successfully updated", nick=user.nickname),
            "success")
    else:
        # Create a new user (by the admin)
        user = user_contr.create(
            nickname=form.nickname.data,
            password=form.password.data,
            automatic_crawling=form.automatic_crawling.data,
            is_admin=False,
            is_active=True,
        )
        flash(
            gettext("User %(nick)s successfully created", nick=user.nickname),
            "success")
    return redirect(url_for("admin.user_form", user_id=user.id))
Пример #24
0
def password_update(user_id):
    ucontr = None
    if admin_permission.can():
        ucontr = UserController()
    elif Permission(UserNeed(user_id)).can():
        ucontr = UserController(user_id)
    else:
        flash(gettext('You do not have rights on this user'), 'danger')
        raise Forbidden(gettext('You do not have rights on this user'))
    user = ucontr.get(id=user_id)
    profile_form, pass_form = ProfileForm(obj=user), PasswordModForm()
    if pass_form.validate():
        ucontr.update({'id': user_id}, {'password': pass_form.password.data})

        flash(gettext('Password for %(login)s successfully updated',
                      login=user.login), 'success')
        return redirect(url_for('user.profile', user_id=user.id))

    return render_template('profile.html', user=user,
            admin_permission=admin_permission,
            form=profile_form, pass_form=pass_form)
Пример #25
0
def process_user_form(user_id=None):
    """
    Create or edit a user.
    """
    form = UserForm()
    user_contr = UserController()

    if not form.validate():
        return render_template('/admin/create_user.html',
                               form=form,
                               message=gettext('Some errors were found'))

    role_user = Role.query.filter(Role.name == "user").first()
    if user_id is not None:
        # Edit a user
        user_contr.update({'id': user_id}, {
            'nickname': form.nickname.data,
            'email': form.email.data,
            'password': form.password.data,
            'refresh_rate': form.refresh_rate.data
        })
        user = user_contr.get(id=user_id)
        flash(
            gettext('User %(nick)s successfully updated', nick=user.nickname),
            'success')
    else:
        # Create a new user
        user = user_contr.create(nickname=form.nickname.data,
                                 email=form.email.data,
                                 password=form.password.data,
                                 roles=[role_user],
                                 refresh_rate=form.refresh_rate.data,
                                 activation_key="")
        flash(
            gettext('User %(nick)s successfully created', nick=user.nickname),
            'success')
    return redirect(url_for('admin.user_form', user_id=user.id))
Пример #26
0
def password_update(user_id):
    ucontr = None
    if admin_permission.can():
        ucontr = UserController()
    elif Permission(UserNeed(user_id)).can():
        ucontr = UserController(user_id)
    else:
        flash(gettext('You do not have rights on this user'), 'danger')
        raise Forbidden(gettext('You do not have rights on this user'))
    user = ucontr.get(id=user_id)
    profile_form, pass_form = ProfileForm(obj=user), PasswordModForm()
    if pass_form.validate():
        ucontr.update({'id': user_id}, {'password': pass_form.password.data})

        flash(
            gettext('Password for %(login)s successfully updated',
                    login=user.login), 'success')
        return redirect(url_for('user.profile', user_id=user.id))

    return render_template('profile.html',
                           user=user,
                           admin_permission=admin_permission,
                           form=profile_form,
                           pass_form=pass_form)
Пример #27
0
def toggle_user(user_id=None):
    """
    Enable or disable the account of a user.
    """
    ucontr = UserController()
    user = ucontr.get(id=user_id)
    user_changed = ucontr.update({'id': user_id},
            {'is_active': not user.is_active})

    if not user_changed:
        flash(gettext('This user does not exist.'), 'danger')
        return redirect(url_for('admin.dashboard'))

    else:
        act_txt = 'activated' if user.is_active else 'desactivated'
        message = gettext('User %(nickname)s successfully %(is_active)s',
                          nickname=user.nickname, is_active=act_txt)
    flash(message, 'success')
    return redirect(url_for('admin.dashboard'))
Пример #28
0
def toggle_user(user_id=None):
    """
    Enable or disable the account of a user.
    """
    ucontr = UserController()
    user = ucontr.get(id=user_id)
    user_changed = ucontr.update({'id': user_id},
                                 {'is_active': not user.is_active})

    if not user_changed:
        flash(gettext('This user does not exist.'), 'danger')
        return redirect(url_for('admin.dashboard'))

    else:
        act_txt = 'activated' if user.is_active else 'desactivated'
        message = gettext('User %(nickname)s successfully %(is_active)s',
                          nickname=user.nickname,
                          is_active=act_txt)
    flash(message, 'success')
    return redirect(url_for('admin.dashboard'))
Пример #29
0
def toggle_user(user_id=None):
    """
    Enable or disable the account of a user.
    """
    ucontr = UserController()
    user = ucontr.get(id=user_id)
    user_changed = ucontr.update({"id": user_id},
                                 {"is_active": not user.is_active})

    if not user_changed:
        flash(gettext("This user does not exist."), "danger")
        return redirect(url_for("admin.dashboard"))

    else:
        act_txt = "activated" if user.is_active else "desactivated"
        message = gettext(
            "User %(nickname)s successfully %(is_active)s",
            nickname=user.nickname,
            is_active=act_txt,
        )
    flash(message, "success")
    return redirect(url_for("admin.dashboard"))
Пример #30
0
def gen_recover_token():
    form = RecoverPasswordForm()
    ucontr = UserController()
    if request.method == 'GET':
        return render_template('recover.html', form=form)

    if form.validate():
        token = str(random.getrandbits(128))
        changed = ucontr.update({'email': form.email.data},
                                {'renew_password_token': token})
        if not changed:
            flash(gettext("No user with %(email)r was found", form.email.data),
                  "danger")
        else:
            body = gettext("""Hello,

A password change request has been made for your account on %(plateform)s.
If you have made that request please follow the link below to renew your
account, otherwise, disregard this email.

%(renew_password_link)s

Regards,

The JARR administrator""",
                           plateform=conf.PLATFORM_URL,
                           renew_password_link=url_for('user.recover',
                                                       token=token,
                                                       _external=True))
            emails.send(to=form.email.data,
                        bcc=conf.NOTIFICATION_EMAIL,
                        subject="[jarr] Password renew",
                        plaintext=body)
            flash(
                gettext("A mail has been sent with a token to renew your "
                        "password"), "info")
    return render_template('recover.html', form=form)