KNX ConfigFlow: Validate contents of knxkeys file (#84411)
parent
c99025be26
commit
a752232de8
|
@ -440,18 +440,37 @@ class KNXCommonFlow(ABC, FlowHandler):
|
|||
) -> FlowResult:
|
||||
"""Configure secure knxkeys used to authenticate."""
|
||||
errors = {}
|
||||
description_placeholders = {}
|
||||
|
||||
if user_input is not None:
|
||||
connection_type = self.new_entry_data[CONF_KNX_CONNECTION_TYPE]
|
||||
storage_key = CONST_KNX_STORAGE_KEY + user_input[CONF_KNX_KNXKEY_FILENAME]
|
||||
try:
|
||||
await load_keyring(
|
||||
keyring = await load_keyring(
|
||||
path=self.hass.config.path(STORAGE_DIR, storage_key),
|
||||
password=user_input[CONF_KNX_KNXKEY_PASSWORD],
|
||||
)
|
||||
except FileNotFoundError:
|
||||
errors[CONF_KNX_KNXKEY_FILENAME] = "file_not_found"
|
||||
errors[CONF_KNX_KNXKEY_FILENAME] = "keyfile_not_found"
|
||||
except InvalidSecureConfiguration:
|
||||
errors[CONF_KNX_KNXKEY_PASSWORD] = "invalid_signature"
|
||||
errors[CONF_KNX_KNXKEY_PASSWORD] = "keyfile_invalid_signature"
|
||||
else:
|
||||
if (
|
||||
connection_type == CONF_KNX_TUNNELING_TCP_SECURE
|
||||
and self._selected_tunnel is not None
|
||||
):
|
||||
tunnel_endpoints = []
|
||||
if host_ia := self._selected_tunnel.individual_address:
|
||||
tunnel_endpoints = keyring.get_tunnel_interfaces_by_host(
|
||||
host=host_ia
|
||||
)
|
||||
if not tunnel_endpoints:
|
||||
errors["base"] = "keyfile_no_tunnel_for_host"
|
||||
description_placeholders = {CONF_HOST: str(host_ia)}
|
||||
|
||||
if connection_type == CONF_KNX_ROUTING_SECURE:
|
||||
if not (keyring.backbone is not None and keyring.backbone.key):
|
||||
errors["base"] = "keyfile_no_backbone_key"
|
||||
|
||||
if not errors:
|
||||
self.new_entry_data |= KNXConfigEntryData(
|
||||
|
@ -463,10 +482,7 @@ class KNXCommonFlow(ABC, FlowHandler):
|
|||
user_id=None,
|
||||
user_password=None,
|
||||
)
|
||||
if (
|
||||
self.new_entry_data[CONF_KNX_CONNECTION_TYPE]
|
||||
== CONF_KNX_ROUTING_SECURE
|
||||
):
|
||||
if connection_type == CONF_KNX_ROUTING_SECURE:
|
||||
title = (
|
||||
"Secure Routing as"
|
||||
f" {self.new_entry_data[CONF_KNX_INDIVIDUAL_ADDRESS]}"
|
||||
|
@ -488,7 +504,10 @@ class KNXCommonFlow(ABC, FlowHandler):
|
|||
}
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="secure_knxkeys", data_schema=vol.Schema(fields), errors=errors
|
||||
step_id="secure_knxkeys",
|
||||
data_schema=vol.Schema(fields),
|
||||
errors=errors,
|
||||
description_placeholders=description_placeholders,
|
||||
)
|
||||
|
||||
async def async_step_routing(self, user_input: dict | None = None) -> FlowResult:
|
||||
|
|
|
@ -2,18 +2,21 @@
|
|||
"config": {
|
||||
"step": {
|
||||
"connection_type": {
|
||||
"title": "KNX connection",
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing.",
|
||||
"data": {
|
||||
"connection_type": "KNX Connection Type"
|
||||
}
|
||||
},
|
||||
"tunnel": {
|
||||
"title": "Tunnel",
|
||||
"description": "Please select a gateway from the list.",
|
||||
"data": {
|
||||
"gateway": "KNX Tunnel Connection"
|
||||
}
|
||||
},
|
||||
"manual_tunnel": {
|
||||
"title": "Tunnel settings",
|
||||
"description": "Please enter the connection information of your tunneling device.",
|
||||
"data": {
|
||||
"tunneling_type": "KNX Tunneling Type",
|
||||
|
@ -30,6 +33,7 @@
|
|||
}
|
||||
},
|
||||
"secure_key_source": {
|
||||
"title": "KNX IP-Secure",
|
||||
"description": "Select how you want to configure KNX/IP Secure.",
|
||||
"menu_options": {
|
||||
"secure_knxkeys": "Use a `.knxkeys` file containing IP secure keys",
|
||||
|
@ -38,6 +42,7 @@
|
|||
}
|
||||
},
|
||||
"secure_knxkeys": {
|
||||
"title": "Keyfile",
|
||||
"description": "Please enter the information for your `.knxkeys` file.",
|
||||
"data": {
|
||||
"knxkeys_filename": "The filename of your `.knxkeys` file (including extension)",
|
||||
|
@ -49,6 +54,7 @@
|
|||
}
|
||||
},
|
||||
"secure_tunnel_manual": {
|
||||
"title": "Secure tunnelling",
|
||||
"description": "Please enter your IP secure information.",
|
||||
"data": {
|
||||
"user_id": "User ID",
|
||||
|
@ -62,6 +68,7 @@
|
|||
}
|
||||
},
|
||||
"secure_routing_manual": {
|
||||
"title": "Secure routing",
|
||||
"description": "Please enter your IP secure information.",
|
||||
"data": {
|
||||
"backbone_key": "Backbone key",
|
||||
|
@ -73,6 +80,7 @@
|
|||
}
|
||||
},
|
||||
"routing": {
|
||||
"title": "Routing",
|
||||
"description": "Please configure the routing options.",
|
||||
"data": {
|
||||
"individual_address": "Individual address",
|
||||
|
@ -96,8 +104,10 @@
|
|||
"invalid_backbone_key": "Invalid backbone key. 32 hexadecimal numbers expected.",
|
||||
"invalid_individual_address": "Value does not match pattern for KNX individual address.\n'area.line.device'",
|
||||
"invalid_ip_address": "Invalid IPv4 address.",
|
||||
"invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"file_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"keyfile_invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"keyfile_no_backbone_key": "The `.knxkeys` file does not contain a backbone key for secure routing.",
|
||||
"keyfile_no_tunnel_for_host": "The `.knxkeys` file does not contain credentials for host `{host}`.",
|
||||
"keyfile_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"no_router_discovered": "No KNXnet/IP router was discovered on the network.",
|
||||
"no_tunnel_discovered": "Could not find a KNX tunneling server on your network.",
|
||||
"unsupported_tunnel_type": "Selected tunnelling type not supported by gateway."
|
||||
|
@ -106,12 +116,14 @@
|
|||
"options": {
|
||||
"step": {
|
||||
"options_init": {
|
||||
"title": "KNX Settings",
|
||||
"menu_options": {
|
||||
"connection_type": "Configure KNX interface",
|
||||
"communication_settings": "Communication settings"
|
||||
}
|
||||
},
|
||||
"communication_settings": {
|
||||
"title": "Communication settings",
|
||||
"data": {
|
||||
"state_updater": "State updater",
|
||||
"rate_limit": "Rate limit"
|
||||
|
@ -122,18 +134,21 @@
|
|||
}
|
||||
},
|
||||
"connection_type": {
|
||||
"title": "[%key:component::knx::config::step::connection_type::title%]",
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing.",
|
||||
"data": {
|
||||
"connection_type": "KNX Connection Type"
|
||||
}
|
||||
},
|
||||
"tunnel": {
|
||||
"title": "[%key:component::knx::config::step::tunnel::title%]",
|
||||
"description": "[%key:component::knx::config::step::tunnel::description%]",
|
||||
"data": {
|
||||
"gateway": "[%key:component::knx::config::step::tunnel::data::gateway%]"
|
||||
}
|
||||
},
|
||||
"manual_tunnel": {
|
||||
"title": "[%key:component::knx::config::step::manual_tunnel::title%]",
|
||||
"description": "[%key:component::knx::config::step::manual_tunnel::description%]",
|
||||
"data": {
|
||||
"tunneling_type": "[%key:component::knx::config::step::manual_tunnel::data::tunneling_type%]",
|
||||
|
@ -150,6 +165,7 @@
|
|||
}
|
||||
},
|
||||
"secure_key_source": {
|
||||
"title": "[%key:component::knx::config::step::secure_key_source::title%]",
|
||||
"description": "[%key:component::knx::config::step::secure_key_source::description%]",
|
||||
"menu_options": {
|
||||
"secure_knxkeys": "[%key:component::knx::config::step::secure_key_source::menu_options::secure_knxkeys%]",
|
||||
|
@ -158,6 +174,7 @@
|
|||
}
|
||||
},
|
||||
"secure_knxkeys": {
|
||||
"title": "[%key:component::knx::config::step::secure_knxkeys::title%]",
|
||||
"description": "[%key:component::knx::config::step::secure_knxkeys::description%]",
|
||||
"data": {
|
||||
"knxkeys_filename": "[%key:component::knx::config::step::secure_knxkeys::data::knxkeys_filename%]",
|
||||
|
@ -169,6 +186,7 @@
|
|||
}
|
||||
},
|
||||
"secure_tunnel_manual": {
|
||||
"title": "[%key:component::knx::config::step::secure_tunnel_manual::title%]",
|
||||
"description": "[%key:component::knx::config::step::secure_tunnel_manual::description%]",
|
||||
"data": {
|
||||
"user_id": "[%key:component::knx::config::step::secure_tunnel_manual::data::user_id%]",
|
||||
|
@ -182,6 +200,7 @@
|
|||
}
|
||||
},
|
||||
"secure_routing_manual": {
|
||||
"title": "[%key:component::knx::config::step::secure_routing_manual::title%]",
|
||||
"description": "[%key:component::knx::config::step::secure_routing_manual::description%]",
|
||||
"data": {
|
||||
"backbone_key": "[%key:component::knx::config::step::secure_routing_manual::data::backbone_key%]",
|
||||
|
@ -193,6 +212,7 @@
|
|||
}
|
||||
},
|
||||
"routing": {
|
||||
"title": "[%key:component::knx::config::step::routing::title%]",
|
||||
"description": "[%key:component::knx::config::step::routing::description%]",
|
||||
"data": {
|
||||
"individual_address": "[%key:component::knx::config::step::routing::data::individual_address%]",
|
||||
|
@ -212,8 +232,10 @@
|
|||
"invalid_backbone_key": "[%key:component::knx::config::error::invalid_backbone_key%]",
|
||||
"invalid_individual_address": "[%key:component::knx::config::error::invalid_individual_address%]",
|
||||
"invalid_ip_address": "[%key:component::knx::config::error::invalid_ip_address%]",
|
||||
"invalid_signature": "[%key:component::knx::config::error::invalid_signature%]",
|
||||
"file_not_found": "[%key:component::knx::config::error::file_not_found%]",
|
||||
"keyfile_no_backbone_key": "[%key:component::knx::config::error::keyfile_no_backbone_key%]",
|
||||
"keyfile_invalid_signature": "[%key:component::knx::config::error::keyfile_invalid_signature%]",
|
||||
"keyfile_no_tunnel_for_host": "[%key:component::knx::config::error::keyfile_no_tunnel_for_host%]",
|
||||
"keyfile_not_found": "[%key:component::knx::config::error::keyfile_not_found%]",
|
||||
"no_router_discovered": "[%key:component::knx::config::error::no_router_discovered%]",
|
||||
"no_tunnel_discovered": "[%key:component::knx::config::error::no_tunnel_discovered%]",
|
||||
"unsupported_tunnel_type": "[%key:component::knx::config::error::unsupported_tunnel_type%]"
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"file_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"invalid_backbone_key": "Invalid backbone key. 32 hexadecimal numbers expected.",
|
||||
"invalid_individual_address": "Value does not match pattern for KNX individual address.\n'area.line.device'",
|
||||
"invalid_ip_address": "Invalid IPv4 address.",
|
||||
"invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"keyfile_invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"keyfile_no_backbone_key": "The `.knxkeys` file does not contain a backbone key for secure routing.",
|
||||
"keyfile_no_tunnel_for_host": "The `.knxkeys` file does not contain credentials for host `{host}`.",
|
||||
"keyfile_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"no_router_discovered": "No KNXnet/IP router was discovered on the network.",
|
||||
"no_tunnel_discovered": "Could not find a KNX tunneling server on your network.",
|
||||
"unsupported_tunnel_type": "Selected tunnelling type not supported by gateway."
|
||||
|
@ -20,7 +22,8 @@
|
|||
"data": {
|
||||
"connection_type": "KNX Connection Type"
|
||||
},
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing."
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing.",
|
||||
"title": "KNX connection"
|
||||
},
|
||||
"manual_tunnel": {
|
||||
"data": {
|
||||
|
@ -36,7 +39,8 @@
|
|||
"port": "Port of the KNX/IP tunneling device.",
|
||||
"route_back": "Enable if your KNXnet/IP tunneling server is behind NAT. Only applies for UDP connections."
|
||||
},
|
||||
"description": "Please enter the connection information of your tunneling device."
|
||||
"description": "Please enter the connection information of your tunneling device.",
|
||||
"title": "Tunnel settings"
|
||||
},
|
||||
"routing": {
|
||||
"data": {
|
||||
|
@ -50,7 +54,8 @@
|
|||
"individual_address": "KNX address to be used by Home Assistant, e.g. `0.0.4`",
|
||||
"local_ip": "Leave blank to use auto-discovery."
|
||||
},
|
||||
"description": "Please configure the routing options."
|
||||
"description": "Please configure the routing options.",
|
||||
"title": "Routing"
|
||||
},
|
||||
"secure_key_source": {
|
||||
"description": "Select how you want to configure KNX/IP Secure.",
|
||||
|
@ -58,7 +63,8 @@
|
|||
"secure_knxkeys": "Use a `.knxkeys` file containing IP secure keys",
|
||||
"secure_routing_manual": "Configure IP secure backbone key manually",
|
||||
"secure_tunnel_manual": "Configure IP secure credentials manually"
|
||||
}
|
||||
},
|
||||
"title": "KNX IP-Secure"
|
||||
},
|
||||
"secure_knxkeys": {
|
||||
"data": {
|
||||
|
@ -69,7 +75,8 @@
|
|||
"knxkeys_filename": "The file is expected to be found in your config directory in `.storage/knx/`.\nIn Home Assistant OS this would be `/config/.storage/knx/`\nExample: `my_project.knxkeys`",
|
||||
"knxkeys_password": "This was set when exporting the file from ETS."
|
||||
},
|
||||
"description": "Please enter the information for your `.knxkeys` file."
|
||||
"description": "Please enter the information for your `.knxkeys` file.",
|
||||
"title": "Keyfile"
|
||||
},
|
||||
"secure_routing_manual": {
|
||||
"data": {
|
||||
|
@ -80,7 +87,8 @@
|
|||
"backbone_key": "Can be seen in the 'Security' report of an ETS project. Eg. '00112233445566778899AABBCCDDEEFF'",
|
||||
"sync_latency_tolerance": "Default is 1000."
|
||||
},
|
||||
"description": "Please enter your IP secure information."
|
||||
"description": "Please enter your IP secure information.",
|
||||
"title": "Secure routing"
|
||||
},
|
||||
"secure_tunnel_manual": {
|
||||
"data": {
|
||||
|
@ -93,24 +101,28 @@
|
|||
"user_id": "This is often tunnel number +1. So 'Tunnel 2' would have User-ID '3'.",
|
||||
"user_password": "Password for the specific tunnel connection set in the 'Properties' panel of the tunnel in ETS."
|
||||
},
|
||||
"description": "Please enter your IP secure information."
|
||||
"description": "Please enter your IP secure information.",
|
||||
"title": "Secure tunnelling"
|
||||
},
|
||||
"tunnel": {
|
||||
"data": {
|
||||
"gateway": "KNX Tunnel Connection"
|
||||
},
|
||||
"description": "Please select a gateway from the list."
|
||||
"description": "Please select a gateway from the list.",
|
||||
"title": "Tunnel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"file_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"invalid_backbone_key": "Invalid backbone key. 32 hexadecimal numbers expected.",
|
||||
"invalid_individual_address": "Value does not match pattern for KNX individual address.\n'area.line.device'",
|
||||
"invalid_ip_address": "Invalid IPv4 address.",
|
||||
"invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"keyfile_invalid_signature": "The password to decrypt the `.knxkeys` file is wrong.",
|
||||
"keyfile_no_backbone_key": "The `.knxkeys` file does not contain a backbone key for secure routing.",
|
||||
"keyfile_no_tunnel_for_host": "The `.knxkeys` file does not contain credentials for host `{host}`.",
|
||||
"keyfile_not_found": "The specified `.knxkeys` file was not found in the path config/.storage/knx/",
|
||||
"no_router_discovered": "No KNXnet/IP router was discovered on the network.",
|
||||
"no_tunnel_discovered": "Could not find a KNX tunneling server on your network.",
|
||||
"unsupported_tunnel_type": "Selected tunnelling type not supported by gateway."
|
||||
|
@ -124,13 +136,15 @@
|
|||
"data_description": {
|
||||
"rate_limit": "Maximum outgoing telegrams per second.\n`0` to disable limit. Recommended: 0 or 20 to 40",
|
||||
"state_updater": "Set default for reading states from the KNX Bus. When disabled, Home Assistant will not actively retrieve entity states from the KNX Bus. Can be overridden by `sync_state` entity options."
|
||||
}
|
||||
},
|
||||
"title": "Communication settings"
|
||||
},
|
||||
"connection_type": {
|
||||
"data": {
|
||||
"connection_type": "KNX Connection Type"
|
||||
},
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing."
|
||||
"description": "Please enter the connection type we should use for your KNX connection. \n AUTOMATIC - The integration takes care of the connectivity to your KNX Bus by performing a gateway scan. \n TUNNELING - The integration will connect to your KNX bus via tunneling. \n ROUTING - The integration will connect to your KNX bus via routing.",
|
||||
"title": "KNX connection"
|
||||
},
|
||||
"manual_tunnel": {
|
||||
"data": {
|
||||
|
@ -146,13 +160,15 @@
|
|||
"port": "Port of the KNX/IP tunneling device.",
|
||||
"route_back": "Enable if your KNXnet/IP tunneling server is behind NAT. Only applies for UDP connections."
|
||||
},
|
||||
"description": "Please enter the connection information of your tunneling device."
|
||||
"description": "Please enter the connection information of your tunneling device.",
|
||||
"title": "Tunnel settings"
|
||||
},
|
||||
"options_init": {
|
||||
"menu_options": {
|
||||
"communication_settings": "Communication settings",
|
||||
"connection_type": "Configure KNX interface"
|
||||
}
|
||||
},
|
||||
"title": "KNX Settings"
|
||||
},
|
||||
"routing": {
|
||||
"data": {
|
||||
|
@ -166,7 +182,8 @@
|
|||
"individual_address": "KNX address to be used by Home Assistant, e.g. `0.0.4`",
|
||||
"local_ip": "Leave blank to use auto-discovery."
|
||||
},
|
||||
"description": "Please configure the routing options."
|
||||
"description": "Please configure the routing options.",
|
||||
"title": "Routing"
|
||||
},
|
||||
"secure_key_source": {
|
||||
"description": "Select how you want to configure KNX/IP Secure.",
|
||||
|
@ -174,7 +191,8 @@
|
|||
"secure_knxkeys": "Use a `.knxkeys` file containing IP secure keys",
|
||||
"secure_routing_manual": "Configure IP secure backbone key manually",
|
||||
"secure_tunnel_manual": "Configure IP secure credentials manually"
|
||||
}
|
||||
},
|
||||
"title": "KNX IP-Secure"
|
||||
},
|
||||
"secure_knxkeys": {
|
||||
"data": {
|
||||
|
@ -185,7 +203,8 @@
|
|||
"knxkeys_filename": "The file is expected to be found in your config directory in `.storage/knx/`.\nIn Home Assistant OS this would be `/config/.storage/knx/`\nExample: `my_project.knxkeys`",
|
||||
"knxkeys_password": "This was set when exporting the file from ETS."
|
||||
},
|
||||
"description": "Please enter the information for your `.knxkeys` file."
|
||||
"description": "Please enter the information for your `.knxkeys` file.",
|
||||
"title": "Keyfile"
|
||||
},
|
||||
"secure_routing_manual": {
|
||||
"data": {
|
||||
|
@ -196,7 +215,8 @@
|
|||
"backbone_key": "Can be seen in the 'Security' report of an ETS project. Eg. '00112233445566778899AABBCCDDEEFF'",
|
||||
"sync_latency_tolerance": "Default is 1000."
|
||||
},
|
||||
"description": "Please enter your IP secure information."
|
||||
"description": "Please enter your IP secure information.",
|
||||
"title": "Secure routing"
|
||||
},
|
||||
"secure_tunnel_manual": {
|
||||
"data": {
|
||||
|
@ -209,13 +229,15 @@
|
|||
"user_id": "This is often tunnel number +1. So 'Tunnel 2' would have User-ID '3'.",
|
||||
"user_password": "Password for the specific tunnel connection set in the 'Properties' panel of the tunnel in ETS."
|
||||
},
|
||||
"description": "Please enter your IP secure information."
|
||||
"description": "Please enter your IP secure information.",
|
||||
"title": "Secure tunnelling"
|
||||
},
|
||||
"tunnel": {
|
||||
"data": {
|
||||
"gateway": "KNX Tunnel Connection"
|
||||
},
|
||||
"description": "Please select a gateway from the list."
|
||||
"description": "Please select a gateway from the list.",
|
||||
"title": "Tunnel"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
"""Test the KNX config flow."""
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from xknx.exceptions.exception import CommunicationError, InvalidSecureConfiguration
|
||||
from xknx.io import DEFAULT_MCAST_GRP, DEFAULT_MCAST_PORT
|
||||
from xknx.io.gateway_scanner import GatewayDescriptor
|
||||
from xknx.telegram import IndividualAddress
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.knx.config_flow import (
|
||||
|
@ -44,6 +45,8 @@ from homeassistant.data_entry_flow import FlowResult, FlowResultType
|
|||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
GATEWAY_INDIVIDUAL_ADDRESS = IndividualAddress("1.0.0")
|
||||
|
||||
|
||||
@pytest.fixture(name="knx_setup")
|
||||
def fixture_knx_setup():
|
||||
|
@ -63,6 +66,7 @@ def _gateway_descriptor(
|
|||
"""Get mock gw descriptor."""
|
||||
descriptor = GatewayDescriptor(
|
||||
name="Test",
|
||||
individual_address=GATEWAY_INDIVIDUAL_ADDRESS,
|
||||
ip_addr=ip,
|
||||
port=port,
|
||||
local_interface="eth0",
|
||||
|
@ -352,9 +356,25 @@ async def test_routing_secure_keyfile(
|
|||
assert result4["step_id"] == "secure_knxkeys"
|
||||
assert not result4["errors"]
|
||||
|
||||
# test file without backbone key
|
||||
with patch(
|
||||
"homeassistant.components.knx.config_flow.load_keyring", return_value=True
|
||||
):
|
||||
"homeassistant.components.knx.config_flow.load_keyring"
|
||||
) as mock_load_keyring:
|
||||
mock_keyring = Mock()
|
||||
mock_keyring.backbone.key = None
|
||||
mock_load_keyring.return_value = mock_keyring
|
||||
secure_knxkeys = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_KNX_KNXKEY_FILENAME: "testcase.knxkeys",
|
||||
CONF_KNX_KNXKEY_PASSWORD: "password",
|
||||
},
|
||||
)
|
||||
assert secure_knxkeys["type"] == FlowResultType.FORM
|
||||
assert secure_knxkeys["errors"] == {"base": "keyfile_no_backbone_key"}
|
||||
|
||||
# test valid file
|
||||
with patch("homeassistant.components.knx.config_flow.load_keyring"):
|
||||
routing_secure_knxkeys = await hass.config_entries.flow.async_configure(
|
||||
result4["flow_id"],
|
||||
{
|
||||
|
@ -976,8 +996,11 @@ async def test_configure_secure_knxkeys(hass: HomeAssistant, knx_setup):
|
|||
assert not result["errors"]
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.knx.config_flow.load_keyring", return_value=True
|
||||
):
|
||||
"homeassistant.components.knx.config_flow.load_keyring"
|
||||
) as mock_load_keyring:
|
||||
mock_keyring = Mock()
|
||||
mock_keyring.get_tunnel_interfaces_by_host.return_value = ["stub"]
|
||||
mock_load_keyring.return_value = mock_keyring
|
||||
secure_knxkeys = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
|
@ -1031,7 +1054,7 @@ async def test_configure_secure_knxkeys_file_not_found(hass: HomeAssistant):
|
|||
)
|
||||
assert secure_knxkeys["type"] == FlowResultType.FORM
|
||||
assert secure_knxkeys["errors"]
|
||||
assert secure_knxkeys["errors"][CONF_KNX_KNXKEY_FILENAME] == "file_not_found"
|
||||
assert secure_knxkeys["errors"][CONF_KNX_KNXKEY_FILENAME] == "keyfile_not_found"
|
||||
|
||||
|
||||
async def test_configure_secure_knxkeys_invalid_signature(hass: HomeAssistant):
|
||||
|
@ -1059,7 +1082,39 @@ async def test_configure_secure_knxkeys_invalid_signature(hass: HomeAssistant):
|
|||
)
|
||||
assert secure_knxkeys["type"] == FlowResultType.FORM
|
||||
assert secure_knxkeys["errors"]
|
||||
assert secure_knxkeys["errors"][CONF_KNX_KNXKEY_PASSWORD] == "invalid_signature"
|
||||
assert (
|
||||
secure_knxkeys["errors"][CONF_KNX_KNXKEY_PASSWORD]
|
||||
== "keyfile_invalid_signature"
|
||||
)
|
||||
|
||||
|
||||
async def test_configure_secure_knxkeys_no_tunnel_for_host(hass: HomeAssistant):
|
||||
"""Test configure secure knxkeys but file was not found."""
|
||||
menu_step = await _get_menu_step(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
menu_step["flow_id"],
|
||||
{"next_step_id": "secure_knxkeys"},
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["step_id"] == "secure_knxkeys"
|
||||
assert not result["errors"]
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.knx.config_flow.load_keyring"
|
||||
) as mock_load_keyring:
|
||||
mock_keyring = Mock()
|
||||
mock_keyring.get_tunnel_interfaces_by_host.return_value = []
|
||||
mock_load_keyring.return_value = mock_keyring
|
||||
secure_knxkeys = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
CONF_KNX_KNXKEY_FILENAME: "testcase.knxkeys",
|
||||
CONF_KNX_KNXKEY_PASSWORD: "password",
|
||||
},
|
||||
)
|
||||
assert secure_knxkeys["type"] == FlowResultType.FORM
|
||||
assert secure_knxkeys["errors"] == {"base": "keyfile_no_tunnel_for_host"}
|
||||
|
||||
|
||||
async def test_options_flow_connection_type(
|
||||
|
@ -1185,9 +1240,7 @@ async def test_options_flow_secure_manual_to_keyfile(
|
|||
assert result4["step_id"] == "secure_knxkeys"
|
||||
assert not result4["errors"]
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.knx.config_flow.load_keyring", return_value=True
|
||||
):
|
||||
with patch("homeassistant.components.knx.config_flow.load_keyring"):
|
||||
secure_knxkeys = await hass.config_entries.options.async_configure(
|
||||
result4["flow_id"],
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue