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
hooks:
- 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.
- Password reset and initialization mails were not sent at all the user
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.
[0.0.35] - 2023-11-25
@ -612,7 +612,7 @@ Changed
Fixed
^^^^^
- ``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
--------------------
@ -679,7 +679,7 @@ Added
- Added an option to tune object IDs :pr:`26`
- Avatar support :pr:`27`
- Dynamical and configurable JWT claims :pr:`28`
- UI improvemnts :pr:`29`
- UI improvements :pr:`29`
- Invitation links expiration :pr:`30`
- Invitees can choose their IDs :pr:`31`
- LDAP backend refactoring :pr:`35`
@ -705,7 +705,7 @@ Added
- Two-steps sign-in :issue:`49`
- Tokens can have several audiences. :issue:`62` :pr:`9`
- Configuration check command. :issue:`66` :pr:`8`
- Groups managament. :issue:`12` :pr:`6`
- Groups management. :issue:`12` :pr:`6`
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.
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
`pre-commit <https://pre-commit.com/>`_ configuration with ``pre-commit install``.

View file

@ -121,7 +121,7 @@ class HTMXFormMixin:
abort(response)
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."""
FIELDLIST_ADD_BUTTON = "fieldlist_add"
FIELDLIST_REMOVE_BUTTON = "fieldlist_remove"

View file

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

View file

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

View file

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

View file

@ -183,12 +183,12 @@ class MemoryBackend(Backend):
model, mirror_attribute
).setdefault(instance.id, set())
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.setdefault(mirror_attribute, [])
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)
def index_delete(self, instance):
@ -216,11 +216,11 @@ class MemoryBackend(Backend):
for subinstance_id in self.index(instance.__class__)[instance.id].get(
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[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)
# 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
# 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.
# 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.
# 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
# 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.
# 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
@ -69,7 +69,7 @@ SECRET_KEY = "change me before you go in production"
# LOGGING configures the logging output:
# - if unset, everything is logged in the standard output
# 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
# - 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
@ -133,7 +133,7 @@ SECRET_KEY = "change me before you go in production"
# - {groups = 'moderators'}
#
# 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
# - "use_oidc" to allow OpenID Connect authentication
# - "manage_oidc" to allow OpenID Connect client managements
@ -188,7 +188,7 @@ WRITE = [
]
[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 false, dynamical client registration needs a token defined
# in DYNAMIC_CLIENT_REGISTRATION_TOKENS

View file

@ -25,10 +25,10 @@ class SMTPSettings(BaseModel):
"""The SMTP port."""
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
"""Wether to use SSL to connect to the SMTP server."""
"""Whether to use SSL to connect to the SMTP server."""
LOGIN: Optional[str] = None
"""The SMTP login."""
@ -220,14 +220,14 @@ class CoreSettings(BaseModel):
"""Enables Javascript to smooth the user experience."""
HTMX: bool = True
"""Accelerates webpages loading with asynchroneous requests."""
"""Accelerates webpages loading with asynchronous requests."""
EMAIL_CONFIRMATION: bool = True
"""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 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.
"""
@ -242,7 +242,7 @@ class CoreSettings(BaseModel):
HIDE_INVALID_LOGINS: bool = True
"""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
clue wether the login exists or not.
clue whether the login exists or not.
If :py:data:`False`,
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()}
"""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]
PERMISSIONS = ["edit_self", "use_oidc"]

View file

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

View file

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

View file

@ -33,7 +33,7 @@ def send_test_mail(email):
recipient=email,
text=text_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,
text=text_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,
text=text_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,
text=text_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,
text=text_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,
text=text_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
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
def can_read(self, field: str):
@ -266,7 +266,7 @@ class User(Model):
return super().__getattribute__(name)
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:`configuration <canaille.core.configuration.ACLSettings>`."""
if self._permissions is None:
@ -276,7 +276,7 @@ class User(Model):
@property
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(
datetime.timezone.utc
)

View file

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

View file

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

View file

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

View file

@ -7,7 +7,7 @@ from pydantic import BaseModel
class JWTMappingSettings(BaseModel):
"""Mapping between the user model and the JWT fields.
Fiels are evaluated with jinja.
Fields are evaluated with jinja.
A ``user`` var is available.
"""
@ -87,7 +87,7 @@ class OIDCSettings(BaseModel):
"""
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:`False`, dynamical client registration needs a token defined in

View file

@ -432,7 +432,7 @@ class ClientManagementMixin:
def resolve_public_key(self, request):
# 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"]
def client_convert_data(self, **kwargs):

View file

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

View file

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

View file

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

View file

@ -32,7 +32,7 @@ Profile management
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.
@ -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 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
*******

View file

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

View file

@ -1,8 +1,8 @@
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.
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.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):

View file

@ -15,7 +15,7 @@ from canaille.backends.ldap.utils import ldap_to_python
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):
user = models.User(
formatted_name="Doe", # leading space

View file

@ -188,7 +188,7 @@ def test_moderator_can_create_edit_and_delete_group(
form["description"] = "yolo2"
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()
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.form.submit(name="action", value="delete", status=302)
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):

View file

@ -13,7 +13,7 @@ from canaille.oidc.oauth import get_jwt_config
@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
def app(app, configuration, backend):
os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "true"