Fix Cloud UI bug preventing managing Google 2FA (#34241)

* Fix Cloud UI bug preventing managing Google 2FA

* Update comment
pull/33850/head
Paulus Schoutsen 2020-04-15 08:43:43 -07:00 committed by GitHub
parent e47b548192
commit 1ac8442c63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 10 deletions

View File

@ -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(),
} }
) )

View File

@ -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()
) )

View File

@ -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):

View File

@ -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()

View File

@ -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