Support configuring Axis to use HTTPS (#113271)

This commit is contained in:
Robert Svensson 2024-03-15 18:58:49 +01:00 committed by GitHub
parent be7c4295dc
commit 5b5ff92a05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 17 deletions

View file

@ -25,6 +25,7 @@ from homeassistant.const import (
CONF_NAME,
CONF_PASSWORD,
CONF_PORT,
CONF_PROTOCOL,
CONF_USERNAME,
)
from homeassistant.core import callback
@ -42,7 +43,9 @@ from .errors import AuthenticationRequired, CannotConnect
from .hub import AxisHub, get_axis_api
AXIS_OUI = {"00:40:8c", "ac:cc:8e", "b8:a4:4f"}
DEFAULT_PORT = 80
DEFAULT_PORT = 443
DEFAULT_PROTOCOL = "https"
PROTOCOL_CHOICES = ["https", "http"]
class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
@ -74,11 +77,19 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
try:
api = await get_axis_api(self.hass, MappingProxyType(user_input))
except AuthenticationRequired:
errors["base"] = "invalid_auth"
except CannotConnect:
errors["base"] = "cannot_connect"
else:
serial = api.vapix.serial_number
await self.async_set_unique_id(format_mac(serial))
self._abort_if_unique_id_configured(
updates={
CONF_PROTOCOL: user_input[CONF_PROTOCOL],
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
CONF_USERNAME: user_input[CONF_USERNAME],
@ -87,6 +98,7 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
)
self.config = {
CONF_PROTOCOL: user_input[CONF_PROTOCOL],
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
CONF_USERNAME: user_input[CONF_USERNAME],
@ -96,13 +108,8 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
return await self._create_entry(serial)
except AuthenticationRequired:
errors["base"] = "invalid_auth"
except CannotConnect:
errors["base"] = "cannot_connect"
data = self.discovery_schema or {
vol.Required(CONF_PROTOCOL): vol.In(PROTOCOL_CHOICES),
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
@ -149,6 +156,9 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
}
self.discovery_schema = {
vol.Required(
CONF_PROTOCOL, default=entry_data.get(CONF_PROTOCOL, DEFAULT_PROTOCOL)
): str,
vol.Required(CONF_HOST, default=entry_data[CONF_HOST]): str,
vol.Required(CONF_USERNAME, default=entry_data[CONF_USERNAME]): str,
vol.Required(CONF_PASSWORD): str,
@ -166,7 +176,7 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
CONF_HOST: discovery_info.ip,
CONF_MAC: format_mac(discovery_info.macaddress),
CONF_NAME: discovery_info.hostname,
CONF_PORT: DEFAULT_PORT,
CONF_PORT: 80,
}
)
@ -210,10 +220,7 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
await self.async_set_unique_id(discovery_info[CONF_MAC])
self._abort_if_unique_id_configured(
updates={
CONF_HOST: discovery_info[CONF_HOST],
CONF_PORT: discovery_info[CONF_PORT],
}
updates={CONF_HOST: discovery_info[CONF_HOST]}
)
self.context.update(
@ -227,10 +234,11 @@ class AxisFlowHandler(ConfigFlow, domain=AXIS_DOMAIN):
)
self.discovery_schema = {
vol.Required(CONF_PROTOCOL): vol.In(PROTOCOL_CHOICES),
vol.Required(CONF_HOST, default=discovery_info[CONF_HOST]): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_PORT, default=discovery_info[CONF_PORT]): int,
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
}
return await self.async_step_user()

View file

@ -7,7 +7,13 @@ from typing import Any
import axis
from axis.configuration import Configuration
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_PORT,
CONF_PROTOCOL,
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.httpx_client import get_async_client
@ -29,6 +35,7 @@ async def get_axis_api(
port=config[CONF_PORT],
username=config[CONF_USERNAME],
password=config[CONF_PASSWORD],
web_proto=config.get(CONF_PROTOCOL, "http"),
)
)

View file

@ -28,6 +28,7 @@ from homeassistant.const import (
CONF_NAME,
CONF_PASSWORD,
CONF_PORT,
CONF_PROTOCOL,
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
@ -65,6 +66,7 @@ async def test_flow_manual_configuration(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -75,6 +77,7 @@ async def test_flow_manual_configuration(
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == f"M1065-LW - {MAC}"
assert result["data"] == {
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -101,6 +104,7 @@ async def test_manual_configuration_update_configuration(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "2.3.4.5",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -130,6 +134,7 @@ async def test_flow_fails_faulty_credentials(hass: HomeAssistant) -> None:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -156,6 +161,7 @@ async def test_flow_fails_cannot_connect(hass: HomeAssistant) -> None:
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -191,6 +197,7 @@ async def test_flow_create_entry_multiple_existing_entries_of_same_model(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -201,6 +208,7 @@ async def test_flow_create_entry_multiple_existing_entries_of_same_model(
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == f"M1065-LW - {MAC}"
assert result["data"] == {
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -233,17 +241,20 @@ async def test_reauth_flow_update_configuration(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "https",
CONF_HOST: "2.3.4.5",
CONF_USERNAME: "user2",
CONF_PASSWORD: "pass2",
CONF_PORT: 80,
CONF_PORT: 443,
},
)
await hass.async_block_till_done()
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "already_configured"
assert mock_config_entry.data[CONF_PROTOCOL] == "https"
assert mock_config_entry.data[CONF_HOST] == "2.3.4.5"
assert mock_config_entry.data[CONF_PORT] == 443
assert mock_config_entry.data[CONF_USERNAME] == "user2"
assert mock_config_entry.data[CONF_PASSWORD] == "pass2"
@ -334,6 +345,7 @@ async def test_discovery_flow(
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -344,6 +356,7 @@ async def test_discovery_flow(
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == f"M1065-LW - {MAC}"
assert result["data"] == {
CONF_PROTOCOL: "http",
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
@ -430,7 +443,7 @@ async def test_discovered_device_already_configured(
"presentationURL": "http://2.3.4.5:8080/",
},
),
8080,
80,
),
(
SOURCE_ZEROCONF,
@ -443,7 +456,7 @@ async def test_discovered_device_already_configured(
properties={"macaddress": MAC},
type="mock_type",
),
8080,
80,
),
],
)