Remove path whitelisting for hassio (#7399)
* Remove path whitelisting for hassio * Update frontend * Lintpull/7312/merge
parent
8ea6c7319a
commit
f17c1090e1
|
@ -3,20 +3,20 @@
|
|||
FINGERPRINTS = {
|
||||
"compatibility.js": "83d9c77748dafa9db49ae77d7f3d8fb0",
|
||||
"core.js": "5d08475f03adb5969bd31855d5ca0cfd",
|
||||
"frontend.html": "1533f44c55927e814294de757cd7eada",
|
||||
"frontend.html": "094c2015c8291c767b8933428d92076f",
|
||||
"mdi.html": "1cc8593d3684f7f6f3b3854403216f77",
|
||||
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
|
||||
"panels/ha-panel-config.html": "39f00f769faa63ee61f1fe6fc85d67f7",
|
||||
"panels/ha-panel-config.html": "59d9eb28758b497a4d9b2428f978b9b1",
|
||||
"panels/ha-panel-dev-event.html": "2db9c218065ef0f61d8d08db8093cad2",
|
||||
"panels/ha-panel-dev-info.html": "61610e015a411cfc84edd2c4d489e71d",
|
||||
"panels/ha-panel-dev-service.html": "415552027cb083badeff5f16080410ed",
|
||||
"panels/ha-panel-dev-state.html": "d70314913b8923d750932367b1099750",
|
||||
"panels/ha-panel-dev-template.html": "567fbf86735e1b891e40c2f4060fec9b",
|
||||
"panels/ha-panel-hassio.html": "1d954cfe5f47c4be3cf4f6f5db9a83b2",
|
||||
"panels/ha-panel-hassio.html": "0aa1523357326cb40e2242dce9b2c0d6",
|
||||
"panels/ha-panel-history.html": "89062c48c76206cad1cec14ddbb1cbb1",
|
||||
"panels/ha-panel-iframe.html": "d920f0aa3c903680f2f8795e2255daab",
|
||||
"panels/ha-panel-logbook.html": "6dd6a16f52117318b202e60f98400163",
|
||||
"panels/ha-panel-map.html": "31c592c239636f91e07c7ac232a5ebc4",
|
||||
"panels/ha-panel-zwave.html": "a81f82b48439da80286798558f414a2e",
|
||||
"panels/ha-panel-zwave.html": "84fb45638d2a69bac343246a687f647c",
|
||||
"websocket_test.html": "575de64b431fe11c3785bf96d7813450"
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -1 +1 @@
|
|||
Subproject commit 863ccb548616236faafa3b3393a1f51429bb8afd
|
||||
Subproject commit 110f152e2371319ff4cf0b6fcc18b10e943cf08d
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -11,8 +11,7 @@ import re
|
|||
|
||||
import aiohttp
|
||||
from aiohttp import web
|
||||
from aiohttp.web_exceptions import (
|
||||
HTTPBadGateway, HTTPNotFound, HTTPMethodNotAllowed)
|
||||
from aiohttp.web_exceptions import HTTPBadGateway
|
||||
from aiohttp.hdrs import CONTENT_TYPE
|
||||
import async_timeout
|
||||
|
||||
|
@ -28,23 +27,6 @@ DEPENDENCIES = ['http']
|
|||
|
||||
TIMEOUT = 10
|
||||
|
||||
HASSIO_REST_COMMANDS = {
|
||||
'host/shutdown': ['POST'],
|
||||
'host/reboot': ['POST'],
|
||||
'host/update': ['POST'],
|
||||
'host/info': ['GET'],
|
||||
'supervisor/info': ['GET'],
|
||||
'supervisor/update': ['POST'],
|
||||
'supervisor/options': ['POST'],
|
||||
'supervisor/reload': ['POST'],
|
||||
'supervisor/logs': ['GET'],
|
||||
'homeassistant/info': ['GET'],
|
||||
'homeassistant/update': ['POST'],
|
||||
'homeassistant/logs': ['GET'],
|
||||
'network/info': ['GET'],
|
||||
'network/options': ['POST'],
|
||||
}
|
||||
|
||||
ADDON_REST_COMMANDS = {
|
||||
'install': ['POST'],
|
||||
'uninstall': ['POST'],
|
||||
|
@ -166,21 +148,6 @@ class HassIOView(HomeAssistantView):
|
|||
@asyncio.coroutine
|
||||
def _handle(self, request, path):
|
||||
"""Route data to hassio."""
|
||||
if path.startswith('addons/'):
|
||||
parts = path.split('/')
|
||||
|
||||
if len(parts) != 3:
|
||||
raise HTTPNotFound()
|
||||
|
||||
allowed_methods = ADDON_REST_COMMANDS.get(parts[-1])
|
||||
else:
|
||||
allowed_methods = HASSIO_REST_COMMANDS.get(path)
|
||||
|
||||
if allowed_methods is None:
|
||||
raise HTTPNotFound()
|
||||
if request.method not in allowed_methods:
|
||||
raise HTTPMethodNotAllowed(request.method, allowed_methods)
|
||||
|
||||
client = yield from self.hassio.command_proxy(path, request)
|
||||
|
||||
data = yield from client.read()
|
||||
|
|
|
@ -48,31 +48,12 @@ def test_fail_setup_cannot_connect(hass):
|
|||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_invalid_path(hassio_client):
|
||||
"""Test requesting invalid path."""
|
||||
with patch.dict(ho.HASSIO_REST_COMMANDS, {}, clear=True):
|
||||
resp = yield from hassio_client.post('/api/hassio/beer')
|
||||
|
||||
assert resp.status == 404
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_invalid_method(hassio_client):
|
||||
"""Test requesting path with invalid method."""
|
||||
with patch.dict(ho.HASSIO_REST_COMMANDS, {'beer': ['POST']}):
|
||||
resp = yield from hassio_client.get('/api/hassio/beer')
|
||||
|
||||
assert resp.status == 405
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_forward_normal_path(hassio_client):
|
||||
def test_forward_request(hassio_client):
|
||||
"""Test fetching normal path."""
|
||||
response = MagicMock()
|
||||
response.read.return_value = mock_coro('data')
|
||||
|
||||
with patch.dict(ho.HASSIO_REST_COMMANDS, {'beer': ['POST']}), \
|
||||
patch('homeassistant.components.hassio.HassIO.command_proxy',
|
||||
with patch('homeassistant.components.hassio.HassIO.command_proxy',
|
||||
Mock(return_value=mock_coro(response))), \
|
||||
patch('homeassistant.components.hassio._create_response') as mresp:
|
||||
mresp.return_value = 'response'
|
||||
|
@ -89,13 +70,12 @@ def test_forward_normal_path(hassio_client):
|
|||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_forward_normal_log_path(hassio_client):
|
||||
def test_forward_log_request(hassio_client):
|
||||
"""Test fetching normal log path."""
|
||||
response = MagicMock()
|
||||
response.read.return_value = mock_coro('data')
|
||||
|
||||
with patch.dict(ho.HASSIO_REST_COMMANDS, {'beer/logs': ['GET']}), \
|
||||
patch('homeassistant.components.hassio.HassIO.command_proxy',
|
||||
with patch('homeassistant.components.hassio.HassIO.command_proxy',
|
||||
Mock(return_value=mock_coro(response))), \
|
||||
patch('homeassistant.components.hassio.'
|
||||
'_create_response_log') as mresp:
|
||||
|
@ -112,69 +92,6 @@ def test_forward_normal_log_path(hassio_client):
|
|||
assert mresp.mock_calls[0][1] == (response, 'data')
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_forward_addon_path(hassio_client):
|
||||
"""Test fetching addon path."""
|
||||
response = MagicMock()
|
||||
response.read.return_value = mock_coro('data')
|
||||
|
||||
with patch.dict(ho.ADDON_REST_COMMANDS, {'install': ['POST']}), \
|
||||
patch('homeassistant.components.hassio.'
|
||||
'HassIO.command_proxy') as proxy_command, \
|
||||
patch('homeassistant.components.hassio._create_response') as mresp:
|
||||
proxy_command.return_value = mock_coro(response)
|
||||
mresp.return_value = 'response'
|
||||
resp = yield from hassio_client.post('/api/hassio/addons/beer/install')
|
||||
|
||||
# Check we got right response
|
||||
assert resp.status == 200
|
||||
body = yield from resp.text()
|
||||
assert body == 'response'
|
||||
|
||||
assert proxy_command.mock_calls[0][1][0] == 'addons/beer/install'
|
||||
|
||||
# Check we forwarded command
|
||||
assert len(mresp.mock_calls) == 1
|
||||
assert mresp.mock_calls[0][1] == (response, 'data')
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_forward_addon_log_path(hassio_client):
|
||||
"""Test fetching addon log path."""
|
||||
response = MagicMock()
|
||||
response.read.return_value = mock_coro('data')
|
||||
|
||||
with patch.dict(ho.ADDON_REST_COMMANDS, {'logs': ['GET']}), \
|
||||
patch('homeassistant.components.hassio.'
|
||||
'HassIO.command_proxy') as proxy_command, \
|
||||
patch('homeassistant.components.hassio.'
|
||||
'_create_response_log') as mresp:
|
||||
proxy_command.return_value = mock_coro(response)
|
||||
mresp.return_value = 'response'
|
||||
resp = yield from hassio_client.get('/api/hassio/addons/beer/logs')
|
||||
|
||||
# Check we got right response
|
||||
assert resp.status == 200
|
||||
body = yield from resp.text()
|
||||
assert body == 'response'
|
||||
|
||||
assert proxy_command.mock_calls[0][1][0] == 'addons/beer/logs'
|
||||
|
||||
# Check we forwarded command
|
||||
assert len(mresp.mock_calls) == 1
|
||||
assert mresp.mock_calls[0][1] == (response, 'data')
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_bad_request_when_wrong_addon_url(hassio_client):
|
||||
"""Test we cannot mess with addon url."""
|
||||
resp = yield from hassio_client.get('/api/hassio/addons/../../info')
|
||||
assert resp.status == 404
|
||||
|
||||
resp = yield from hassio_client.get('/api/hassio/addons/info')
|
||||
assert resp.status == 404
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def test_bad_gateway_when_cannot_find_supervisor(hassio_client):
|
||||
"""Test we get a bad gateway error if we can't find supervisor."""
|
||||
|
|
Loading…
Reference in New Issue