kopia lustrzana https://github.com/Yakifo/amqtt
the sys/broker plugin requires the full BrokerContext. moving 'BasePlugin' into its own file to remove a circular import. also fixing lint errors and updating pre commit config to mirror the checks being run in ci only
rodzic
1e1e2026d3
commit
92eb3da74b
|
@ -10,75 +10,6 @@ ci:
|
|||
- pylint
|
||||
|
||||
repos:
|
||||
# Codespell for spelling corrections
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --ignore-words-list=ihs,ro,fo,assertIn,astroid,formated
|
||||
- --skip="./.*,*.csv,*.json"
|
||||
- --quiet-level=2
|
||||
exclude_types:
|
||||
- csv
|
||||
- json
|
||||
|
||||
# General pre-commit hooks
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: detect-private-key
|
||||
exclude: tests/_test_files/certs/
|
||||
- id: check-merge-conflict
|
||||
- id: check-added-large-files
|
||||
- id: check-case-conflict
|
||||
# - id: no-commit-to-branch
|
||||
# args: [--branch, main]
|
||||
- id: check-executables-have-shebangs
|
||||
- id: trailing-whitespace
|
||||
name: Trim Trailing Whitespace
|
||||
description: This hook trims trailing whitespace.
|
||||
entry: trailing-whitespace-fixer
|
||||
language: python
|
||||
types: [text]
|
||||
args: [--markdown-linebreak-ext=md]
|
||||
- id: check-toml
|
||||
- id: check-json
|
||||
- id: check-yaml
|
||||
args: [--allow-multiple-documents]
|
||||
- id: mixed-line-ending
|
||||
|
||||
# Prettier for code formatting
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v4.0.0-alpha.8
|
||||
hooks:
|
||||
- id: prettier
|
||||
additional_dependencies:
|
||||
- prettier@3.2.5
|
||||
- prettier-plugin-sort-json@3.1.0
|
||||
exclude_types:
|
||||
- python
|
||||
|
||||
# Secret detection
|
||||
- repo: https://github.com/Yelp/detect-secrets
|
||||
rev: v1.5.0
|
||||
hooks:
|
||||
- id: detect-secrets
|
||||
args:
|
||||
- --exclude-files=tests/*
|
||||
- --exclude-files=samples/client_subscribe_acl.py
|
||||
- --exclude-files=docs/quickstart.rst
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.26.0
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
|
||||
# YAML Linting
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.37.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
|
||||
# Python-specific hooks ######################################################
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.11.10
|
||||
|
@ -90,11 +21,6 @@ repos:
|
|||
- --line-length=130
|
||||
- --exit-non-zero-on-fix
|
||||
- id: ruff-format
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.19.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py313-plus]
|
||||
|
||||
# Local hooks for mypy and pylint
|
||||
- repo: local
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from passlib.apps import custom_app_context as pwd_context
|
||||
|
||||
from amqtt.broker import BrokerContext
|
||||
from amqtt.plugins.manager import BaseContext, BasePlugin
|
||||
from amqtt.plugins.base import BasePlugin
|
||||
from amqtt.session import Session
|
||||
|
||||
_PARTS_EXPECTED_LENGTH = 2 # Expected number of parts in a valid line
|
||||
|
@ -12,10 +13,10 @@ _PARTS_EXPECTED_LENGTH = 2 # Expected number of parts in a valid line
|
|||
class BaseAuthPlugin(BasePlugin):
|
||||
"""Base class for authentication plugins."""
|
||||
|
||||
def __init__(self, context: BaseContext) -> None:
|
||||
def __init__(self, context: BrokerContext) -> None:
|
||||
super().__init__(context)
|
||||
|
||||
self.auth_config = self.context.config.get("auth", None) if self.context.config else None
|
||||
self.auth_config: dict[str, Any] | None = self._get_config_section("auth")
|
||||
if not self.auth_config:
|
||||
self.context.logger.warning("'auth' section not found in context configuration")
|
||||
|
||||
|
@ -30,7 +31,6 @@ class BaseAuthPlugin(BasePlugin):
|
|||
- `None` if authentication can't be achieved (then plugin result is then ignored)
|
||||
|
||||
"""
|
||||
|
||||
if not self.auth_config:
|
||||
# auth config section not found
|
||||
self.context.logger.warning("'auth' section not found in context configuration")
|
||||
|
@ -50,7 +50,6 @@ class AnonymousAuthPlugin(BaseAuthPlugin):
|
|||
self.context.logger.debug("Authentication success: config allows anonymous")
|
||||
return True
|
||||
|
||||
session: Session | None = session
|
||||
if session and session.username:
|
||||
self.context.logger.debug(f"Authentication success: session has username '{session.username}'")
|
||||
return True
|
||||
|
@ -61,7 +60,7 @@ class AnonymousAuthPlugin(BaseAuthPlugin):
|
|||
class FileAuthPlugin(BaseAuthPlugin):
|
||||
"""Authentication plugin based on a file-stored user database."""
|
||||
|
||||
def __init__(self, context: BaseContext) -> None:
|
||||
def __init__(self, context: BrokerContext) -> None:
|
||||
super().__init__(context)
|
||||
self._users: dict[str, str] = {}
|
||||
self._read_password_file()
|
||||
|
@ -98,7 +97,6 @@ class FileAuthPlugin(BaseAuthPlugin):
|
|||
"""Authenticate users based on the file-stored user database."""
|
||||
authenticated = await super().authenticate(session=session)
|
||||
if authenticated:
|
||||
|
||||
if not session:
|
||||
self.context.logger.debug("Authentication failure: no session provided")
|
||||
return False
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
from typing import Any
|
||||
|
||||
from amqtt.broker import BrokerContext
|
||||
|
||||
|
||||
class BasePlugin:
|
||||
"""The base from which all plugins should inherit."""
|
||||
|
||||
def __init__(self, context: BrokerContext) -> None:
|
||||
self.context = context
|
||||
|
||||
def _get_config_section(self, name: str) -> dict[str, Any] | None:
|
||||
if not self.context.config or not hasattr(self.context.config, name):
|
||||
return None
|
||||
section_config: int | dict[str, Any] | None = self.context.config.get(name, None)
|
||||
# mypy has difficulty excluding int from `config`'s type, unless isinstance` is its own check
|
||||
if isinstance(section_config, int):
|
||||
return None
|
||||
return section_config
|
|
@ -3,8 +3,7 @@ from functools import partial
|
|||
import logging
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from amqtt.plugins.manager import BasePlugin
|
||||
|
||||
from amqtt.plugins.base import BasePlugin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from amqtt.session import Session
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
__all__ = ["BaseContext", "PluginManager", "get_plugin_manager", "BasePlugin"]
|
||||
__all__ = ["BaseContext", "PluginManager", "get_plugin_manager"]
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
@ -35,11 +35,6 @@ class BaseContext:
|
|||
self.logger: logging.Logger = _LOGGER
|
||||
self.config: dict[str, Any] | None = None
|
||||
|
||||
class BasePlugin:
|
||||
def __init__(self, context: BaseContext) -> None:
|
||||
self.context = context
|
||||
|
||||
|
||||
|
||||
class PluginManager:
|
||||
"""Wraps contextlib Entry point mechanism to provide a basic plugin system.
|
||||
|
|
|
@ -2,7 +2,7 @@ import asyncio
|
|||
from collections import deque # pylint: disable=C0412
|
||||
from typing import SupportsIndex, SupportsInt # pylint: disable=C0412
|
||||
|
||||
from amqtt.plugins.manager import BasePlugin
|
||||
from amqtt.plugins.base import BasePlugin
|
||||
|
||||
try:
|
||||
from collections.abc import Buffer
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
from typing import Any
|
||||
|
||||
from amqtt.broker import Action
|
||||
from amqtt.plugins.manager import BaseContext, BasePlugin
|
||||
from amqtt.broker import Action, BrokerContext
|
||||
from amqtt.plugins.base import BasePlugin
|
||||
from amqtt.session import Session
|
||||
|
||||
|
||||
class BaseTopicPlugin(BasePlugin):
|
||||
"""Base class for topic plugins."""
|
||||
|
||||
def __init__(self, context: BaseContext) -> None:
|
||||
def __init__(self, context: BrokerContext) -> None:
|
||||
super().__init__(context)
|
||||
|
||||
self.topic_config: dict[str, Any] | None = self.context.config.get("topic-check", None) if self.context.config else None
|
||||
self.topic_config: dict[str, Any] | None = self._get_config_section("topic-check")
|
||||
if self.topic_config is None:
|
||||
self.context.logger.warning("'topic-check' section not found in context configuration")
|
||||
|
||||
async def topic_filtering(self, *, session: Session = None, topic: str = None, action: Action = None) -> bool:
|
||||
async def topic_filtering(
|
||||
self, *, session: Session | None = None, topic: str | None = None, action: Action | None = None
|
||||
) -> bool:
|
||||
"""Logic for filtering out topics.
|
||||
|
||||
Args:
|
||||
|
@ -35,11 +37,13 @@ class BaseTopicPlugin(BasePlugin):
|
|||
|
||||
|
||||
class TopicTabooPlugin(BaseTopicPlugin):
|
||||
def __init__(self, context: BaseContext) -> None:
|
||||
def __init__(self, context: BrokerContext) -> None:
|
||||
super().__init__(context)
|
||||
self._taboo: list[str] = ["prohibited", "top-secret", "data/classified"]
|
||||
|
||||
async def topic_filtering(self, *, session: Session = None, topic: str = None, action: Action = None) -> bool:
|
||||
async def topic_filtering(
|
||||
self, *, session: Session | None = None, topic: str | None = None, action: Action | None = None
|
||||
) -> bool:
|
||||
filter_result = await super().topic_filtering(session=session, topic=topic, action=action)
|
||||
if filter_result:
|
||||
if session and session.username == "admin":
|
||||
|
@ -69,7 +73,9 @@ class TopicAccessControlListPlugin(BaseTopicPlugin):
|
|||
break
|
||||
return ret
|
||||
|
||||
async def topic_filtering(self, *, session: Session = None, topic: str = None, action: Action = None) -> bool:
|
||||
async def topic_filtering(
|
||||
self, *, session: Session | None = None, topic: str | None = None, action: Action | None = None
|
||||
) -> bool:
|
||||
filter_result = await super().topic_filtering(session=session, topic=topic, action=action)
|
||||
if not filter_result:
|
||||
return False
|
||||
|
|
|
@ -88,7 +88,6 @@ theme:
|
|||
extra_css:
|
||||
- assets/extra.css
|
||||
|
||||
|
||||
#extra_javascript:
|
||||
#- assets/extra.js
|
||||
|
||||
|
@ -117,7 +116,6 @@ markdown_extensions:
|
|||
- toc:
|
||||
permalink: "¤"
|
||||
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- autorefs
|
||||
|
|
Ładowanie…
Reference in New Issue