chore: configure ruff

This commit is contained in:
Éloi Rivard 2024-04-23 22:12:04 +02:00
parent 256566df94
commit dc89a20b11
No known key found for this signature in database
GPG key ID: 7EDA204EA57DD184
13 changed files with 63 additions and 54 deletions

View file

@ -1,7 +1,7 @@
---
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.3.7'
rev: 'v0.4.1'
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
@ -15,21 +15,10 @@ repos:
- id: end-of-file-fixer
exclude: "\\.svg$|\\.map$|\\.min\\.css$|\\.min\\.js$|\\.po$|\\.pot$"
- id: check-toml
- repo: https://github.com/pycqa/isort
rev: "5.13.2"
hooks:
- id: isort
name: isort (python)
args: ["--force-single-line-imports", "--profile", "black"]
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.5
hooks:
- id: docformatter
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.2
hooks:
- id: pyupgrade
args: ["--py38-plus"]
- repo: https://github.com/rtts/djhtml
rev: 3.0.6
hooks:

View file

@ -17,8 +17,9 @@ ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class RootSettings(BaseSettings):
"""The top-level namespace contains holds the configuration settings
unrelated to Canaille. The configuration paramateres from the following
libraries can be used:
unrelated to Canaille.
The configuration paramateres from the following libraries can be used:
- :doc:`Flask <flask:config>`
- :doc:`Flask-WTF <flask-wtf:config>`

View file

@ -36,7 +36,7 @@ def current_user():
def login_user(user):
"""Opens a session for the user."""
"""Open a session for the user."""
g.user = user
try:
previous = (
@ -50,7 +50,7 @@ def login_user(user):
def logout_user():
"""Closes the user session."""
"""Close the user session."""
try:
session["user_id"].pop()
del g.user

View file

@ -72,7 +72,7 @@ class HTMXFormMixin:
render_field_extra_context = {}
def field_from_name(self, field_name):
"""Returns a tuple containing a field and its rendering context."""
"""Return a tuple containing a field and its rendering context."""
if self.SEPARATOR not in field_name:
field = self[field_name] if field_name in self else None
return field, {}
@ -120,7 +120,7 @@ class HTMXFormMixin:
abort(response)
def form_control(self):
"""Checks wether the current request is the result of the users adding
"""Check wether 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

@ -34,21 +34,20 @@ class BaseBackend:
@classmethod
def install(self, config):
"""This methods prepares the database to host canaille data."""
"""Prepare the database to host canaille data."""
raise NotImplementedError()
def setup(self):
"""This method will be called before each http request, it should open
the connection to the backend."""
"""Is called before each http request, it should open the connection to
the backend."""
def teardown(self):
"""This method will be called after each http request, it should close
the connections to the backend."""
"""Is called after each http request, it should close the connections
to the backend."""
@classmethod
def validate(cls, config):
"""This method should validate the config part dedicated to the
backend.
"""Validate the config part dedicated to the backend.
It should raise :class:`~canaille.configuration.ConfigurationError` when
errors are met.
@ -56,15 +55,15 @@ class BaseBackend:
raise NotImplementedError()
def check_user_password(self, user, password: str) -> bool:
"""Checks if the password matches the user password in the database."""
"""Check if the password matches the user password in the database."""
raise NotImplementedError()
def set_user_password(self, user, password: str):
"""Sets a password for the user."""
"""Set a password for the user."""
raise NotImplementedError()
def has_account_lockability(self):
"""Indicates wether the backend supports locking user accounts."""
"""Indicate wether the backend supports locking user accounts."""
raise NotImplementedError()
def register_models(self):

View file

@ -89,8 +89,9 @@ class BackendModel:
@classmethod
def query(cls, **kwargs):
"""
Performs a query on the database and return a collection of instances.
"""Perform a query on the database and return a collection of
instances.
Parameters can be any valid attribute with the expected value:
>>> User.query(first_name="George")
@ -120,11 +121,11 @@ class BackendModel:
raise NotImplementedError()
def save(self):
"""Validates the current modifications in the database."""
"""Validate the current modifications in the database."""
raise NotImplementedError()
def delete(self):
"""Removes the current instance from the database."""
"""Remove the current instance from the database."""
raise NotImplementedError()
def update(self, **kwargs):
@ -145,7 +146,7 @@ class BackendModel:
setattr(self, attribute, value)
def reload(self):
"""Cancels the unsaved modifications.
"""Cancel the unsaved modifications.
>>> user = User.get(user_name="george")
>>> user.display_name

View file

@ -26,7 +26,6 @@ def populate(ctx, nb):
@with_backendcontext
def users(ctx):
"""Populate the database with generated random users."""
from canaille.core.populate import fake_users
fake_users(ctx.obj["number"])
@ -43,7 +42,6 @@ def users(ctx):
@with_backendcontext
def groups(ctx, nb_users_max):
"""Populate the database with generated random groups."""
from canaille.core.populate import fake_groups
fake_groups(ctx.obj["number"], nb_users_max)

View file

@ -11,8 +11,7 @@ from canaille.core.configuration import Permission
class User(Model):
"""
User model, based on the `SCIM User schema
"""User model, based on the `SCIM User schema
<https://datatracker.ietf.org/doc/html/rfc7643#section-4.1>`_,
`Entreprise User Schema Extension
<https://datatracker.ietf.org/doc/html/rfc7643#section-4.3>`_
@ -249,7 +248,7 @@ class User(Model):
_permissions = None
def has_password(self) -> bool:
"""Checks wether a password has been set for the user."""
"""Check wether a password has been set for the user."""
return self.password is not None
def can_read(self, field: str):
@ -323,8 +322,7 @@ class User(Model):
class Group(Model):
"""
User model, based on the `SCIM Group schema
"""User model, based on the `SCIM Group schema
<https://datatracker.ietf.org/doc/html/rfc7643#section-4.2>`_.
"""

View file

@ -8,8 +8,7 @@ from canaille.core.models import User
class Client(Model):
"""
OpenID Connect client definition, based on the
"""OpenID Connect client definition, based on the
`OAuth 2.0 Dynamic Client Registration protocols
<https://datatracker.ietf.org/doc/html/rfc7591.html>`_
and the `OpenID Connect RP-Initiated Logout

View file

@ -90,7 +90,8 @@ class OIDCSettings(BaseModel):
"""Wether 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 :attr:`DYNAMIC_CLIENT_REGISTRATION_TOKENS`.
If :py:data:`False`, dynamical client registration needs a token defined in
:attr:`DYNAMIC_CLIENT_REGISTRATION_TOKENS`.
"""
DYNAMIC_CLIENT_REGISTRATION_TOKENS: Optional[List[str]] = None

View file

@ -179,7 +179,22 @@ exclude_lines = [
]
[tool.ruff.lint]
ignore = ["E501", "E722"]
select = [
"E", # pycodestyle
"F", # pyflakes
"I", # isort
"UP", # pyupgrade
]
ignore = [
"E501", # line-too-long
"E722", # bare-except
]
[tool.ruff.lint.isort]
force-single-line = true
[too.ruff.format]
docstring-code-format = true
[tool.tox]
legacy_tox_ini = """

View file

@ -67,7 +67,6 @@ def test_keep_old_object_classes(backend, testclient, slapd_server):
In such a case Canaille should keep the unmanaged objectClass and
attributes.
"""
user = models.User(cn="foo", sn="bar", user_name="baz")
user.save()

View file

@ -18,7 +18,8 @@ def test_password_forgotten(smtpd, testclient, user):
res = res.form.submit(status=200)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. You should receive "
"it within a few minutes.",
) in res.flashes
res.mustcontain("Send again")
@ -35,7 +36,8 @@ def test_password_forgotten_multiple_mails(smtpd, testclient, user):
res = res.form.submit(status=200)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. You should receive "
"it within a few minutes.",
) in res.flashes
res.mustcontain("Send again")
@ -61,7 +63,8 @@ def test_password_forgotten_invalid(smtpd, testclient, user):
res = res.form.submit(status=200)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. "
"You should receive it within a few minutes.",
) in res.flashes
res.mustcontain(no="The login &#39;i-dont-really-exist&#39; does not exist")
@ -72,7 +75,8 @@ def test_password_forgotten_invalid(smtpd, testclient, user):
res = res.form.submit(status=200)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. "
"You should receive it within a few minutes.",
) not in res.flashes
res.mustcontain("The login &#39;i-dont-really-exist&#39; does not exist")
@ -90,11 +94,13 @@ def test_password_forgotten_invalid_when_user_cannot_self_edit(smtpd, testclient
res = res.form.submit(status=200)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. "
"You should receive it within a few minutes.",
) not in res.flashes
assert (
"error",
"The user 'John (johnny) Doe' does not have permissions to update their password. We cannot send a password reset email.",
"The user 'John (johnny) Doe' does not have permissions to update their "
"password. We cannot send a password reset email.",
) in res.flashes
testclient.app.config["CANAILLE"]["HIDE_INVALID_LOGINS"] = True
@ -105,11 +111,13 @@ def test_password_forgotten_invalid_when_user_cannot_self_edit(smtpd, testclient
res = res.form.submit(status=200)
assert (
"error",
"The user 'John (johnny) Doe' does not have permissions to update their password. We cannot send a password reset email.",
"The user 'John (johnny) Doe' does not have permissions to update their "
"password. We cannot send a password reset email.",
) not in res.flashes
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. "
"You should receive it within a few minutes.",
) in res.flashes
assert len(smtpd.messages) == 0
@ -124,7 +132,8 @@ def test_password_forgotten_mail_error(SMTP, smtpd, testclient, user):
res = res.form.submit(status=200, expect_errors=True)
assert (
"success",
"A password reset link has been sent at your email address. You should receive it within a few minutes.",
"A password reset link has been sent at your email address. "
"You should receive it within a few minutes.",
) not in res.flashes
assert (
"error",