From 43f9f328a513fbc06e8b2deb41dbef4352a97c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Tue, 14 May 2024 22:53:47 +0200 Subject: [PATCH] refactor: factorize features definition --- canaille/__init__.py | 14 ++------ canaille/app/features.py | 33 +++++++++++++++++++ canaille/core/endpoints/account.py | 21 ++++-------- canaille/core/endpoints/forms.py | 2 +- .../core/templates/forgotten-password.html | 2 +- canaille/core/templates/join.html | 2 +- canaille/core/templates/login.html | 4 +-- canaille/core/templates/mails/admin.html | 2 +- canaille/core/templates/password.html | 2 +- canaille/core/templates/profile_add.html | 4 +-- canaille/core/templates/profile_settings.html | 12 +++---- canaille/core/templates/users.html | 2 +- canaille/templates/base.html | 2 +- 13 files changed, 60 insertions(+), 42 deletions(-) create mode 100644 canaille/app/features.py diff --git a/canaille/__init__.py b/canaille/__init__.py index f830ec62..e4dc4021 100644 --- a/canaille/__init__.py +++ b/canaille/__init__.py @@ -95,11 +95,6 @@ def setup_flask(app): return { "debug": app.debug or app.config.get("TESTING", False), - "has_smtp": "SMTP" in app.config["CANAILLE"], - "has_oidc": "CANAILLE_OIDC" in app.config, - "has_password_recovery": app.config["CANAILLE"]["ENABLE_PASSWORD_RECOVERY"], - "has_registration": app.config["CANAILLE"]["ENABLE_REGISTRATION"], - "has_account_lockability": app.backend.instance.has_account_lockability(), "logo_url": app.config["CANAILLE"]["LOGO"], "favicon_url": app.config["CANAILLE"]["FAVICON"] or app.config["CANAILLE"]["LOGO"], @@ -107,12 +102,7 @@ def setup_flask(app): "user": current_user(), "menu": True, "is_boosted": request.headers.get("HX-Boosted", False), - "has_email_confirmation": app.config["CANAILLE"]["EMAIL_CONFIRMATION"] - is True - or ( - app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is None - and "SMTP" in app.config["CANAILLE"] - ), + "features": app.features, } @@ -128,6 +118,7 @@ def create_app( config=None, validate=True, backend=None, env_file=".env", env_prefix="" ): from .app.configuration import setup_config + from .app.features import setup_features from .app.i18n import setup_i18n from .app.themes import setup_themer from .backends import setup_backend @@ -147,6 +138,7 @@ def create_app( try: setup_logging(app) backend = setup_backend(app, backend) + setup_features(app) setup_flask_converters(app) setup_blueprints(app) setup_jinja(app) diff --git a/canaille/app/features.py b/canaille/app/features.py new file mode 100644 index 00000000..27f71713 --- /dev/null +++ b/canaille/app/features.py @@ -0,0 +1,33 @@ +class Features: + def __init__(self, app): + self.app = app + + @property + def has_smtp(self): + return "SMTP" in self.app.config["CANAILLE"] + + @property + def has_oidc(self): + return "CANAILLE_OIDC" in self.app.config + + @property + def has_password_recovery(self): + return self.app.config["CANAILLE"]["ENABLE_PASSWORD_RECOVERY"] + + @property + def has_registration(self): + return self.app.config["CANAILLE"]["ENABLE_REGISTRATION"] + + @property + def has_account_lockability(self): + return self.app.backend.instance.has_account_lockability() + + @property + def has_email_confirmation(self): + return self.app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is True or ( + self.app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is None and self.has_smtp + ) + + +def setup_features(app): + app.features = Features(app) diff --git a/canaille/core/endpoints/account.py b/canaille/core/endpoints/account.py index b0db8035..ed885f90 100644 --- a/canaille/core/endpoints/account.py +++ b/canaille/core/endpoints/account.py @@ -290,10 +290,7 @@ def registration(data=None, hash=None): ], } - has_smtp = "SMTP" in current_app.config["CANAILLE"] - emails_readonly = current_app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is True or ( - current_app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is None and has_smtp - ) + emails_readonly = current_app.features.has_email_confirmation readable_fields, writable_fields = default_fields() form = build_profile_form(writable_fields, readable_fields) @@ -587,17 +584,13 @@ def profile_edition(user, edited_user): abort(404) menuitem = "profile" if edited_user.id == user.id else "users" - has_smtp = "SMTP" in current_app.config["CANAILLE"] - has_email_confirmation = current_app.config["CANAILLE"][ - "EMAIL_CONFIRMATION" - ] is True or ( - current_app.config["CANAILLE"]["EMAIL_CONFIRMATION"] is None and has_smtp + emails_readonly = ( + current_app.features.has_email_confirmation and not user.can_manage_users ) - emails_readonly = has_email_confirmation and not user.can_manage_users profile_form = profile_edition_main_form(user, edited_user, emails_readonly) emails_form = ( - profile_edition_emails_form(user, edited_user, has_smtp) + profile_edition_emails_form(user, edited_user, current_app.features.has_smtp) if emails_readonly else None ) @@ -718,14 +711,14 @@ def profile_settings(user, edited_user): if ( request.form.get("action") == "confirm-lock" - and Backend.instance.has_account_lockability() + and current_app.features.has_account_lockability and not edited_user.locked ): return render_template("modals/lock-account.html", edited_user=edited_user) if ( request.form.get("action") == "lock" - and Backend.instance.has_account_lockability() + and current_app.features.has_account_lockability and not edited_user.locked ): flash(_("The account has been locked"), "success") @@ -736,7 +729,7 @@ def profile_settings(user, edited_user): if ( request.form.get("action") == "unlock" - and Backend.instance.has_account_lockability() + and current_app.features.has_account_lockability and edited_user.locked ): flash(_("The account has been unlocked"), "success") diff --git a/canaille/core/endpoints/forms.py b/canaille/core/endpoints/forms.py index 40be89fc..ff48380b 100644 --- a/canaille/core/endpoints/forms.py +++ b/canaille/core/endpoints/forms.py @@ -339,7 +339,7 @@ def build_profile_form(write_field_names, readonly_field_names, user=None): if "groups" in fields and not Backend.instance.query(models.Group): del fields["groups"] - if current_app.backend.instance.has_account_lockability(): # pragma: no branch + if current_app.features.has_account_lockability: # pragma: no branch fields["lock_date"] = DateTimeUTCField( _("Account expiration"), validators=[wtforms.validators.Optional()], diff --git a/canaille/core/templates/forgotten-password.html b/canaille/core/templates/forgotten-password.html index d9144987..7a4f6a95 100644 --- a/canaille/core/templates/forgotten-password.html +++ b/canaille/core/templates/forgotten-password.html @@ -29,7 +29,7 @@
- {% if has_registration %} + {% if features.has_registration %} {{ _("Create an account") }} {% endif %} {{ _("Login page") }} diff --git a/canaille/core/templates/join.html b/canaille/core/templates/join.html index 4411b68a..047958b0 100644 --- a/canaille/core/templates/join.html +++ b/canaille/core/templates/join.html @@ -37,7 +37,7 @@
{{ _("Login page") }} - {% if has_smtp and has_password_recovery %} + {% if features.has_smtp and features.has_password_recovery %} {{ _("Forgotten password") }} {% endif %} diff --git a/canaille/core/templates/mails/admin.html b/canaille/core/templates/mails/admin.html index f4aa80b2..f713cdc0 100644 --- a/canaille/core/templates/mails/admin.html +++ b/canaille/core/templates/mails/admin.html @@ -10,7 +10,7 @@ {% trans %}Emails{% endtrans %} - {% if has_oidc %} + {% if features.has_oidc %} {% trans %}Clients{% endtrans %} diff --git a/canaille/core/templates/password.html b/canaille/core/templates/password.html index bce2b8f1..40fc1a1d 100644 --- a/canaille/core/templates/password.html +++ b/canaille/core/templates/password.html @@ -30,7 +30,7 @@
{{ _("I am not %(username)s", username=username) }} - {% if has_smtp and has_password_recovery %} + {% if features.has_smtp and features.has_password_recovery %} {{ _("Forgotten password") }} {% endif %} diff --git a/canaille/core/templates/profile_add.html b/canaille/core/templates/profile_add.html index 6d59d9ef..77147f3c 100644 --- a/canaille/core/templates/profile_add.html +++ b/canaille/core/templates/profile_add.html @@ -19,7 +19,7 @@ {% trans %}Add{% endtrans %} - {% if has_smtp %} + {% if features.has_smtp %} {% trans %}Invite{% endtrans %} @@ -175,7 +175,7 @@ {% trans %}User password is not mandatory{% endtrans %}

- {% if has_smtp %} + {% if features.has_smtp %} {% trans %}The user will not be able to authenticate unless the password is set, but they will be able to ask for a password initialization mail.{% endtrans %} {% else %} {% trans %}The user will not be able to authenticate unless the password is set.{% endtrans %} diff --git a/canaille/core/templates/profile_settings.html b/canaille/core/templates/profile_settings.html index ff421005..6021e832 100644 --- a/canaille/core/templates/profile_settings.html +++ b/canaille/core/templates/profile_settings.html @@ -50,7 +50,7 @@ {% block user_name_field scoped %}{{ render_field(form.user_name) }}{% endblock %} {% endif %} - {% if has_account_lockability and "lock_date" in form and not edited_user.locked %} + {% if features.has_account_lockability and "lock_date" in form and not edited_user.locked %} {% block lock_date_field scoped %}{{ render_field(form.lock_date) }}{% endblock %} {% endif %} @@ -86,7 +86,7 @@ {% if not edited_user.has_password() %}

- {% if has_smtp and edited_user.can_edit_self %} + {% if features.has_smtp and edited_user.can_edit_self %} @@ -94,7 +94,7 @@
{% trans %}This user does not have a password yet{% endtrans %}
- {% if has_smtp and edited_user.can_edit_self %} + {% if features.has_smtp and edited_user.can_edit_self %}

{% trans %}You can solve this by:{% endtrans %}

  • {% trans %}setting a password using this form;{% endtrans %}
  • @@ -106,7 +106,7 @@ {% endif %}
- {% elif has_smtp and edited_user.user_name != user.user_name and edited_user.has_password() and edited_user.can_edit_self %} + {% elif features.has_smtp and edited_user.user_name != user.user_name and edited_user.has_password() and edited_user.can_edit_self %}