Skip to content

Commit

Permalink
Only allow admins to enable remote connection (#22609)
Browse files Browse the repository at this point in the history
* Only allow admins to enable remote connection

* Protect WS API

* Lint
  • Loading branch information
balloob authored and pvizeli committed Apr 1, 2019
1 parent 282fd22 commit c968049
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
9 changes: 5 additions & 4 deletions homeassistant/components/cloud/__init__.py
Expand Up @@ -187,10 +187,11 @@ async def _service_handler(service):
await cloud.remote.disconnect()
await prefs.async_update(remote_enabled=False)

hass.services.async_register(
DOMAIN, SERVICE_REMOTE_CONNECT, _service_handler)
hass.services.async_register(
DOMAIN, SERVICE_REMOTE_DISCONNECT, _service_handler)
empty_schema = vol.Schema({})
hass.helpers.service.async_register_admin_service(
DOMAIN, SERVICE_REMOTE_CONNECT, _service_handler, empty_schema)
hass.helpers.service.async_register_admin_service(
DOMAIN, SERVICE_REMOTE_DISCONNECT, _service_handler, empty_schema)

await http_api.async_setup(hass)
hass.async_create_task(hass.helpers.discovery.async_load_platform(
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/cloud/http_api.py
Expand Up @@ -422,6 +422,7 @@ def _account_data(cloud):
}


@websocket_api.require_admin
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
Expand All @@ -436,6 +437,7 @@ async def websocket_remote_connect(hass, connection, msg):
connection.send_result(msg['id'], _account_data(cloud))


@websocket_api.require_admin
@_require_cloud_login
@websocket_api.async_response
@_ws_handle_cloud_errors
Expand Down
26 changes: 25 additions & 1 deletion tests/components/cloud/test_init.py
@@ -1,6 +1,10 @@
"""Test the cloud component."""
from unittest.mock import patch

import pytest

from homeassistant.core import Context
from homeassistant.exceptions import Unauthorized
from homeassistant.auth.const import GROUP_ID_ADMIN
from homeassistant.components import cloud
from homeassistant.components.cloud.const import DOMAIN
Expand Down Expand Up @@ -34,7 +38,7 @@ async def test_constructor_loads_info_from_config(hass):
assert cl.relayer == 'test-relayer'


async def test_remote_services(hass, mock_cloud_fixture):
async def test_remote_services(hass, mock_cloud_fixture, hass_read_only_user):
"""Setup cloud component and test services."""
cloud = hass.data[DOMAIN]

Expand All @@ -58,6 +62,26 @@ async def test_remote_services(hass, mock_cloud_fixture):
assert mock_disconnect.called
assert not cloud.client.remote_autostart

# Test admin access required
non_admin_context = Context(user_id=hass_read_only_user.id)

with patch(
"hass_nabucasa.remote.RemoteUI.connect", return_value=mock_coro()
) as mock_connect, pytest.raises(Unauthorized):
await hass.services.async_call(DOMAIN, "remote_connect", blocking=True,
context=non_admin_context)

assert mock_connect.called is False

with patch(
"hass_nabucasa.remote.RemoteUI.disconnect", return_value=mock_coro()
) as mock_disconnect, pytest.raises(Unauthorized):
await hass.services.async_call(
DOMAIN, "remote_disconnect", blocking=True,
context=non_admin_context)

assert mock_disconnect.called is False


async def test_startup_shutdown_events(hass, mock_cloud_fixture):
"""Test if the cloud will start on startup event."""
Expand Down

0 comments on commit c968049

Please sign in to comment.