refactor: factorize features definition

This commit is contained in:
Éloi Rivard 2024-05-14 22:53:47 +02:00
parent 92081db2c0
commit 43f9f328a5
No known key found for this signature in database
GPG key ID: 7EDA204EA57DD184
13 changed files with 60 additions and 42 deletions

View file

@ -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)

33
canaille/app/features.py Normal file
View file

@ -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)

View file

@ -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")

View file

@ -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()],

View file

@ -29,7 +29,7 @@
<div class="ui right aligned container">
<div class="ui stackable buttons">
{% if has_registration %}
{% if features.has_registration %}
<a type="button" class="ui right floated button" href="{{ url_for('core.account.join') }}">{{ _("Create an account") }}</a>
{% endif %}
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.login') }}">{{ _("Login page") }}</a>

View file

@ -37,7 +37,7 @@
<div class="ui right aligned container">
<div class="ui stackable buttons">
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.login') }}">{{ _("Login page") }}</a>
{% if has_smtp and has_password_recovery %}
{% if features.has_smtp and features.has_password_recovery %}
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.forgotten') }}">{{ _("Forgotten password") }}</a>
{% endif %}
<button type="submit" class="ui right floated primary button" name="action" value="create-profile" id="create-profile">

View file

@ -29,10 +29,10 @@
<div class="ui right aligned container">
<div class="ui stackable buttons">
{% if has_registration %}
{% if features.has_registration %}
<a type="button" class="ui right floated button" href="{{ url_for('core.account.join') }}">{{ _("Create an account") }}</a>
{% endif %}
{% if has_smtp and has_password_recovery %}
{% if features.has_smtp and features.has_password_recovery %}
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.forgotten') }}">{{ _("Forgotten password") }}</a>
{% endif %}
<button type="submit" name="answer" class="ui right floated primary button" hx-boost="false">{{ _("Continue") }}</button>

View file

@ -10,7 +10,7 @@
<i class="user mail icon"></i>
{% trans %}Emails{% endtrans %}
</a>
{% if has_oidc %}
{% if features.has_oidc %}
<a class="item" href="{{ url_for('oidc.clients.index') }}">
<i class="th list icon"></i>
{% trans %}Clients{% endtrans %}

View file

@ -30,7 +30,7 @@
<div class="ui right aligned container">
<div class="ui stackable buttons">
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.login') }}">{{ _("I am not %(username)s", username=username) }}</a>
{% if has_smtp and has_password_recovery %}
{% if features.has_smtp and features.has_password_recovery %}
<a type="button" class="ui right floated button" href="{{ url_for('core.auth.forgotten') }}">{{ _("Forgotten password") }}</a>
{% endif %}
<button type="submit" class="ui right floated primary button">{{ _("Sign in") }}</button>

View file

@ -19,7 +19,7 @@
<i class="plus icon"></i>
{% trans %}Add{% endtrans %}
</a>
{% if has_smtp %}
{% if features.has_smtp %}
<a class="item" href="{{ url_for('core.account.user_invitation') }}">
<i class="paper plane icon"></i>
{% trans %}Invite{% endtrans %}
@ -175,7 +175,7 @@
{% trans %}User password is not mandatory{% endtrans %}
</div>
<p>
{% 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 %}

View file

@ -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() %}
<div class="ui message warning visible">
{% if has_smtp and edited_user.can_edit_self %}
{% if features.has_smtp and edited_user.can_edit_self %}
<button type="submit" name="action" value="password-initialization-mail" class="ui right floated primary button">
{% trans %}Send mail{% endtrans %}
</button>
@ -94,7 +94,7 @@
<div class="header">
{% trans %}This user does not have a password yet{% endtrans %}
</div>
{% if has_smtp and edited_user.can_edit_self %}
{% if features.has_smtp and edited_user.can_edit_self %}
<p>{% trans %}You can solve this by:{% endtrans %}</p>
<ul class="ui list">
<li>{% trans %}setting a password using this form;{% endtrans %}</li>
@ -106,7 +106,7 @@
{% endif %}
</div>
{% 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 %}
<div class="ui message info">
<button type="submit" name="action" value="password-reset-mail" class="ui right floated button">
@ -120,7 +120,7 @@
{% endif %}
{% if has_account_lockability and edited_user.locked %}
{% if features.has_account_lockability and edited_user.locked %}
<div class="ui message warning visible">
<button type="submit" name="action" value="unlock" class="ui right floated button">
@ -140,7 +140,7 @@
<div class="ui right aligned container">
<div class="ui stackable buttons">
{% if has_account_lockability and "lock_date" in user.writable_fields and not edited_user.locked %}
{% if features.has_account_lockability and "lock_date" in user.writable_fields and not edited_user.locked %}
<button type="submit" class="ui right floated basic negative button confirm" name="action" value="confirm-lock" id="lock" formnovalidate>
{% trans %}Lock the account{% endtrans %}
</button>

View file

@ -14,7 +14,7 @@
<i class="plus icon"></i>
{% trans %}Add{% endtrans %}
</a>
{% if has_smtp %}
{% if features.has_smtp %}
<a class="item" href="{{ url_for('core.account.user_invitation') }}">
<i class="paper plane icon"></i>
{% trans %}Invite{% endtrans %}

View file

@ -37,7 +37,7 @@
{% trans %}Profile{% endtrans %}
</a>
{% endif %}
{% if has_oidc and user.can_use_oidc %}
{% if features.has_oidc and user.can_use_oidc %}
<a class="item {% if menuitem is defined and menuitem == "consents" %}active{% endif %}"
href="{{ url_for('oidc.consents.consents') }}">
<i class="handshake icon"></i>