From 2f56509c275d8a7c3371134ca16bea9607567b90 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 07:47:50 +0000 Subject: [PATCH 1/3] Initial plan From f95ad72b93310f9a5061ac9e749561af831163ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 07:50:42 +0000 Subject: [PATCH 2/3] Raise error when both password and key_file are provided Co-authored-by: gensyn <36128035+gensyn@users.noreply.github.com> Agent-Logs-Url: https://github.com/gensyn/ssh_command/sessions/5ab62ef3-b3b0-453f-be28-8e9642eafc4c --- README.md | 2 +- __init__.py | 7 +++++++ strings.json | 3 +++ tests/unit_tests/test_validate_service_data.py | 5 +++++ translations/de.json | 3 +++ translations/en.json | 3 +++ 6 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c332ef..ffcb953 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ All parameters are optional in the raw schema except `host` and `username` — t #### Validation rules enforced by the service -- Either `password` or `key_file` must be provided +- Either `password` or `key_file` must be provided, but not both - Either `command` or `input` or both must be provided - If `key_file` is provided, the file must exist on the Home Assistant filesystem - `known_hosts` may not be provided when `check_known_hosts` is `false` diff --git a/__init__.py b/__init__.py index 61d9e4a..9bff380 100644 --- a/__init__.py +++ b/__init__.py @@ -31,6 +31,13 @@ async def _validate_service_data(data: dict[str, Any]) -> None: translation_key="password_or_key_file_required", ) + if has_password and has_key_file: + raise ServiceValidationError( + "Password and key file cannot both be provided.", + translation_domain=DOMAIN, + translation_key="password_and_key_file", + ) + has_command: bool = bool(data.get(CONF_COMMAND)) has_input: bool = bool(data.get(CONF_INPUT)) diff --git a/strings.json b/strings.json index b17ed4f..2f868bc 100644 --- a/strings.json +++ b/strings.json @@ -53,6 +53,9 @@ "password_or_key_file_required": { "message": "Either password or key file must be provided." }, + "password_and_key_file": { + "message": "Password and key file cannot both be provided." + }, "command_or_input": { "message": "Either command or input must be provided." }, diff --git a/tests/unit_tests/test_validate_service_data.py b/tests/unit_tests/test_validate_service_data.py index 90b458d..3574479 100644 --- a/tests/unit_tests/test_validate_service_data.py +++ b/tests/unit_tests/test_validate_service_data.py @@ -21,6 +21,11 @@ async def test_no_password_no_key_file_raises(self): await _validate_service_data({"command": "echo hi"}) self.assertEqual(ctx.exception.translation_key, "password_or_key_file_required") + async def test_password_and_key_file_raises(self): + with self.assertRaises(ServiceValidationError) as ctx: + await _validate_service_data({"password": "secret", "key_file": "/home/user/.ssh/id_rsa", "command": "echo hi"}) + self.assertEqual(ctx.exception.translation_key, "password_and_key_file") + async def test_no_command_no_input_raises(self): with self.assertRaises(ServiceValidationError) as ctx: await _validate_service_data({"password": "secret"}) diff --git a/translations/de.json b/translations/de.json index 24b7b9b..bb59079 100644 --- a/translations/de.json +++ b/translations/de.json @@ -49,6 +49,9 @@ "password_or_key_file_required": { "message": "Entweder Passwort oder Schlüsseldatei muss angegeben werden." }, + "password_and_key_file": { + "message": "Passwort und Schlüsseldatei können nicht gleichzeitig angegeben werden." + }, "command_or_input": { "message": "Entweder Befehl oder Eingabe muss angegeben werden." }, diff --git a/translations/en.json b/translations/en.json index e2a8919..c52b05e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -49,6 +49,9 @@ "password_or_key_file_required": { "message": "Either password or key file must be provided." }, + "password_and_key_file": { + "message": "Password and key file cannot both be provided." + }, "command_or_input": { "message": "Either command or input must be provided." }, From 9ef88353607c39bcc4f9de35bc0a49f89c74c0eb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:07:53 +0000 Subject: [PATCH 3/3] Fix test_password_and_key_file_raises to pass hass argument Co-authored-by: gensyn <36128035+gensyn@users.noreply.github.com> Agent-Logs-Url: https://github.com/gensyn/ssh_command/sessions/e7e48fd7-44bc-4678-9965-fa84aeff7366 --- tests/unit_tests/test_validate_service_data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit_tests/test_validate_service_data.py b/tests/unit_tests/test_validate_service_data.py index a5f104a..4e5b443 100644 --- a/tests/unit_tests/test_validate_service_data.py +++ b/tests/unit_tests/test_validate_service_data.py @@ -31,7 +31,7 @@ async def test_no_password_no_key_file_raises(self): async def test_password_and_key_file_raises(self): with self.assertRaises(ServiceValidationError) as ctx: - await _validate_service_data({"password": "secret", "key_file": "/home/user/.ssh/id_rsa", "command": "echo hi"}) + await _validate_service_data(self.mock_hass, {"password": "secret", "key_file": "/home/user/.ssh/id_rsa", "command": "echo hi"}) self.assertEqual(ctx.exception.translation_key, "password_and_key_file") async def test_no_command_no_input_raises(self):