Remove deprecated homekit_controller credential storage locations (#34333)
* Remove deprecated homekit_controller credential storage locations * async_import_legacy_pairing can also be removed
This commit is contained in:
parent
b4282fca84
commit
1b4851f2e0
3 changed files with 0 additions and 237 deletions
|
@ -1,6 +1,5 @@
|
||||||
"""Support for Homekit device discovery."""
|
"""Support for Homekit device discovery."""
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
import aiohomekit
|
import aiohomekit
|
||||||
|
@ -216,16 +215,6 @@ async def async_setup(hass, config):
|
||||||
hass.data[CONTROLLER] = aiohomekit.Controller()
|
hass.data[CONTROLLER] = aiohomekit.Controller()
|
||||||
hass.data[KNOWN_DEVICES] = {}
|
hass.data[KNOWN_DEVICES] = {}
|
||||||
|
|
||||||
dothomekit_dir = hass.config.path(".homekit")
|
|
||||||
if os.path.exists(dothomekit_dir):
|
|
||||||
_LOGGER.warning(
|
|
||||||
(
|
|
||||||
"Legacy homekit_controller state found in %s. Support for reading "
|
|
||||||
"the folder is deprecated and will be removed in 0.109.0."
|
|
||||||
),
|
|
||||||
dothomekit_dir,
|
|
||||||
)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
"""Config flow to configure homekit_controller."""
|
"""Config flow to configure homekit_controller."""
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import aiohomekit
|
import aiohomekit
|
||||||
from aiohomekit.controller.ip import IpPairing
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
|
@ -23,32 +20,6 @@ PIN_FORMAT = re.compile(r"^(\d{3})-{0,1}(\d{2})-{0,1}(\d{3})$")
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def load_old_pairings(hass):
|
|
||||||
"""Load any old pairings from on-disk json fragments."""
|
|
||||||
old_pairings = {}
|
|
||||||
|
|
||||||
data_dir = os.path.join(hass.config.path(), HOMEKIT_DIR)
|
|
||||||
pairing_file = os.path.join(data_dir, PAIRING_FILE)
|
|
||||||
|
|
||||||
# Find any pairings created with in HA 0.85 / 0.86
|
|
||||||
if os.path.exists(pairing_file):
|
|
||||||
with open(pairing_file) as pairing_file:
|
|
||||||
old_pairings.update(json.load(pairing_file))
|
|
||||||
|
|
||||||
# Find any pairings created in HA <= 0.84
|
|
||||||
if os.path.exists(data_dir):
|
|
||||||
for device in os.listdir(data_dir):
|
|
||||||
if not device.startswith("hk-"):
|
|
||||||
continue
|
|
||||||
alias = device[3:]
|
|
||||||
if alias in old_pairings:
|
|
||||||
continue
|
|
||||||
with open(os.path.join(data_dir, device)) as pairing_data_fp:
|
|
||||||
old_pairings[alias] = json.load(pairing_data_fp)
|
|
||||||
|
|
||||||
return old_pairings
|
|
||||||
|
|
||||||
|
|
||||||
def normalize_hkid(hkid):
|
def normalize_hkid(hkid):
|
||||||
"""Normalize a hkid so that it is safe to compare with other normalized hkids."""
|
"""Normalize a hkid so that it is safe to compare with other normalized hkids."""
|
||||||
return hkid.lower()
|
return hkid.lower()
|
||||||
|
@ -218,15 +189,6 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow):
|
||||||
self.context["title_placeholders"] = {"name": name}
|
self.context["title_placeholders"] = {"name": name}
|
||||||
|
|
||||||
if paired:
|
if paired:
|
||||||
old_pairings = await self.hass.async_add_executor_job(
|
|
||||||
load_old_pairings, self.hass
|
|
||||||
)
|
|
||||||
|
|
||||||
if hkid in old_pairings:
|
|
||||||
return await self.async_import_legacy_pairing(
|
|
||||||
properties, old_pairings[hkid]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Device is paired but not to us - ignore it
|
# Device is paired but not to us - ignore it
|
||||||
_LOGGER.debug("HomeKit device %s ignored as already paired", hkid)
|
_LOGGER.debug("HomeKit device %s ignored as already paired", hkid)
|
||||||
return self.async_abort(reason="already_paired")
|
return self.async_abort(reason="already_paired")
|
||||||
|
@ -245,23 +207,6 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow):
|
||||||
# pairing code)
|
# pairing code)
|
||||||
return self._async_step_pair_show_form()
|
return self._async_step_pair_show_form()
|
||||||
|
|
||||||
async def async_import_legacy_pairing(self, discovery_props, pairing_data):
|
|
||||||
"""Migrate a legacy pairing to config entries."""
|
|
||||||
|
|
||||||
hkid = discovery_props["id"]
|
|
||||||
|
|
||||||
_LOGGER.info(
|
|
||||||
(
|
|
||||||
"Legacy configuration %s for homekit"
|
|
||||||
"accessory migrated to configuration entries"
|
|
||||||
),
|
|
||||||
hkid,
|
|
||||||
)
|
|
||||||
|
|
||||||
pairing = IpPairing(pairing_data)
|
|
||||||
|
|
||||||
return await self._entry_from_accessory(pairing)
|
|
||||||
|
|
||||||
async def async_step_pair(self, pair_info=None):
|
async def async_step_pair(self, pair_info=None):
|
||||||
"""Pair with a new HomeKit accessory."""
|
"""Pair with a new HomeKit accessory."""
|
||||||
# If async_step_pair is called with no pairing code then we do the M1
|
# If async_step_pair is called with no pairing code then we do the M1
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
"""Tests for homekit_controller config flow."""
|
"""Tests for homekit_controller config flow."""
|
||||||
import json
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
import aiohomekit
|
import aiohomekit
|
||||||
|
@ -13,7 +12,6 @@ import pytest
|
||||||
from homeassistant.components.homekit_controller import config_flow
|
from homeassistant.components.homekit_controller import config_flow
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
from tests.components.homekit_controller.common import setup_platform
|
|
||||||
|
|
||||||
PAIRING_START_FORM_ERRORS = [
|
PAIRING_START_FORM_ERRORS = [
|
||||||
(aiohomekit.BusyError, "busy_error"),
|
(aiohomekit.BusyError, "busy_error"),
|
||||||
|
@ -496,175 +494,6 @@ async def test_user_no_unpaired_devices(hass, controller):
|
||||||
assert result["reason"] == "no_devices"
|
assert result["reason"] == "no_devices"
|
||||||
|
|
||||||
|
|
||||||
async def test_parse_new_homekit_json(hass):
|
|
||||||
"""Test migrating recent .homekit/pairings.json files."""
|
|
||||||
accessory = Accessory.create_with_info(
|
|
||||||
"TestDevice", "example.com", "Test", "0001", "0.1"
|
|
||||||
)
|
|
||||||
service = accessory.add_service(ServicesTypes.LIGHTBULB)
|
|
||||||
on_char = service.add_char(CharacteristicsTypes.ON)
|
|
||||||
on_char.value = 0
|
|
||||||
|
|
||||||
accessories = Accessories()
|
|
||||||
accessories.add_accessory(accessory)
|
|
||||||
|
|
||||||
fake_controller = await setup_platform(hass)
|
|
||||||
pairing = await fake_controller.add_paired_device(accessories, "00:00:00:00:00:00")
|
|
||||||
pairing.pairing_data = {"AccessoryPairingID": "00:00:00:00:00:00"}
|
|
||||||
|
|
||||||
mock_path = mock.Mock()
|
|
||||||
mock_path.exists.side_effect = [True, False]
|
|
||||||
|
|
||||||
read_data = {"00:00:00:00:00:00": pairing.pairing_data}
|
|
||||||
mock_open = mock.mock_open(read_data=json.dumps(read_data))
|
|
||||||
|
|
||||||
discovery_info = {
|
|
||||||
"name": "TestDevice",
|
|
||||||
"host": "127.0.0.1",
|
|
||||||
"port": 8080,
|
|
||||||
"properties": {"md": "TestDevice", "id": "00:00:00:00:00:00", "c#": 1, "sf": 0},
|
|
||||||
}
|
|
||||||
|
|
||||||
flow = _setup_flow_handler(hass)
|
|
||||||
|
|
||||||
pairing_cls_imp = (
|
|
||||||
"homeassistant.components.homekit_controller.config_flow.IpPairing"
|
|
||||||
)
|
|
||||||
|
|
||||||
with mock.patch(pairing_cls_imp) as pairing_cls:
|
|
||||||
pairing_cls.return_value = pairing
|
|
||||||
with mock.patch("builtins.open", mock_open):
|
|
||||||
with mock.patch("os.path", mock_path):
|
|
||||||
result = await flow.async_step_zeroconf(discovery_info)
|
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
|
||||||
assert result["title"] == "TestDevice"
|
|
||||||
assert result["data"]["AccessoryPairingID"] == "00:00:00:00:00:00"
|
|
||||||
assert flow.context == {
|
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
|
||||||
"unique_id": "00:00:00:00:00:00",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_parse_old_homekit_json(hass):
|
|
||||||
"""Test migrating original .homekit/hk-00:00:00:00:00:00 files."""
|
|
||||||
accessory = Accessory.create_with_info(
|
|
||||||
"TestDevice", "example.com", "Test", "0001", "0.1"
|
|
||||||
)
|
|
||||||
service = accessory.add_service(ServicesTypes.LIGHTBULB)
|
|
||||||
on_char = service.add_char(CharacteristicsTypes.ON)
|
|
||||||
on_char.value = 0
|
|
||||||
|
|
||||||
accessories = Accessories()
|
|
||||||
accessories.add_accessory(accessory)
|
|
||||||
|
|
||||||
fake_controller = await setup_platform(hass)
|
|
||||||
pairing = await fake_controller.add_paired_device(accessories, "00:00:00:00:00:00")
|
|
||||||
pairing.pairing_data = {"AccessoryPairingID": "00:00:00:00:00:00"}
|
|
||||||
|
|
||||||
mock_path = mock.Mock()
|
|
||||||
mock_path.exists.side_effect = [False, True]
|
|
||||||
|
|
||||||
mock_listdir = mock.Mock()
|
|
||||||
mock_listdir.return_value = ["hk-00:00:00:00:00:00", "pairings.json"]
|
|
||||||
|
|
||||||
read_data = {"AccessoryPairingID": "00:00:00:00:00:00"}
|
|
||||||
mock_open = mock.mock_open(read_data=json.dumps(read_data))
|
|
||||||
|
|
||||||
discovery_info = {
|
|
||||||
"name": "TestDevice",
|
|
||||||
"host": "127.0.0.1",
|
|
||||||
"port": 8080,
|
|
||||||
"properties": {"md": "TestDevice", "id": "00:00:00:00:00:00", "c#": 1, "sf": 0},
|
|
||||||
}
|
|
||||||
|
|
||||||
flow = _setup_flow_handler(hass)
|
|
||||||
|
|
||||||
pairing_cls_imp = (
|
|
||||||
"homeassistant.components.homekit_controller.config_flow.IpPairing"
|
|
||||||
)
|
|
||||||
|
|
||||||
with mock.patch(pairing_cls_imp) as pairing_cls:
|
|
||||||
pairing_cls.return_value = pairing
|
|
||||||
with mock.patch("builtins.open", mock_open):
|
|
||||||
with mock.patch("os.path", mock_path):
|
|
||||||
with mock.patch("os.listdir", mock_listdir):
|
|
||||||
result = await flow.async_step_zeroconf(discovery_info)
|
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
|
||||||
assert result["title"] == "TestDevice"
|
|
||||||
assert result["data"]["AccessoryPairingID"] == "00:00:00:00:00:00"
|
|
||||||
assert flow.context == {
|
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
|
||||||
"unique_id": "00:00:00:00:00:00",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_parse_overlapping_homekit_json(hass):
|
|
||||||
"""Test migrating .homekit/pairings.json files when hk- exists too."""
|
|
||||||
accessory = Accessory.create_with_info(
|
|
||||||
"TestDevice", "example.com", "Test", "0001", "0.1"
|
|
||||||
)
|
|
||||||
service = accessory.add_service(ServicesTypes.LIGHTBULB)
|
|
||||||
on_char = service.add_char(CharacteristicsTypes.ON)
|
|
||||||
on_char.value = 0
|
|
||||||
|
|
||||||
accessories = Accessories()
|
|
||||||
accessories.add_accessory(accessory)
|
|
||||||
|
|
||||||
fake_controller = await setup_platform(hass)
|
|
||||||
pairing = await fake_controller.add_paired_device(accessories)
|
|
||||||
pairing.pairing_data = {"AccessoryPairingID": "00:00:00:00:00:00"}
|
|
||||||
|
|
||||||
mock_listdir = mock.Mock()
|
|
||||||
mock_listdir.return_value = ["hk-00:00:00:00:00:00", "pairings.json"]
|
|
||||||
|
|
||||||
mock_path = mock.Mock()
|
|
||||||
mock_path.exists.side_effect = [True, True]
|
|
||||||
|
|
||||||
# First file to get loaded is .homekit/pairing.json
|
|
||||||
read_data_1 = {"00:00:00:00:00:00": {"AccessoryPairingID": "00:00:00:00:00:00"}}
|
|
||||||
mock_open_1 = mock.mock_open(read_data=json.dumps(read_data_1))
|
|
||||||
|
|
||||||
# Second file to get loaded is .homekit/hk-00:00:00:00:00:00
|
|
||||||
read_data_2 = {"AccessoryPairingID": "00:00:00:00:00:00"}
|
|
||||||
mock_open_2 = mock.mock_open(read_data=json.dumps(read_data_2))
|
|
||||||
|
|
||||||
side_effects = [mock_open_1.return_value, mock_open_2.return_value]
|
|
||||||
|
|
||||||
discovery_info = {
|
|
||||||
"name": "TestDevice",
|
|
||||||
"host": "127.0.0.1",
|
|
||||||
"port": 8080,
|
|
||||||
"properties": {"md": "TestDevice", "id": "00:00:00:00:00:00", "c#": 1, "sf": 0},
|
|
||||||
}
|
|
||||||
|
|
||||||
flow = _setup_flow_handler(hass)
|
|
||||||
|
|
||||||
pairing_cls_imp = (
|
|
||||||
"homeassistant.components.homekit_controller.config_flow.IpPairing"
|
|
||||||
)
|
|
||||||
with mock.patch(pairing_cls_imp) as pairing_cls:
|
|
||||||
pairing_cls.return_value = pairing
|
|
||||||
with mock.patch("builtins.open", side_effect=side_effects):
|
|
||||||
with mock.patch("os.path", mock_path):
|
|
||||||
with mock.patch("os.listdir", mock_listdir):
|
|
||||||
result = await flow.async_step_zeroconf(discovery_info)
|
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result["type"] == "create_entry"
|
|
||||||
assert result["title"] == "TestDevice"
|
|
||||||
assert result["data"]["AccessoryPairingID"] == "00:00:00:00:00:00"
|
|
||||||
assert flow.context == {
|
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
|
||||||
"unique_id": "00:00:00:00:00:00",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_unignore_works(hass, controller):
|
async def test_unignore_works(hass, controller):
|
||||||
"""Test rediscovery triggered disovers work."""
|
"""Test rediscovery triggered disovers work."""
|
||||||
device = setup_mock_accessory(controller)
|
device = setup_mock_accessory(controller)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue