From 80cc0298ce565b6fc099a6b620d04a709bb950d0 Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Sun, 19 Nov 2023 22:17:39 +0200 Subject: [PATCH] Make username and client_id templates --- README.md | 17 +++++++++++++++-- qtoggleserver/mqtt/mqtteventhandler.py | 18 ++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b90822b..dba1f9a 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,16 @@ are specified and the payload will be the template context serialized as JSON. ### `tls_enable` +Controls TLS support. + * type: `boolean` * default: `false` ### `tls_verify` +Whether to verify the server-supplied certificate. Disabling this will effectively disable server authentication, +ensuring only data transmission encryption. + * type: `boolean` * default: `true` @@ -69,20 +74,28 @@ Full path to client certificate key file, for client authentication. ### `username` +Indicates a username to supply for authentication. The value is in fact a template that can be customized following the +rules described in [Template Notifications](https://github.com/qtoggle/qtoggleserver/wiki/Template-Notifications). The +available context is limited however to `device_attrs`. + * type: `string` * default: `null` ### `password` +Indicates a password to supply for authentication. + * type: `string` * default: `null` ### `client_id` -Indicates the MQTT client id to use. +Indicates the MQTT client id to use. The value is in fact a template that can be customized following the rules +described in [Template Notifications](https://github.com/qtoggle/qtoggleserver/wiki/Template-Notifications). The +available context is limited however to `device_attrs`. * type: `string` - * default: device name + * default: `{{device_attrs.name}}` ### `reconnect_interval` diff --git a/qtoggleserver/mqtt/mqtteventhandler.py b/qtoggleserver/mqtt/mqtteventhandler.py index 8c1570e..56bbd91 100644 --- a/qtoggleserver/mqtt/mqtteventhandler.py +++ b/qtoggleserver/mqtt/mqtteventhandler.py @@ -21,6 +21,7 @@ class MqttEventHandler(TemplateNotificationsHandler): DEFAULT_PORT = 1883 DEFAULT_RECONNECT_INTERVAL = 5 # seconds DEFAULT_TOPIC = '{{device_attrs.name}}' + DEFAULT_CLIENT_ID = '{{device_attrs.name}}' DEFAULT_QOS = 0 DEFAULT_TEMPLATES = { @@ -49,7 +50,7 @@ def __init__( tls_key: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, - client_id: Optional[str] = None, + client_id: str = DEFAULT_CLIENT_ID, reconnect_interval: int = DEFAULT_RECONNECT_INTERVAL, topic: str = DEFAULT_TOPIC, json_context_fields: Optional[list[str]] = None, @@ -66,7 +67,7 @@ def __init__( self.tls_key: Optional[str] = tls_key self.username: Optional[str] = username self.password: Optional[str] = password - self.client_id: Optional[str] = client_id + self.client_id: str = client_id self.reconnect_interval: int = reconnect_interval self.topic: str = topic self.json_context_fields: Optional[set[str]] = set(json_context_fields) if json_context_fields else None @@ -79,6 +80,10 @@ def __init__( super().__init__(**kwargs) self._topic_template: Template = self.make_template(self.topic) + self._username_template: Optional[Template] = None + self._client_id_template: Template = self.make_template(self.client_id) + if self.username: + self._username_template = self.make_template(self.username) self.client_logger: logging.Logger = self.logger.getChild('client') if not self.client_logging: @@ -98,12 +103,17 @@ async def _client_loop(self) -> None: tls_context.load_cert_chain(self.tls_cert, self.tls_key) else: tls_context = None - client_id = self.client_id or core_device_attrs.attr_get_name() + + template_context = {'device_attrs': await core_device_attrs.to_json()} + client_id = await self._client_id_template.render_async(template_context) + username = None + if self._username_template: + username = await self._username_template.render_async(template_context) async with aiomqtt.Client( hostname=self.server, port=self.port, tls_context=tls_context, - username=self.username, + username=username, password=self.password, client_id=client_id, logger=self.client_logger,