Cloud: Expose if google is registered in status + check on login (#48260)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
pull/48475/head
Bram Kragten 2021-03-29 19:26:51 +02:00 committed by GitHub
parent 022f56f54d
commit 03b7b1305c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 48 additions and 18 deletions

View File

@ -110,7 +110,7 @@ class CloudClient(Interface):
async def logged_in(self) -> None:
"""When user logs in."""
await self.prefs.async_set_username(self.cloud.username)
is_new_user = await self.prefs.async_set_username(self.cloud.username)
async def enable_alexa(_):
"""Enable Alexa."""
@ -136,6 +136,9 @@ class CloudClient(Interface):
if gconf.should_report_state:
gconf.async_enable_report_state()
if is_new_user:
await gconf.async_sync_entities(gconf.agent_user_id)
tasks = []
if self._prefs.alexa_enabled and self._prefs.alexa_report_state:

View File

@ -131,6 +131,11 @@ class CloudGoogleConfig(AbstractConfig):
"""Return Agent User Id to use for query responses."""
return self._cloud.username
@property
def has_registered_user_agent(self):
"""Return if we have a Agent User Id registered."""
return len(self._store.agent_user_ids) > 0
def get_agent_user_id(self, context):
"""Get agent user ID making request."""
return self.agent_user_id

View File

@ -27,7 +27,6 @@ from homeassistant.const import (
HTTP_OK,
HTTP_UNAUTHORIZED,
)
from homeassistant.core import callback
from .const import (
DOMAIN,
@ -225,6 +224,7 @@ class CloudLoginView(HomeAssistantView):
hass = request.app["hass"]
cloud = hass.data[DOMAIN]
await cloud.login(data["email"], data["password"])
return self.json({"success": True})
@ -310,15 +310,15 @@ class CloudForgotPasswordView(HomeAssistantView):
return self.json_message("ok")
@callback
def websocket_cloud_status(hass, connection, msg):
@websocket_api.async_response
async def websocket_cloud_status(hass, connection, msg):
"""Handle request for account info.
Async friendly.
"""
cloud = hass.data[DOMAIN]
connection.send_message(
websocket_api.result_message(msg["id"], _account_data(cloud))
websocket_api.result_message(msg["id"], await _account_data(cloud))
)
@ -446,7 +446,7 @@ async def websocket_hook_delete(hass, connection, msg):
connection.send_message(websocket_api.result_message(msg["id"]))
def _account_data(cloud):
async def _account_data(cloud):
"""Generate the auth data JSON response."""
if not cloud.is_logged_in:
@ -456,6 +456,8 @@ def _account_data(cloud):
client = cloud.client
remote = cloud.remote
gconf = await client.get_google_config()
# Load remote certificate
if remote.certificate:
certificate = attr.asdict(remote.certificate)
@ -467,6 +469,7 @@ def _account_data(cloud):
"email": claims["email"],
"cloud": cloud.iot.state,
"prefs": client.prefs.as_dict(),
"google_registered": gconf.has_registered_user_agent,
"google_entities": client.google_user_config["filter"].config,
"alexa_entities": client.alexa_user_config["filter"].config,
"remote_domain": remote.instance_domain,
@ -485,7 +488,7 @@ async def websocket_remote_connect(hass, connection, msg):
cloud = hass.data[DOMAIN]
await cloud.client.prefs.async_update(remote_enabled=True)
await cloud.remote.connect()
connection.send_result(msg["id"], _account_data(cloud))
connection.send_result(msg["id"], await _account_data(cloud))
@websocket_api.require_admin
@ -498,7 +501,7 @@ async def websocket_remote_disconnect(hass, connection, msg):
cloud = hass.data[DOMAIN]
await cloud.client.prefs.async_update(remote_enabled=False)
await cloud.remote.disconnect()
connection.send_result(msg["id"], _account_data(cloud))
connection.send_result(msg["id"], await _account_data(cloud))
@websocket_api.require_admin

View File

@ -173,7 +173,7 @@ class CloudPreferences:
updated_entities = {**entities, entity_id: updated_entity}
await self.async_update(alexa_entity_configs=updated_entities)
async def async_set_username(self, username):
async def async_set_username(self, username) -> bool:
"""Set the username that is logged in."""
# Logging out.
if username is None:
@ -182,18 +182,20 @@ class CloudPreferences:
if user is not None:
await self._hass.auth.async_remove_user(user)
await self._save_prefs({**self._prefs, PREF_CLOUD_USER: None})
return
return False
cur_username = self._prefs.get(PREF_USERNAME)
if cur_username == username:
return
return False
if cur_username is None:
await self._save_prefs({**self._prefs, PREF_USERNAME: username})
else:
await self._save_prefs(self._empty_config(username))
return True
def as_dict(self):
"""Return dictionary version."""
return {

View File

@ -269,13 +269,17 @@ class AbstractConfig(ABC):
if webhook_id is None:
return
webhook.async_register(
self.hass,
DOMAIN,
"Local Support",
webhook_id,
self._handle_local_webhook,
)
try:
webhook.async_register(
self.hass,
DOMAIN,
"Local Support",
webhook_id,
self._handle_local_webhook,
)
except ValueError:
_LOGGER.info("Webhook handler is already defined!")
return
self._local_sdk_active = True

View File

@ -379,6 +379,7 @@ async def test_websocket_status(
"exclude_entity_globs": [],
"exclude_entities": [],
},
"google_registered": False,
"remote_domain": None,
"remote_connected": False,
"remote_certificate": None,

View File

@ -39,6 +39,18 @@ async def test_set_username_migration(hass):
assert not prefs.google_enabled
async def test_set_new_username(hass, hass_storage):
"""Test if setting new username returns true."""
hass_storage[STORAGE_KEY] = {"version": 1, "data": {"username": "old-user"}}
prefs = CloudPreferences(hass)
await prefs.async_initialize()
assert not await prefs.async_set_username("old-user")
assert await prefs.async_set_username("new-user")
async def test_load_invalid_cloud_user(hass, hass_storage):
"""Test loading cloud user with invalid storage."""
hass_storage[STORAGE_KEY] = {"version": 1, "data": {"cloud_user": "non-existing"}}