chore: automitaclly fix typos

This commit is contained in:
Éloi Rivard 2024-09-11 09:33:42 +02:00
parent 902f978130
commit cfabcc485c
No known key found for this signature in database
GPG key ID: 7EDA204EA57DD184
29 changed files with 69 additions and 58 deletions

View file

@ -23,3 +23,11 @@ repos:
rev: 3.0.6 rev: 3.0.6
hooks: hooks:
- id: djhtml - id: djhtml
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
- tomli
exclude: ".*\\.min\\..*|translations|\\.css$|^tests|fomanticui"
args: [--write-changes]

View file

@ -195,7 +195,7 @@ Fixed
preferred user email address. preferred user email address.
- Password reset and initialization mails were not sent at all the user - Password reset and initialization mails were not sent at all the user
addresses if one email address could not be reached. addresses if one email address could not be reached.
- Password comparision was too permissive on login. - Password comparison was too permissive on login.
- Encrypt passwords in the SQL backend. - Encrypt passwords in the SQL backend.
[0.0.35] - 2023-11-25 [0.0.35] - 2023-11-25
@ -612,7 +612,7 @@ Changed
Fixed Fixed
^^^^^ ^^^^^
- ``HIDE_INVALID_LOGIN`` behavior and default value. - ``HIDE_INVALID_LOGIN`` behavior and default value.
- mo files are not versionned anymore :pr:`49` :pr:`53` - mo files are not versioned anymore :pr:`49` :pr:`53`
[0.0.8] - 2022-03-15 [0.0.8] - 2022-03-15
-------------------- --------------------
@ -679,7 +679,7 @@ Added
- Added an option to tune object IDs :pr:`26` - Added an option to tune object IDs :pr:`26`
- Avatar support :pr:`27` - Avatar support :pr:`27`
- Dynamical and configurable JWT claims :pr:`28` - Dynamical and configurable JWT claims :pr:`28`
- UI improvemnts :pr:`29` - UI improvements :pr:`29`
- Invitation links expiration :pr:`30` - Invitation links expiration :pr:`30`
- Invitees can choose their IDs :pr:`31` - Invitees can choose their IDs :pr:`31`
- LDAP backend refactoring :pr:`35` - LDAP backend refactoring :pr:`35`
@ -705,7 +705,7 @@ Added
- Two-steps sign-in :issue:`49` - Two-steps sign-in :issue:`49`
- Tokens can have several audiences. :issue:`62` :pr:`9` - Tokens can have several audiences. :issue:`62` :pr:`9`
- Configuration check command. :issue:`66` :pr:`8` - Configuration check command. :issue:`66` :pr:`8`
- Groups managament. :issue:`12` :pr:`6` - Groups management. :issue:`12` :pr:`6`
Fixed Fixed
^^^^^ ^^^^^

View file

@ -129,7 +129,7 @@ Code style
---------- ----------
We use `ruff <https://docs.astral.sh/ruff/>`_ along with other tools to format our code. We use `ruff <https://docs.astral.sh/ruff/>`_ along with other tools to format our code.
Please run ``tox -e style`` on your patches before submiting them. Please run ``tox -e style`` on your patches before submitting them.
In order to perform a style check and correction at each commit you can use our In order to perform a style check and correction at each commit you can use our
`pre-commit <https://pre-commit.com/>`_ configuration with ``pre-commit install``. `pre-commit <https://pre-commit.com/>`_ configuration with ``pre-commit install``.

View file

@ -121,7 +121,7 @@ class HTMXFormMixin:
abort(response) abort(response)
def form_control(self): def form_control(self):
"""Check wether the current request is the result of the users adding """Check whether the current request is the result of the users adding
or removing a field from a FieldList.""" or removing a field from a FieldList."""
FIELDLIST_ADD_BUTTON = "fieldlist_add" FIELDLIST_ADD_BUTTON = "fieldlist_add"
FIELDLIST_REMOVE_BUTTON = "fieldlist_remove" FIELDLIST_REMOVE_BUTTON = "fieldlist_remove"

View file

@ -50,7 +50,7 @@ def type_from_filename(filename):
return maintype, subtype return maintype, subtype
def send_email(subject, recipient, text, html, attachements=None): def send_email(subject, recipient, text, html, attachments=None):
current_app.logger.debug(f"Sending a mail to {recipient}: {subject}") current_app.logger.debug(f"Sending a mail to {recipient}: {subject}")
msg = email.message.EmailMessage() msg = email.message.EmailMessage()
msg.set_content(text) msg.set_content(text)
@ -68,8 +68,8 @@ def send_email(subject, recipient, text, html, attachements=None):
msg["From"] = f'"{name}" <{address}>' msg["From"] = f'"{name}" <{address}>'
attachements = attachements or [] attachments = attachments or []
for cid, filename, value in attachements: for cid, filename, value in attachments:
maintype, subtype = type_from_filename(filename) maintype, subtype = type_from_filename(filename)
msg.get_payload()[1].add_related( msg.get_payload()[1].add_related(
value, maintype=maintype, subtype=subtype, cid=cid value, maintype=maintype, subtype=subtype, cid=cid

View file

@ -135,7 +135,7 @@ class Backend:
raise NotImplementedError() raise NotImplementedError()
def has_account_lockability(self): def has_account_lockability(self):
"""Indicate wether the backend supports locking user accounts.""" """Indicate whether the backend supports locking user accounts."""
raise NotImplementedError() raise NotImplementedError()
def register_models(self): def register_models(self):

View file

@ -111,7 +111,7 @@ def serialize(instance):
def get_factory(model): def get_factory(model):
"""Read informations about models. """Read information about models.
Options can be used to filter models:: Options can be used to filter models::

View file

@ -183,12 +183,12 @@ class MemoryBackend(Backend):
model, mirror_attribute model, mirror_attribute
).setdefault(instance.id, set()) ).setdefault(instance.id, set())
for subinstance_id in listify(instance._state.get(attribute, [])): for subinstance_id in listify(instance._state.get(attribute, [])):
# add the current objet in the subinstance state # add the current object in the subinstance state
subinstance_state = self.index(model)[subinstance_id] subinstance_state = self.index(model)[subinstance_id]
subinstance_state.setdefault(mirror_attribute, []) subinstance_state.setdefault(mirror_attribute, [])
subinstance_state[mirror_attribute].append(instance.id) subinstance_state[mirror_attribute].append(instance.id)
# add the current objet in the subinstance index # add the current object in the subinstance index
mirror_attribute_index.add(subinstance_id) mirror_attribute_index.add(subinstance_id)
def index_delete(self, instance): def index_delete(self, instance):
@ -216,11 +216,11 @@ class MemoryBackend(Backend):
for subinstance_id in self.index(instance.__class__)[instance.id].get( for subinstance_id in self.index(instance.__class__)[instance.id].get(
attribute, [] attribute, []
): ):
# remove the current objet from the subinstance state # remove the current object from the subinstance state
subinstance_state = self.index(model)[subinstance_id] subinstance_state = self.index(model)[subinstance_id]
subinstance_state[mirror_attribute].remove(instance.id) subinstance_state[mirror_attribute].remove(instance.id)
# remove the current objet from the subinstance index # remove the current object from the subinstance index
mirror_attribute_index.remove(subinstance_id) mirror_attribute_index.remove(subinstance_id)
# update the index for each attribute # update the index for each attribute

View file

@ -40,7 +40,7 @@ SECRET_KEY = "change me before you go in production"
# If EMAIL_CONFIRMATION is set to true, users will need to click on a # If EMAIL_CONFIRMATION is set to true, users will need to click on a
# confirmation link sent by email when they want to add a new email. # confirmation link sent by email when they want to add a new email.
# 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 explicitely 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 =
@ -51,7 +51,7 @@ SECRET_KEY = "change me before you go in production"
# If HIDE_INVALID_LOGINS is set to true (the default), when a user # If HIDE_INVALID_LOGINS is set to true (the default), when a user
# tries to sign in with an invalid login, a message is shown indicating # tries to sign in with an invalid login, a message is shown indicating
# that the password is wrong, but does not give a clue wether the login # that the password is wrong, but does not give a clue whether the login
# exists or not. # exists or not.
# If HIDE_INVALID_LOGINS is set to false, when a user tries to sign in with # If HIDE_INVALID_LOGINS is set to false, when a user tries to sign in with
# an invalid login, a message is shown indicating that the login does not # an invalid login, a message is shown indicating that the login does not
@ -69,7 +69,7 @@ SECRET_KEY = "change me before you go in production"
# LOGGING configures the logging output: # LOGGING configures the logging output:
# - if unset, everything is logged in the standard output # - if unset, everything is logged in the standard output
# the log level is debug if DEBUG is True, else this is INFO # the log level is debug if DEBUG is True, else this is INFO
# - if this is a dictionnary, it is passed to the python dictConfig method: # - if this is a dictionary, it is passed to the python dictConfig method:
# https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig # https://docs.python.org/3/library/logging.config.html#logging.config.dictConfig
# - 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
@ -133,7 +133,7 @@ SECRET_KEY = "change me before you go in production"
# - {groups = 'moderators'} # - {groups = 'moderators'}
# #
# The 'PERMISSIONS' parameter that is an list of items the users in the access # The 'PERMISSIONS' parameter that is an list of items the users in the access
# control will be able to manage. 'PERMISSIONS' is optionnal. Values can be: # control will be able to manage. 'PERMISSIONS' is optional. Values can be:
# - "edit_self" to allow users to edit their own profile # - "edit_self" to allow users to edit their own profile
# - "use_oidc" to allow OpenID Connect authentication # - "use_oidc" to allow OpenID Connect authentication
# - "manage_oidc" to allow OpenID Connect client managements # - "manage_oidc" to allow OpenID Connect client managements
@ -188,7 +188,7 @@ WRITE = [
] ]
[CANAILLE_OIDC] [CANAILLE_OIDC]
# Wether a token is needed for the RFC7591 dynamical client registration. # Whether a token is needed for the RFC7591 dynamical client registration.
# If true, no token is needed to register a client. # If true, no token is needed to register a client.
# If false, dynamical client registration needs a token defined # If false, dynamical client registration needs a token defined
# in DYNAMIC_CLIENT_REGISTRATION_TOKENS # in DYNAMIC_CLIENT_REGISTRATION_TOKENS

View file

@ -25,10 +25,10 @@ class SMTPSettings(BaseModel):
"""The SMTP port.""" """The SMTP port."""
TLS: Optional[bool] = False TLS: Optional[bool] = False
"""Wether to use TLS to connect to the SMTP server.""" """Whether to use TLS to connect to the SMTP server."""
SSL: Optional[bool] = False SSL: Optional[bool] = False
"""Wether to use SSL to connect to the SMTP server.""" """Whether to use SSL to connect to the SMTP server."""
LOGIN: Optional[str] = None LOGIN: Optional[str] = None
"""The SMTP login.""" """The SMTP login."""
@ -220,14 +220,14 @@ class CoreSettings(BaseModel):
"""Enables Javascript to smooth the user experience.""" """Enables Javascript to smooth the user experience."""
HTMX: bool = True HTMX: bool = True
"""Accelerates webpages loading with asynchroneous requests.""" """Accelerates webpages loading with asynchronous requests."""
EMAIL_CONFIRMATION: bool = True EMAIL_CONFIRMATION: bool = True
"""If :py:data:`True`, users will need to click on a confirmation link sent """If :py:data:`True`, users will need to click on a confirmation link sent
by email when they want to add a new email. by email when they want to add a new email.
By default, this is true By default, this is true
if ``SMTP`` is configured, else this is false. If explicitely set to true if ``SMTP`` is configured, else this is false. If explicitly set to true
and ``SMTP`` is disabled, the email field will be read-only. and ``SMTP`` is disabled, the email field will be read-only.
""" """
@ -242,7 +242,7 @@ class CoreSettings(BaseModel):
HIDE_INVALID_LOGINS: bool = True HIDE_INVALID_LOGINS: bool = True
"""If :py:data:`True`, when users try to sign in with an invalid login, a """If :py:data:`True`, when users try to sign in with an invalid login, a
message is shown indicating that the password is wrong, but does not give a message is shown indicating that the password is wrong, but does not give a
clue wether the login exists or not. clue whether the login exists or not.
If :py:data:`False`, If :py:data:`False`,
when a user tries to sign in with an invalid login, a message is shown when a user tries to sign in with an invalid login, a message is shown
@ -292,7 +292,7 @@ class CoreSettings(BaseModel):
ACL: Optional[Dict[str, ACLSettings]] = {"DEFAULT": ACLSettings()} ACL: Optional[Dict[str, ACLSettings]] = {"DEFAULT": ACLSettings()}
"""Mapping of permission groups. See :class:`ACLSettings` for more details. """Mapping of permission groups. See :class:`ACLSettings` for more details.
The ACL name can be freely choosed. For example:: The ACL name can be freely chosen. For example::
[CANAILLE.ACL.DEFAULT] [CANAILLE.ACL.DEFAULT]
PERMISSIONS = ["edit_self", "use_oidc"] PERMISSIONS = ["edit_self", "use_oidc"]

View file

@ -804,7 +804,7 @@ def profile_delete(user, edited_user):
flash( flash(
_( _(
"The user %(user)s has been sucessfuly deleted", "The user %(user)s has been successfully deleted",
user=edited_user.formatted_name, user=edited_user.formatted_name,
), ),
"success", "success",

View file

@ -46,7 +46,7 @@ def create_group(user):
Backend.instance.save(group) Backend.instance.save(group)
flash( flash(
_( _(
"The group %(group)s has been sucessfully created", "The group %(group)s has been successfully created",
group=group.display_name, group=group.display_name,
), ),
"success", "success",
@ -106,7 +106,7 @@ def edit_group(group):
Backend.instance.save(group) Backend.instance.save(group)
flash( flash(
_( _(
"The group %(group)s has been sucessfully edited.", "The group %(group)s has been successfully edited.",
group=group.display_name, group=group.display_name,
), ),
"success", "success",
@ -159,7 +159,10 @@ def delete_member(group):
def delete_group(group): def delete_group(group):
flash( flash(
_("The group %(group)s has been sucessfully deleted", group=group.display_name), _(
"The group %(group)s has been successfully deleted",
group=group.display_name,
),
"success", "success",
) )
Backend.instance.delete(group) Backend.instance.delete(group)

View file

@ -33,7 +33,7 @@ def send_test_mail(email):
recipient=email, recipient=email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )
@ -74,7 +74,7 @@ def send_password_reset_mail(user, mail):
recipient=mail, recipient=mail,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )
@ -115,7 +115,7 @@ def send_password_initialization_mail(user, email):
recipient=email, recipient=email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )
@ -146,7 +146,7 @@ def send_invitation_mail(email, registration_url):
recipient=email, recipient=email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )
@ -177,7 +177,7 @@ def send_confirmation_email(email, confirmation_url):
recipient=email, recipient=email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )
@ -208,5 +208,5 @@ def send_registration_mail(email, registration_url):
recipient=email, recipient=email,
text=text_body, text=text_body,
html=html_body, html=html_body,
attachements=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None, attachments=[(logo_cid, logo_filename, logo_raw)] if logo_filename else None,
) )

View file

@ -248,7 +248,7 @@ class User(Model):
_permissions = None _permissions = None
def has_password(self) -> bool: def has_password(self) -> bool:
"""Check wether a password has been set for the user.""" """Check whether a password has been set for the user."""
return self.password is not None return self.password is not None
def can_read(self, field: str): def can_read(self, field: str):
@ -266,7 +266,7 @@ class User(Model):
return super().__getattribute__(name) return super().__getattribute__(name)
def can(self, *permissions: Permission): def can(self, *permissions: Permission):
"""Wether or not the user has the """Whether or not the user has the
:class:`~canaille.core.configuration.Permission` according to the :class:`~canaille.core.configuration.Permission` according to the
:class:`configuration <canaille.core.configuration.ACLSettings>`.""" :class:`configuration <canaille.core.configuration.ACLSettings>`."""
if self._permissions is None: if self._permissions is None:
@ -276,7 +276,7 @@ class User(Model):
@property @property
def locked(self) -> bool: def locked(self) -> bool:
"""Wether the user account has been locked or has expired.""" """Whether the user account has been locked or has expired."""
return bool(self.lock_date) and self.lock_date < datetime.datetime.now( return bool(self.lock_date) and self.lock_date < datetime.datetime.now(
datetime.timezone.utc datetime.timezone.utc
) )

View file

@ -82,7 +82,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -30,7 +30,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -72,7 +72,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -7,7 +7,7 @@ from pydantic import BaseModel
class JWTMappingSettings(BaseModel): class JWTMappingSettings(BaseModel):
"""Mapping between the user model and the JWT fields. """Mapping between the user model and the JWT fields.
Fiels are evaluated with jinja. Fields are evaluated with jinja.
A ``user`` var is available. A ``user`` var is available.
""" """
@ -87,7 +87,7 @@ class OIDCSettings(BaseModel):
""" """
DYNAMIC_CLIENT_REGISTRATION_OPEN: bool = False DYNAMIC_CLIENT_REGISTRATION_OPEN: bool = False
"""Wether a token is needed for the RFC7591 dynamical client registration. """Whether a token is needed for the RFC7591 dynamical client registration.
If :py:data:`True`, no token is needed to register a client. If :py:data:`True`, no token is needed to register a client.
If :py:data:`False`, dynamical client registration needs a token defined in If :py:data:`False`, dynamical client registration needs a token defined in

View file

@ -432,7 +432,7 @@ class ClientManagementMixin:
def resolve_public_key(self, request): def resolve_public_key(self, request):
# At the moment the only keypair accepted in software statement # At the moment the only keypair accepted in software statement
# is the one used to isues JWTs. This might change somedays. # is the one used to issues JWTs. This might change somedays.
return current_app.config["CANAILLE_OIDC"]["JWT"]["PUBLIC_KEY"] return current_app.config["CANAILLE_OIDC"]["JWT"]["PUBLIC_KEY"]
def client_convert_data(self, **kwargs): def client_convert_data(self, **kwargs):

View file

@ -30,7 +30,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -34,7 +34,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -38,7 +38,7 @@
<div class="header"> <div class="header">
{% trans %}No item matches your request{% endtrans %} {% trans %}No item matches your request{% endtrans %}
</div> </div>
<p>{% trans %}Maybe try with different criterias?{% endtrans %}</p> <p>{% trans %}Maybe try with different criteria?{% endtrans %}</p>
{% else %} {% else %}
<div class="header"> <div class="header">
{% trans %}There is nothing here{% endtrans %} {% trans %}There is nothing here{% endtrans %}

View file

@ -32,7 +32,7 @@ Profile management
Canaille provides an interface to manage user profiles. Canaille provides an interface to manage user profiles.
The exact list of displayed fields, and wether they are :attr:`writable <canaille.core.configuration.ACLSettings.WRITE>` or :attr:`read-only <canaille.core.configuration.ACLSettings.READ>` depends on the user :class:`Access Control List settings (ACL) <canaille.core.configuration.ACLSettings>`. The exact list of displayed fields, and whether they are :attr:`writable <canaille.core.configuration.ACLSettings.WRITE>` or :attr:`read-only <canaille.core.configuration.ACLSettings.READ>` depends on the user :class:`Access Control List settings (ACL) <canaille.core.configuration.ACLSettings>`.
Depending on their ACL :class:`permissions <canaille.core.configuration.Permission>`, users can either be allowed to edit their own profile, edit any user profile, or do nothing at all. Depending on their ACL :class:`permissions <canaille.core.configuration.Permission>`, users can either be allowed to edit their own profile, edit any user profile, or do nothing at all.
@ -272,7 +272,7 @@ Thanks to its lightweight :ref:`in-memory database <tutorial/databases:Memory>`
It can also being launched in your development environment, if you find that launching a Keycloak in a Docker container is too heavy for your little web application. It can also being launched in your development environment, if you find that launching a Keycloak in a Docker container is too heavy for your little web application.
It also fits well in continuous integration scenarios. Thanks to its :ref:`CLI <feature_cli>`, you can prepare data in Canaille, let your application interract with it, and then check the side effects. It also fits well in continuous integration scenarios. Thanks to its :ref:`CLI <feature_cli>`, you can prepare data in Canaille, let your application interact with it, and then check the side effects.
Roadmap Roadmap
******* *******

View file

@ -12,7 +12,7 @@
.. rst-class:: lead .. rst-class:: lead
Lightweight Identity and Autorization Management Lightweight Identity and Authorization Management
---- ----

View file

@ -1,8 +1,8 @@
Troubleshooting Troubleshooting
############### ###############
The web interface throws unuseful error messages The web interface throws useless error messages
================================================ ===============================================
Unless the current user has admin :class:`permissions <canaille.core.configuration.Permission>`, or the installation is in :attr:`~canaille.app.configuration.RootSettings.DEBUG` mode, error messages won't be too technical. Unless the current user has admin :class:`permissions <canaille.core.configuration.Permission>`, or the installation is in :attr:`~canaille.app.configuration.RootSettings.DEBUG` mode, error messages won't be too technical.
For instance, you can see *The request you made is invalid*. For instance, you can see *The request you made is invalid*.

View file

@ -59,7 +59,7 @@ def test_form_translations(testclient, logged_user, backend):
res = form.submit(name="action", value="edit-profile") res = form.submit(name="action", value="edit-profile")
res.mustcontain(no="Not a valid phone number") res.mustcontain(no="Not a valid phone number")
res.mustcontain("Nest pas un numéro de téléphone valide") res.mustcontain("Nest pas un numéro de téléphone valid")
def test_language_config(testclient, logged_user, backend): def test_language_config(testclient, logged_user, backend):

View file

@ -15,7 +15,7 @@ from canaille.backends.ldap.utils import ldap_to_python
from canaille.backends.ldap.utils import python_to_ldap from canaille.backends.ldap.utils import python_to_ldap
# TODO: tester le changement de cardinalité des attributs # TODO: tester le changement de cardinalité des attributes
def test_object_creation(app, backend): def test_object_creation(app, backend):
user = models.User( user = models.User(
formatted_name="Doe", # leading space formatted_name="Doe", # leading space

View file

@ -188,7 +188,7 @@ def test_moderator_can_create_edit_and_delete_group(
form["description"] = "yolo2" form["description"] = "yolo2"
res = form.submit(name="action", value="edit") res = form.submit(name="action", value="edit")
assert res.flashes == [("success", "The group bar has been sucessfully edited.")] assert res.flashes == [("success", "The group bar has been successfully edited.")]
res = res.follow() res = res.follow()
bar_group = backend.get(models.Group, display_name="bar") bar_group = backend.get(models.Group, display_name="bar")
@ -199,7 +199,7 @@ def test_moderator_can_create_edit_and_delete_group(
res = res.forms["editgroupform"].submit(name="action", value="confirm-delete") res = res.forms["editgroupform"].submit(name="action", value="confirm-delete")
res = res.form.submit(name="action", value="delete", status=302) res = res.form.submit(name="action", value="delete", status=302)
assert backend.get(models.Group, display_name="bar") is None assert backend.get(models.Group, display_name="bar") is None
assert ("success", "The group bar has been sucessfully deleted") in res.flashes assert ("success", "The group bar has been successfully deleted") in res.flashes
def test_cannot_create_already_existing_group(testclient, logged_moderator, foo_group): def test_cannot_create_already_existing_group(testclient, logged_moderator, foo_group):

View file

@ -13,7 +13,7 @@ from canaille.oidc.oauth import get_jwt_config
@pytest.fixture @pytest.fixture
# For some reason all the params from the overriden fixture must be present here # For some reason all the params from the overridden fixture must be present here
# https://github.com/pytest-dev/pytest/issues/11075 # https://github.com/pytest-dev/pytest/issues/11075
def app(app, configuration, backend): def app(app, configuration, backend):
os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "true" os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "true"