Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion homeassistant/components/cloud/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ async def get_google_config(self) -> google_config.CloudGoogleConfig:

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."""
Expand All @@ -136,6 +136,9 @@ async def enable_google(_):
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:
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/cloud/google_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ def agent_user_id(self):
"""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
Expand Down
17 changes: 10 additions & 7 deletions homeassistant/components/cloud/http_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
HTTP_OK,
HTTP_UNAUTHORIZED,
)
from homeassistant.core import callback

from .const import (
DOMAIN,
Expand Down Expand Up @@ -225,6 +224,7 @@ async def post(self, request, data):
hass = request.app["hass"]
cloud = hass.data[DOMAIN]
await cloud.login(data["email"], data["password"])

return self.json({"success": True})


Expand Down Expand Up @@ -310,15 +310,15 @@ async def post(self, request, data):
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))
)


Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand Down
8 changes: 5 additions & 3 deletions homeassistant/components/cloud/prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ async def async_update_alexa_entity_config(
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:
Expand All @@ -182,18 +182,20 @@ async def async_set_username(self, username):
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 {
Expand Down
18 changes: 11 additions & 7 deletions homeassistant/components/google_assistant/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,13 +269,17 @@ def async_enable_local_sdk(self):
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

Expand Down
1 change: 1 addition & 0 deletions tests/components/cloud/test_http_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
12 changes: 12 additions & 0 deletions tests/components/cloud/test_prefs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"}}
Expand Down