[docs]
class Features:
def __init__(self, app):
self.app = app
@property
def has_smtp(self):
"""Indicate whether the mail sending feature is enabled.
This feature is required to :attr:`validate user email addresses <canaille.app.features.Features.has_email_confirmation>`, send email OTP passwords etc.
It is controlled by the :attr:`CANAILLE.SMTP <canaille.core.configuration.CoreSettings.SMTP>` configuration parameter.
"""
return bool(self.app.config["CANAILLE"]["SMTP"])
@property
def has_password_recovery(self):
"""Indicate whether the password recovery feature is enabled.
It is controlled by the :attr:`CANAILLE.ENABLE_PASSWORD_RECOVERY <canaille.core.configuration.CoreSettings.ENABLE_PASSWORD_RECOVERY>` configuration parameter.
"""
return self.app.config["CANAILLE"]["ENABLE_PASSWORD_RECOVERY"]
@property
def has_intruder_lockout(self):
"""Indicate whether the intruder lockout feature is enabled.
It is controlled by the :attr:`CANAILLE.ENABLE_INTRUDER_LOCKOUT <canaille.core.configuration.CoreSettings.ENABLE_INTRUDER_LOCKOUT>` configuration parameter.
"""
return self.app.config["CANAILLE"]["ENABLE_INTRUDER_LOCKOUT"]
@property
def has_otp(self):
"""Indicate whether the OTP authentication factor is enabled.
It is controlled by the :attr:`CANAILLE.OTP_METHOD <canaille.core.configuration.CoreSettings.OTP_METHOD>` configuration parameter,
needs the ``otp`` extra package to be installed,
and requires the backend to support OTP attributes.
"""
try:
import otpauth # noqa: F401
return (
bool(self.app.config["CANAILLE"]["OTP_METHOD"])
and self.app.backend.instance.has_otp_support()
)
except ImportError: # pragma: no cover
return False
@property
def has_registration(self):
"""Indicate whether the user account registration is enabled.
It is controlled by the :attr:`CANAILLE.ENABLE_REGISTRATION <canaille.core.configuration.CoreSettings.ENABLE_REGISTRATION>` configuration parameter.
"""
return self.app.config["CANAILLE"]["ENABLE_REGISTRATION"]
@property
def has_account_lockability(self):
"""Indicate whether the user accounts can be locked.
It depends on the backend used by Canaille.
This is only disabled for OpenLDAP versions under 2.6.
"""
return self.app.backend.instance.has_account_lockability()
@property
def has_email_confirmation(self):
"""Indicate whether the user email confirmation is enabled.
It is controlled by the :attr:`CANAILLE.EMAIL_CONFIRMATION <canaille.core.configuration.CoreSettings.EMAIL_CONFIRMATION>` configuration parameter.
"""
return self.app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is True or (
self.app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is None and self.has_smtp
)
@property
def has_trusted_hosts(self):
"""Indicate whether the Flask TRUSTED_HOSTS option is enabled.
It is controlled by the :attr:`TRUSTED_HOSTS <canaille.app.configuration.RootSettings.TRUSTED_HOSTS>` configuration parameter.
"""
return bool(self.app.config["TRUSTED_HOSTS"])
@property
def has_oidc(self):
"""Indicate whether the OIDC feature is enabled.
This feature is required to make Canaille an authorization server for other applications and enable SSO.
It is controlled by the :class:`CANAILLE_OIDC <canaille.oidc.configuration.OIDCSettings>` configuration parameter,
and needs the ``oidc`` extra package to be installed.
"""
try:
import authlib # noqa: F401
return (
self.app.config.get("CANAILLE_OIDC")
and self.app.config["CANAILLE_OIDC"]["ENABLE_OIDC"]
)
except ImportError: # pragma: no cover
return False
@property
def has_scim_server(self):
"""Indicate whether the SCIM server feature is enabled.
This feature is required to make Canaille a provisioning server.
It is controlled by the :attr:`CANAILLE_SCIM.ENABLE_SERVER <canaille.scim.configuration.SCIMSettings.ENABLE_SERVER>` configuration parameter,
and needs the ``scim`` extra package to be installed.
"""
try:
import scim2_models # noqa: F401
return (
self.app.config.get("CANAILLE_SCIM")
and self.app.config["CANAILLE_SCIM"]["ENABLE_SERVER"]
)
except ImportError: # pragma: no cover
return False
@property
def has_scim_client(self):
"""Indicate whether the SCIM client feature is enabled.
This feature is required to make Canaille a provisioning client.
It is controlled by the :attr:`CANAILLE_SCIM.ENABLE_CLIENT <canaille.scim.configuration.SCIMSettings.ENABLE_CLIENT>` configuration parameter,
and needs the ``scim`` extra package to be installed.
"""
try:
import httpx # noqa: F401
import scim2_client # noqa: F401
return (
self.app.config.get("CANAILLE_SCIM")
and self.app.config["CANAILLE_SCIM"]["ENABLE_CLIENT"]
)
except ImportError: # pragma: no cover
return False
@property
def has_captcha(self):
"""Indicate whether the CAPTCHA feature is enabled.
It is controlled by the :attr:`CANAILLE.CAPTCHA_ENABLED <canaille.core.configuration.CoreSettings.CAPTCHA_ENABLED>` configuration parameter,
and needs the ``captcha`` extra package to be installed.
"""
try:
import captcha # noqa: F401
except ImportError: # pragma: no cover
return False
return self.app.config["CANAILLE"]["CAPTCHA_ENABLED"]
@property
def has_fido(self):
"""Indicate whether the FIDO2/WebAuthn authentication factor is enabled.
It requires the ``fido`` extra package to be installed, a SQL backend,
and JavaScript to be enabled.
LDAP backend is not supported.
"""
try:
import webauthn # noqa: F401
except ImportError: # pragma: no cover
return False
backend_name = self.app.config["CANAILLE"]["DATABASE"]
javascript_enabled = self.app.config["CANAILLE"].get("JAVASCRIPT", True)
return backend_name != "ldap" and javascript_enabled
def setup_features(app):
app.features = Features(app)