forked from Github-Mirrors/canaille
Merge branch 'issue-99-disable-password-recovery' into 'master'
Added an option to disable password recovery Closes #99 See merge request yaal/canaille!46
This commit is contained in:
commit
6ef0766acf
10 changed files with 48 additions and 4 deletions
11
CHANGES.rst
11
CHANGES.rst
|
@ -3,7 +3,16 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
|
||||
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
|
||||
|
||||
[0.0.7] - 2022-03-15
|
||||
[0.0.9] - 2022-xx-xx
|
||||
====================
|
||||
|
||||
Added
|
||||
*****
|
||||
|
||||
- ``DISABLE_PASSWORD_RESET`` configuration option to disable password recovery. :pr:`46`
|
||||
|
||||
|
||||
[0.0.8] - 2022-03-15
|
||||
====================
|
||||
|
||||
Fixed
|
||||
|
|
|
@ -179,6 +179,9 @@ def create_app(config=None, validate=True):
|
|||
|
||||
return {
|
||||
"has_smtp": "SMTP" in app.config,
|
||||
"has_password_recovery": app.config.get(
|
||||
"ENABLE_PASSWORD_RECOVERY", True
|
||||
),
|
||||
"logo_url": app.config.get("LOGO"),
|
||||
"favicon_url": app.config.get("FAVICON", app.config.get("LOGO")),
|
||||
"website_name": app.config.get("NAME", "Canaille"),
|
||||
|
|
|
@ -526,6 +526,9 @@ def impersonate(user, username):
|
|||
@bp.route("/reset", methods=["GET", "POST"])
|
||||
@smtp_needed()
|
||||
def forgotten():
|
||||
if not current_app.config.get("ENABLE_PASSWORD_RECOVERY", True):
|
||||
abort(404)
|
||||
|
||||
form = ForgottenPasswordForm(request.form)
|
||||
if not request.form:
|
||||
return render_template("forgotten-password.html", form=form)
|
||||
|
@ -562,6 +565,9 @@ def forgotten():
|
|||
|
||||
@bp.route("/reset/<uid>/<hash>", methods=["GET", "POST"])
|
||||
def reset(uid, hash):
|
||||
if not current_app.config.get("ENABLE_PASSWORD_RECOVERY", True):
|
||||
abort(404)
|
||||
|
||||
form = PasswordResetForm(request.form)
|
||||
user = User.get(uid)
|
||||
|
||||
|
|
|
@ -40,6 +40,10 @@ OIDC_METADATA_FILE = "canaille/conf/openid-configuration.json"
|
|||
# wether the login exists or not.
|
||||
# HIDE_INVALID_LOGINS = false
|
||||
|
||||
# If ENABLE_PASSWORD_RECOVERY is false, then users cannot ask for a password
|
||||
# recovery link by email. This option is true by default.
|
||||
# ENABLE_PASSWORD_RECOVERY = true
|
||||
|
||||
# The validity duration of registration invitations, in seconds.
|
||||
# Defaults to 2 days
|
||||
# INVITATION_EXPIRATION = 172800
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
<div class="ui right aligned container">
|
||||
<div class="ui stackable buttons">
|
||||
{% if has_smtp %}
|
||||
{% if has_smtp and has_password_recovery %}
|
||||
<a type="button" class="ui right floated button" href="{{ url_for('account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
||||
{% endif %}
|
||||
<button type="submit" class="ui right floated primary button">{{ _("Continue") }}</button>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<div class="ui right aligned container">
|
||||
<div class="ui stackable buttons">
|
||||
<a type="button" class="ui right floated button" href="{{ url_for('account.login') }}">{{ _("I am not %(username)s", username=username) }}</a>
|
||||
{% if has_smtp %}
|
||||
{% if has_smtp and has_password_recovery %}
|
||||
<a type="button" class="ui right floated button" href="{{ url_for('account.forgotten') }}">{{ _("Forgotten password") }}</a>
|
||||
{% endif %}
|
||||
<button type="submit" class="ui right floated primary button">{{ _("Sign in") }}</button>
|
||||
|
|
|
@ -40,6 +40,10 @@ OIDC_METADATA_FILE = "conf/openid-configuration.json"
|
|||
# wether the login exists or not.
|
||||
# HIDE_INVALID_LOGINS = false
|
||||
|
||||
# If ENABLE_PASSWORD_RECOVERY is false, then users cannot ask for a password
|
||||
# recovery link by email. This option is true by default.
|
||||
# ENABLE_PASSWORD_RECOVERY = true
|
||||
|
||||
# The validity duration of registration invitations, in seconds.
|
||||
# Defaults to 2 days
|
||||
# INVITATION_EXPIRATION = 172800
|
||||
|
|
|
@ -40,6 +40,10 @@ OIDC_METADATA_FILE = "conf/openid-configuration.json"
|
|||
# wether the login exists or not.
|
||||
# HIDE_INVALID_LOGINS = false
|
||||
|
||||
# If ENABLE_PASSWORD_RECOVERY is false, then users cannot ask for a password
|
||||
# recovery link by email. This option is true by default.
|
||||
# ENABLE_PASSWORD_RECOVERY = true
|
||||
|
||||
# The validity duration of registration invitations, in seconds.
|
||||
# Defaults to 2 days
|
||||
# INVITATION_EXPIRATION = 172800
|
||||
|
|
|
@ -49,7 +49,11 @@ Canaille is based on Flask, so any `flask configuration <https://flask.palletspr
|
|||
|
||||
:HIDE_INVALID_LOGINS:
|
||||
*Optional.* Wether to tell the users if a username exists during failing login attempts.
|
||||
Defaults to ``True``. This may be a security issue to disable this, as this give a way to malicious people to guess who has an account on this canaille instance.
|
||||
Defaults to ``True``. This may be a security issue to disable this, as this give a way to malicious people to if an account exists on this canaille instance.
|
||||
|
||||
:ENABLE_PASSWORD_RECOVERY:
|
||||
*Optional* Wether the password recovery feature is enabled or not.
|
||||
Defaults to ``True``.
|
||||
|
||||
:INVITATION_EXPIRATION:
|
||||
*Optional* The validity duration of registration invitations, in seconds.
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
def test_password_forgotten_disabled(smtpd, testclient, slapd_connection, user):
|
||||
testclient.app.config["ENABLE_PASSWORD_RECOVERY"] = False
|
||||
|
||||
testclient.get("/reset", status=404)
|
||||
testclient.get("/reset/uid/hash", status=404)
|
||||
|
||||
res = testclient.get("/login")
|
||||
assert "Forgotten password" not in res.text
|
||||
|
||||
|
||||
def test_password_forgotten(smtpd, testclient, slapd_connection, user):
|
||||
res = testclient.get("/reset", status=200)
|
||||
|
||||
|
|
Loading…
Reference in a new issue