Fix Cloud UI bug preventing managing Google 2FA (#34241)
* Fix Cloud UI bug preventing managing Google 2FA * Update commentpull/33850/head
parent
e47b548192
commit
1ac8442c63
|
@ -492,7 +492,7 @@ async def google_assistant_list(hass, connection, msg):
|
||||||
{
|
{
|
||||||
"entity_id": entity.entity_id,
|
"entity_id": entity.entity_id,
|
||||||
"traits": [trait.name for trait in entity.traits()],
|
"traits": [trait.name for trait in entity.traits()],
|
||||||
"might_2fa": entity.might_2fa(),
|
"might_2fa": entity.might_2fa_traits(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -372,14 +372,19 @@ class GoogleEntity:
|
||||||
@callback
|
@callback
|
||||||
def might_2fa(self) -> bool:
|
def might_2fa(self) -> bool:
|
||||||
"""Return if the entity might encounter 2FA."""
|
"""Return if the entity might encounter 2FA."""
|
||||||
|
if not self.config.should_2fa(self.state):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return self.might_2fa_traits()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def might_2fa_traits(self) -> bool:
|
||||||
|
"""Return if the entity might encounter 2FA based on just traits."""
|
||||||
state = self.state
|
state = self.state
|
||||||
domain = state.domain
|
domain = state.domain
|
||||||
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||||
device_class = state.attributes.get(ATTR_DEVICE_CLASS)
|
device_class = state.attributes.get(ATTR_DEVICE_CLASS)
|
||||||
|
|
||||||
if not self.config.should_2fa(state):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return any(
|
return any(
|
||||||
trait.might_2fa(domain, features, device_class) for trait in self.traits()
|
trait.might_2fa(domain, features, device_class) for trait in self.traits()
|
||||||
)
|
)
|
||||||
|
|
|
@ -688,20 +688,30 @@ async def test_list_google_entities(hass, hass_ws_client, setup_api, mock_cloud_
|
||||||
entity = GoogleEntity(
|
entity = GoogleEntity(
|
||||||
hass, MockConfig(should_expose=lambda *_: False), State("light.kitchen", "on")
|
hass, MockConfig(should_expose=lambda *_: False), State("light.kitchen", "on")
|
||||||
)
|
)
|
||||||
|
entity2 = GoogleEntity(
|
||||||
|
hass,
|
||||||
|
MockConfig(should_expose=lambda *_: True, should_2fa=lambda *_: False),
|
||||||
|
State("cover.garage", "open", {"device_class": "garage"}),
|
||||||
|
)
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.google_assistant.helpers.async_get_entities",
|
"homeassistant.components.google_assistant.helpers.async_get_entities",
|
||||||
return_value=[entity],
|
return_value=[entity, entity2],
|
||||||
):
|
):
|
||||||
await client.send_json({"id": 5, "type": "cloud/google_assistant/entities"})
|
await client.send_json({"id": 5, "type": "cloud/google_assistant/entities"})
|
||||||
response = await client.receive_json()
|
response = await client.receive_json()
|
||||||
|
|
||||||
assert response["success"]
|
assert response["success"]
|
||||||
assert len(response["result"]) == 1
|
assert len(response["result"]) == 2
|
||||||
assert response["result"][0] == {
|
assert response["result"][0] == {
|
||||||
"entity_id": "light.kitchen",
|
"entity_id": "light.kitchen",
|
||||||
"might_2fa": False,
|
"might_2fa": False,
|
||||||
"traits": ["action.devices.traits.OnOff"],
|
"traits": ["action.devices.traits.OnOff"],
|
||||||
}
|
}
|
||||||
|
assert response["result"][1] == {
|
||||||
|
"entity_id": "cover.garage",
|
||||||
|
"might_2fa": True,
|
||||||
|
"traits": ["action.devices.traits.OpenClose"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_update_google_entity(hass, hass_ws_client, setup_api, mock_cloud_login):
|
async def test_update_google_entity(hass, hass_ws_client, setup_api, mock_cloud_login):
|
||||||
|
|
|
@ -33,6 +33,7 @@ class MockConfig(helpers.AbstractConfig):
|
||||||
"""Initialize config."""
|
"""Initialize config."""
|
||||||
super().__init__(hass)
|
super().__init__(hass)
|
||||||
self._should_expose = should_expose
|
self._should_expose = should_expose
|
||||||
|
self._should_2fa = should_2fa
|
||||||
self._secure_devices_pin = secure_devices_pin
|
self._secure_devices_pin = secure_devices_pin
|
||||||
self._entity_config = entity_config or {}
|
self._entity_config = entity_config or {}
|
||||||
self._local_sdk_webhook_id = local_sdk_webhook_id
|
self._local_sdk_webhook_id = local_sdk_webhook_id
|
||||||
|
@ -73,6 +74,10 @@ class MockConfig(helpers.AbstractConfig):
|
||||||
"""Expose it all."""
|
"""Expose it all."""
|
||||||
return self._should_expose is None or self._should_expose(state)
|
return self._should_expose is None or self._should_expose(state)
|
||||||
|
|
||||||
|
def should_2fa(self, state):
|
||||||
|
"""Expose it all."""
|
||||||
|
return self._should_2fa is None or self._should_2fa(state)
|
||||||
|
|
||||||
|
|
||||||
BASIC_CONFIG = MockConfig()
|
BASIC_CONFIG = MockConfig()
|
||||||
|
|
||||||
|
|
|
@ -845,10 +845,8 @@ async def test_lock_unlock_unlock(hass):
|
||||||
assert err.value.code == const.ERR_CHALLENGE_NOT_SETUP
|
assert err.value.code == const.ERR_CHALLENGE_NOT_SETUP
|
||||||
|
|
||||||
# Test with 2FA override
|
# Test with 2FA override
|
||||||
with patch(
|
with patch.object(
|
||||||
"homeassistant.components.google_assistant.helpers"
|
BASIC_CONFIG, "should_2fa", return_value=False,
|
||||||
".AbstractConfig.should_2fa",
|
|
||||||
return_value=False,
|
|
||||||
):
|
):
|
||||||
await trt.execute(trait.COMMAND_LOCKUNLOCK, BASIC_DATA, {"lock": False}, {})
|
await trt.execute(trait.COMMAND_LOCKUNLOCK, BASIC_DATA, {"lock": False}, {})
|
||||||
assert len(calls) == 2
|
assert len(calls) == 2
|
||||||
|
|
Loading…
Reference in New Issue