From ddaafe5c8cd38d33859591bace8bc4b7945da683 Mon Sep 17 00:00:00 2001 From: Sami Haahtinen Date: Sun, 1 Oct 2023 21:02:35 +0100 Subject: [PATCH] Add support for TLS connections (#210) * Add support for TLS connections Add a toggle for connections that use TLS. this change makes it possible to access HTTPS enabled printers. * Add basic connection documentation Document the default values and add a note that TLS must be configured on the server side for them to work. --- custom_components/moonraker/__init__.py | 8 +++- custom_components/moonraker/api.py | 11 +++++- custom_components/moonraker/config_flow.py | 20 ++++++++-- custom_components/moonraker/const.py | 1 + .../moonraker/translations/en.json | 1 + docs/_static/connection-dialog.png | Bin 0 -> 22227 bytes docs/connection.rst | 35 ++++++++++++++++++ docs/index.rst | 1 + tests/const.py | 3 ++ tests/test_config_flow.py | 30 +++++++++++++++ 10 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 docs/_static/connection-dialog.png create mode 100644 docs/connection.rst diff --git a/custom_components/moonraker/__init__.py b/custom_components/moonraker/__init__.py index cb8414f..9caf175 100755 --- a/custom_components/moonraker/__init__.py +++ b/custom_components/moonraker/__init__.py @@ -19,6 +19,7 @@ CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, + CONF_TLS, CONF_URL, DOMAIN, HOSTNAME, @@ -60,13 +61,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): url = entry.data.get(CONF_URL) port = entry.data.get(CONF_PORT) + tls = entry.data.get(CONF_TLS) api_key = entry.data.get(CONF_API_KEY) printer_name = ( entry.data.get(CONF_PRINTER_NAME) if custom_name is None else custom_name ) api = MoonrakerApiClient( - url, async_get_clientsession(hass, verify_ssl=False), port=port, api_key=api_key + url, + async_get_clientsession(hass, verify_ssl=False), + port=port, + api_key=api_key, + tls=tls, ) try: diff --git a/custom_components/moonraker/api.py b/custom_components/moonraker/api.py index 026c24f..cda40e7 100755 --- a/custom_components/moonraker/api.py +++ b/custom_components/moonraker/api.py @@ -6,14 +6,21 @@ class MoonrakerApiClient(MoonrakerListener): """Moonraker communication API""" - def __init__(self, url, session, port: int = 7125, api_key: str = None): + def __init__( + self, url, session, port: int = 7125, api_key: str = None, tls: bool = False + ): self.running = False if api_key == "": api_key = None if port is None: port = 7125 self.client = MoonrakerClient( - listener=self, host=url, port=port, session=session, api_key=api_key + listener=self, + host=url, + port=port, + session=session, + api_key=api_key, + ssl=tls, ) async def start(self) -> None: diff --git a/custom_components/moonraker/config_flow.py b/custom_components/moonraker/config_flow.py index 7c9fcbf..0d484af 100755 --- a/custom_components/moonraker/config_flow.py +++ b/custom_components/moonraker/config_flow.py @@ -8,7 +8,15 @@ import voluptuous as vol from .api import MoonrakerApiClient -from .const import CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, CONF_URL, DOMAIN, TIMEOUT +from .const import ( + CONF_API_KEY, + CONF_PORT, + CONF_PRINTER_NAME, + CONF_TLS, + CONF_URL, + DOMAIN, + TIMEOUT, +) _LOGGER = logging.getLogger(__name__) @@ -45,7 +53,10 @@ async def async_step_user(self, user_input=None): return await self._show_config_form(user_input) if not await self._test_connection( - user_input[CONF_URL], user_input[CONF_PORT], user_input[CONF_API_KEY] + user_input[CONF_URL], + user_input[CONF_PORT], + user_input[CONF_API_KEY], + user_input[CONF_TLS], ): self._errors[CONF_URL] = "printer_connection_error" return await self._show_config_form(user_input) @@ -57,6 +68,7 @@ async def async_step_user(self, user_input=None): # Provide defaults for form user_input[CONF_URL] = "192.168.1.123" user_input[CONF_PORT] = "7125" + user_input[CONF_TLS] = False user_input[CONF_API_KEY] = "" user_input[CONF_PRINTER_NAME] = "" @@ -72,6 +84,7 @@ async def _show_config_form(self, user_input): # pylint: disable=unused-argumen { vol.Required(CONF_URL, default=user_input[CONF_URL]): str, vol.Optional(CONF_PORT, default=user_input[CONF_PORT]): str, + vol.Optional(CONF_TLS, default=user_input[CONF_TLS]): bool, vol.Optional(CONF_API_KEY, default=user_input[CONF_API_KEY]): str, vol.Optional( CONF_PRINTER_NAME, default=user_input[CONF_PRINTER_NAME] @@ -104,12 +117,13 @@ async def _test_printer_name(self, printer_name): return True - async def _test_connection(self, host, port, api_key): + async def _test_connection(self, host, port, api_key, tls): api = MoonrakerApiClient( host, async_get_clientsession(self.hass, verify_ssl=False), port=port, api_key=api_key, + tls=tls, ) try: diff --git a/custom_components/moonraker/const.py b/custom_components/moonraker/const.py index f88f3c0..f5c0b81 100644 --- a/custom_components/moonraker/const.py +++ b/custom_components/moonraker/const.py @@ -22,6 +22,7 @@ CONF_API_KEY = "api_key" CONF_URL = "url" CONF_PORT = "port" +CONF_TLS = "tls" CONF_PRINTER_NAME = "printer_name" # API dict keys diff --git a/custom_components/moonraker/translations/en.json b/custom_components/moonraker/translations/en.json index 876242a..b6f31a5 100644 --- a/custom_components/moonraker/translations/en.json +++ b/custom_components/moonraker/translations/en.json @@ -6,6 +6,7 @@ "data": { "url": "Host", "port": "Port", + "tls": "Uses TLS", "api_key": "API Key (Optional)", "printer_name": "Printer's Name (Defaults to the hostname)" } diff --git a/docs/_static/connection-dialog.png b/docs/_static/connection-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7ca9e26fa516eb52339d88792cb65831f8c9a0 GIT binary patch literal 22227 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 F{V$YK^3DJN literal 0 HcmV?d00001 diff --git a/docs/connection.rst b/docs/connection.rst new file mode 100644 index 0000000..cc0fbfc --- /dev/null +++ b/docs/connection.rst @@ -0,0 +1,35 @@ +Connection properties +====================== + +The connection properties dialog can be used to connect to the Moonraker API. +The integration is capable of connecting to most Moonraker deployments. + +.. image:: _static/connection-dialog.png + :align: center + +Connection properties can be defined as follows: + +.. list-table:: Connection properties + :header-rows: 1 + + * - name + - default + - description + * - Host + - None, **(required)** + - IP address or hostname of Moonraker + * - Port + - 7125 + - Moonraker port + * - Uses TLS + - + - use encrypted connections + * - API Key + - + - Moonraker API key + * - Printer's Name + - Host address + - Device name in Home Assistant + +Note: Encrypted connections must be configured in Moonraker API or by using a +reverse proxy to connect to Moonraker API. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 22cdac0..5ba702b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -33,6 +33,7 @@ This software seems to have issues working on **FLSUN Speeder Pad** and **Sonic install dashboard + connection .. toctree:: :caption: Usage diff --git a/tests/const.py b/tests/const.py index cf1dcf8..2280fc4 100644 --- a/tests/const.py +++ b/tests/const.py @@ -3,6 +3,7 @@ CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, + CONF_TLS, CONF_URL, ) @@ -10,6 +11,7 @@ MOCK_CONFIG = { CONF_URL: "1.2.3.4", CONF_PORT: "1234", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "", } @@ -17,6 +19,7 @@ MOCK_CONFIG_WITH_NAME = { CONF_URL: "1.2.3.4", CONF_PORT: "1234", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "example name", } diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index b5b86b5..8f807bd 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -8,6 +8,7 @@ CONF_API_KEY, CONF_PORT, CONF_PRINTER_NAME, + CONF_TLS, CONF_URL, DOMAIN, ) @@ -133,12 +134,36 @@ async def test_server_host_when_good(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "7125", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "", } assert result["result"] +@pytest.mark.usefixtures("bypass_connect_client") +async def test_server_ssl_enabled(hass): + """Test server host with TLS.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={CONF_URL: "1.2.3.4", CONF_TLS: True} + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result["title"] == DOMAIN + assert result["data"] == { + CONF_URL: "1.2.3.4", + CONF_PORT: "7125", + CONF_API_KEY: "", + CONF_TLS: True, + CONF_PRINTER_NAME: "", + } + assert result["result"] + + @pytest.mark.usefixtures("bypass_connect_client") async def test_server_port_too_low(hass): """Test server port when it's too low.""" @@ -194,6 +219,7 @@ async def test_server_port_when_good_port(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "7611", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "", } @@ -216,6 +242,7 @@ async def test_server_port_when_port_empty(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "", } @@ -281,6 +308,7 @@ async def test_server_api_key_when_good(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "7125", + CONF_TLS: False, CONF_API_KEY: "A7ylD3EuPWWxGlsshlCIJjzRBNbQzlre", CONF_PRINTER_NAME: "", } @@ -306,6 +334,7 @@ async def test_server_api_key_when_empty(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "7125", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "", } @@ -343,6 +372,7 @@ async def test_printer_name_when_good(hass): assert result["data"] == { CONF_URL: "1.2.3.4", CONF_PORT: "7125", + CONF_TLS: False, CONF_API_KEY: "", CONF_PRINTER_NAME: "example name", }