standardizing naming convention for new plugins

pull/288/head
Andrew Mirsky 2025-08-06 14:08:45 -04:00
rodzic 04591aaaab
commit ae6d772927
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: A98E67635CDF2C39
5 zmienionych plików z 38 dodań i 25 usunięć

Wyświetl plik

@ -20,7 +20,7 @@ def default_hash_scheme() -> list[str]:
return ["argon2", "bcrypt", "pbkdf2_sha256", "scrypt"]
class UserAuthDBPlugin(BaseAuthPlugin, BaseTopicPlugin):
class UserAuthDBPlugin(BaseAuthPlugin):
def __init__(self, context: BrokerContext) -> None:
super().__init__(context)

Wyświetl plik

@ -15,7 +15,7 @@ from aiohttp import ClientResponse, ClientSession, FormData
from amqtt.broker import BrokerContext
from amqtt.contexts import Action
from amqtt.plugins.base import BaseAuthPlugin, BaseTopicPlugin, BasePlugin
from amqtt.plugins.base import BaseAuthPlugin, BasePlugin, BaseTopicPlugin
from amqtt.session import Session
logger = logging.getLogger(__name__)
@ -72,7 +72,7 @@ class HttpConfig:
"""duration, in seconds, to wait for the HTTP server to respond"""
class HttpPlugin(BasePlugin):
class AuthHttpPlugin(BasePlugin[BrokerContext]):
def __init__(self, context: BrokerContext) -> None:
super().__init__(context)
@ -138,7 +138,7 @@ class HttpPlugin(BasePlugin):
return f"{'https' if self.config.with_tls else 'http'}://{self.config.host}:{self.config.port}{uri}"
class HttpAuthPlugin(HttpPlugin, BaseAuthPlugin):
class UserAuthHttpPlugin(AuthHttpPlugin, BaseAuthPlugin):
async def authenticate(self, *, session: Session) -> bool | None:
d = {"username": session.username, "password": session.password, "client_id": session.client_id}
@ -152,7 +152,7 @@ class HttpAuthPlugin(HttpPlugin, BaseAuthPlugin):
"""URI of the auth check."""
class HttpTopicPlugin(HttpPlugin, BaseTopicPlugin):
class TopicAuthHttpPlugin(AuthHttpPlugin, BaseTopicPlugin):
async def topic_filtering(self, *,
session: Session | None = None,
@ -175,5 +175,6 @@ class HttpTopicPlugin(HttpPlugin, BaseTopicPlugin):
@dataclass
class Config(HttpConfig):
"""Configuration for the HTTP Topic Plugin."""
topic_uri: str = "/acl"
"""URI of the topic check."""

Wyświetl plik

@ -1,7 +1,7 @@
# Relational Database for Authentication and Authorization
- `amqtt.contrib.auth_db.AuthUserDBPlugin` (authentication) verify a client's ability to connect to broker
- `amqtt.contrib.auth_db.AuthTopicDBPlugin` (authorization) determine a client's access to topics
- `amqtt.contrib.auth_db.UserAuthDBPlugin` (authentication) verify a client's ability to connect to broker
- `amqtt.contrib.auth_db.TopicAuthDBPlugin` (authorization) determine a client's access to topics
Relational database access is supported using SQLAlchemy so MySQL, MariaDB, Postgres and SQLite support is available.

Wyświetl plik

@ -1,9 +1,16 @@
# Authentication & Authorization via external HTTP server
`amqtt.contrib.http.HttpAuthPlugin`
If clients accessing the broker are managed by another application, it can implement API endpoints
that respond with information about client authenticated and topic-level authorization.
that respond with information about client authentication and/or topic-level authorization.
- `amqtt.contrib.http.UserAuthHttpPlugin` (client authentication)
- `amqtt.contrib.http.TopicAuthHttpPlugin` (topic authorization)
Configuration of these plugins is identical (except for the uri name) so that they can be used independently, if desired.
## User Auth
See the [Request and Response Modes](#request-response-modes) section below for details on `params_mode` and `response_mode`.
!!! info "browser-based mqtt over websockets"
@ -35,9 +42,18 @@ that respond with information about client authenticated and topic-level authori
try {
const clientMqtt = await mqtt.connect(url, options);
See the [Request and Response Modes](#request-response-modes) section below for details on `params_mode` and `response_mode`.
::: amqtt.contrib.http.UserAuthHttpPlugin.Config
options:
show_source: false
heading_level: 4
extra:
class_style: "simple"
::: amqtt.contrib.http.HttpAuthPlugin.Config
## Topic ACL
See the [Request and Response Modes](#request-response-modes) section below for details on `params_mode` and `response_mode`.
::: amqtt.contrib.http.TopicAuthHttpPlugin.Config
options:
show_source: false
heading_level: 4
@ -57,10 +73,6 @@ format will depend on `params_mode` configuration attribute (`json` or `form`).:
- password *(str)*
- client_id *(str)*
*For superuser validation, the request will contain:*
- username *(str)*
*For acl check, the request will contain:*
- username *(str)*
@ -75,8 +87,8 @@ All endpoints should respond with the following, dependent on `response_mode` co
- status code: 2xx (granted) or 4xx(denied) or 5xx (noop)
!!! note "5xx response"
**noop** (no operation): plugin will not participate in the filtering operation and will defer to another
topic filtering plugin to determine access. if there is no other topic filtering plugin, access will be denied.
**noop** (no operation): plugin will not participate in the operation and will defer to another
plugin to determine access. if there is no other auth/filtering plugin, access will be denied.
*In `json` mode:*
@ -87,8 +99,8 @@ All endpoints should respond with the following, dependent on `response_mode` co
or { 'error': 'optional error message' } (noop)
!!! note "excluded 'ok' key"
**noop** (no operation): plugin will not participate in the filtering operation and will defer to another
topic filtering plugin to determine access. if there is no other topic filtering plugin, access will be denied.
**noop** (no operation): plugin will not participate in the operation and will defer to another
plugin to determine access. if there is no other auth/filtering plugin, access will be denied.
*In `text` mode:*

Wyświetl plik

@ -8,7 +8,7 @@ from aiohttp.web import Response
from amqtt.broker import BrokerContext, Broker
from amqtt.contexts import Action
from amqtt.contrib.http import HttpAuthPlugin, ParamsMode, ResponseMode, RequestMethod, HttpTopicPlugin
from amqtt.contrib.http import UserAuthHttpPlugin, TopicAuthHttpPlugin, ParamsMode, ResponseMode, RequestMethod
from amqtt.session import Session
logger = logging.getLogger(__name__)
@ -135,7 +135,7 @@ async def test_request_auth_response(empty_broker, http_server, kind, url,
username, matcher, is_allowed):
context = BrokerContext(broker=empty_broker)
context.config = HttpAuthPlugin.Config(
context.config = UserAuthHttpPlugin.Config(
host="127.0.0.1",
port=8080,
user_uri=url,
@ -143,7 +143,7 @@ async def test_request_auth_response(empty_broker, http_server, kind, url,
params_mode=params_mode,
response_mode=response_mode,
)
http_acl = HttpAuthPlugin(context)
http_acl = UserAuthHttpPlugin(context)
logger.warning(f'kind is {kind}')
session = Session()
@ -162,7 +162,7 @@ async def test_request_topic_response(empty_broker, http_server, kind, url,
request_method, params_mode, response_mode,
username, matcher, is_allowed):
context = BrokerContext(broker=empty_broker)
context.config = HttpTopicPlugin.Config(
context.config = TopicAuthHttpPlugin.Config(
host="127.0.0.1",
port=8080,
topic_uri=url,
@ -170,7 +170,7 @@ async def test_request_topic_response(empty_broker, http_server, kind, url,
params_mode=params_mode,
response_mode=response_mode,
)
http_acl = HttpTopicPlugin(context)
http_acl = TopicAuthHttpPlugin(context)
s = Session()
s.username = username