Skip to content

Commit

Permalink
chore: configure ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
azmeuk committed Apr 23, 2024
1 parent 256566d commit dc89a20
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 54 deletions.
13 changes: 1 addition & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -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]
Expand All @@ -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:
Expand Down
5 changes: 3 additions & 2 deletions canaille/app/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

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>`
Expand Down
4 changes: 2 additions & 2 deletions canaille/app/flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions canaille/app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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, {}
Expand Down Expand Up @@ -120,7 +120,7 @@ def render_field(self, field, *args, **kwargs):
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"
Expand Down
19 changes: 9 additions & 10 deletions canaille/backends/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,36 @@ def session(self, *args, **kwargs):

@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.
"""
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):
Expand Down
11 changes: 6 additions & 5 deletions canaille/backends/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -120,11 +121,11 @@ def get(cls, identifier=None, **kwargs):
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):
Expand All @@ -145,7 +146,7 @@ def update(self, **kwargs):
setattr(self, attribute, value)

def reload(self):
"""Cancels the unsaved modifications.
"""Cancel the unsaved modifications.
>>> user = User.get(user_name="george")
>>> user.display_name
Expand Down
2 changes: 0 additions & 2 deletions canaille/core/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand All @@ -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)
Expand Down
8 changes: 3 additions & 5 deletions canaille/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@


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>`_
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -323,8 +322,7 @@ def writable_fields(self):


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>`_.
"""

Expand Down
3 changes: 1 addition & 2 deletions canaille/oidc/basemodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@


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
Expand Down
3 changes: 2 additions & 1 deletion canaille/oidc/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 16 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """
Expand Down
1 change: 0 additions & 1 deletion tests/backends/ldap/test_object_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
27 changes: 18 additions & 9 deletions tests/core/test_forgotten_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

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

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

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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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",
Expand Down

0 comments on commit dc89a20

Please sign in to comment.