updates configuration and config.sample and demo config files toinclude new parameters. adds new tests for configuration condition.

This commit is contained in:
sebastien 2024-11-15 16:28:21 +01:00
parent d10497d3d2
commit 9b8f8e9cd4
10 changed files with 68 additions and 4 deletions

View file

@ -173,6 +173,7 @@ def setup_config(app, config=None, test_config=True, env_file=".env", env_prefix
def validate(config, validate_remote=False): def validate(config, validate_remote=False):
validate_keypair(config.get("CANAILLE_OIDC")) validate_keypair(config.get("CANAILLE_OIDC"))
validate_theme(config["CANAILLE"]) validate_theme(config["CANAILLE"])
validate_admin_email(config["CANAILLE"])
if not validate_remote: if not validate_remote:
return return
@ -234,3 +235,10 @@ def validate_theme(config):
os.path.join(ROOT, "themes", config["THEME"]) os.path.join(ROOT, "themes", config["THEME"])
): ):
raise ConfigurationException(f'Cannot find theme \'{config["THEME"]}\'') raise ConfigurationException(f'Cannot find theme \'{config["THEME"]}\'')
def validate_admin_email(config):
if config["ENABLE_PASSWORD_COMPROMISSION_CHECK"] and config["ADMIN_EMAIL"] is None:
raise ConfigurationException(
"You must set an administration email if you want to check if users' passwords are compromised."
)

View file

@ -42,7 +42,7 @@ SECRET_KEY = "change me before you go in production"
# By default, this is true if SMTP is configured, else this is false. # By default, this is true if SMTP is configured, else this is false.
# If explicitly set to true and SMTP is disabled, the email field # If explicitly set to true and SMTP is disabled, the email field
# will be read-only. # will be read-only.
# EMAIL_CONFIRMATION = # EMAIL_CONFIRMATION = True
# If ENABLE_REGISTRATION is true, then users can freely create an account # If ENABLE_REGISTRATION is true, then users can freely create an account
# at this instance. If email verification is available, users must confirm # at this instance. If email verification is available, users must confirm
@ -74,6 +74,28 @@ SECRET_KEY = "change me before you go in production"
# - if this is a string, it is passed to the python fileConfig method # - if this is a string, it is passed to the python fileConfig method
# https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig # https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig
# Minimum length for user password.
# It is possible not to set a minimum, by entering None or 0.
# MIN_PASSWORD_LENGTH = 8
# Maximum length for user password.
# There is a technical limit with passlib used by sql database of 4096
# characters. If the value entered is 0 or None, or greater than 4096,
# then 4096 will be retained.
# MAX_PASSWORD_LENGTH = 1000
# Administration email contact.
# In certain special cases (example : questioning about password
# corruption), it is necessary to provide an administration contact
# email.
# ADMIN_EMAIL = "admin@mydomain.tld"
# If :py:data:`True`, Canaille will check for password compromise on HIBP
# every time a new password is register.
# (https://haveibeenpwned.com/)
# ENABLE_PASSWORD_COMPROMISSION_CHECK = False
# [CANAILLE_SQL] # [CANAILLE_SQL]
# The SQL database connection string # The SQL database connection string
# Details on https://docs.sqlalchemy.org/en/20/core/engines.html # Details on https://docs.sqlalchemy.org/en/20/core/engines.html

View file

@ -313,7 +313,7 @@ class CoreSettings(BaseModel):
then 4096 will be retained. then 4096 will be retained.
""" """
ADMIN_EMAIL: str = None ADMIN_EMAIL: str | None = None
"""Administration email contact. """Administration email contact.
In certain special cases (example : questioning about password In certain special cases (example : questioning about password
@ -322,6 +322,8 @@ class CoreSettings(BaseModel):
""" """
ENABLE_PASSWORD_COMPROMISSION_CHECK: bool = False ENABLE_PASSWORD_COMPROMISSION_CHECK: bool = False
"""Enable to check for password compromise on HIBP. """If :py:data:`True`, Canaille will check for password compromise on HIBP
every time a new password is register.
(https://haveibeenpwned.com/)
""" """

View file

@ -7,6 +7,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE_LDAP] [CANAILLE_LDAP]
URI = "ldap://ldap:389" URI = "ldap://ldap:389"

View file

@ -7,6 +7,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE.ACL.DEFAULT] [CANAILLE.ACL.DEFAULT]
PERMISSIONS = ["edit_self", "use_oidc"] PERMISSIONS = ["edit_self", "use_oidc"]

View file

@ -7,6 +7,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE_SQL] [CANAILLE_SQL]
DATABASE_URI = "sqlite:///demo.sqlite" DATABASE_URI = "sqlite:///demo.sqlite"

View file

@ -6,6 +6,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE.LOGGING] [CANAILLE.LOGGING]
version = 1 version = 1

View file

@ -6,6 +6,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE.LOGGING] [CANAILLE.LOGGING]
version = 1 version = 1

View file

@ -6,6 +6,7 @@ LOGO = "/static/img/canaille-head.webp"
FAVICON = "/static/img/canaille-c.webp" FAVICON = "/static/img/canaille-c.webp"
EMAIL_CONFIRMATION = false EMAIL_CONFIRMATION = false
ENABLE_REGISTRATION = true ENABLE_REGISTRATION = true
ADMIN_EMAIL = "admin@mydomain.tld"
[CANAILLE.LOGGING] [CANAILLE.LOGGING]
version = 1 version = 1

View file

@ -203,3 +203,29 @@ def test_invalid_theme(configuration, backend):
config_obj = settings_factory(configuration) config_obj = settings_factory(configuration)
config_dict = config_obj.model_dump() config_dict = config_obj.model_dump()
validate(config_dict, validate_remote=False) validate(config_dict, validate_remote=False)
def test_enable_password_compromission_check_with_and_without_admin_email(
configuration, backend
):
configuration["CANAILLE"]["ENABLE_PASSWORD_COMPROMISSION_CHECK"] = False
configuration["CANAILLE"]["ADMIN_EMAIL"] = None
config_obj = settings_factory(configuration)
config_dict = config_obj.model_dump()
validate(config_dict, validate_remote=False)
configuration["CANAILLE"]["ENABLE_PASSWORD_COMPROMISSION_CHECK"] = True
configuration["CANAILLE"]["ADMIN_EMAIL"] = "admin_default_mail@mymail.com"
config_obj = settings_factory(configuration)
config_dict = config_obj.model_dump()
validate(config_dict, validate_remote=False)
with pytest.raises(
ConfigurationException,
match=r"You must set an administration email if you want to check if users' passwords are compromised.",
):
configuration["CANAILLE"]["ENABLE_PASSWORD_COMPROMISSION_CHECK"] = True
configuration["CANAILLE"]["ADMIN_EMAIL"] = None
config_obj = settings_factory(configuration)
config_dict = config_obj.model_dump()
validate(config_dict, validate_remote=False)