Skip to content

Commit

Permalink
Hass.io: logo support / timeout handling (#8668)
Browse files Browse the repository at this point in the history
* Disable auth on logo / no timeout for addons update/install

* fix tests
  • Loading branch information
pvizeli authored and balloob committed Jul 27, 2017
1 parent 9e6817b commit 51108b8
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
35 changes: 29 additions & 6 deletions homeassistant/components/hassio.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,15 @@
DOMAIN = 'hassio'
DEPENDENCIES = ['http']

TIMEOUT = 10
NO_TIMEOUT = set(['homeassistant/update', 'host/update', 'supervisor/update'])
NO_TIMEOUT = {
re.compile(r'^homeassistant/update$'), re.compile(r'^host/update$'),
re.compile(r'^supervisor/update$'), re.compile(r'^addons/[^/]*/update$'),
re.compile(r'^addons/[^/]*/install$')
}

NO_AUTH = {
re.compile(r'^panel$'), re.compile(r'^addons/[^/]*/logo$')
}


@asyncio.coroutine
Expand Down Expand Up @@ -71,7 +78,7 @@ def is_connected(self):
This method is a coroutine.
"""
try:
with async_timeout.timeout(TIMEOUT, loop=self.loop):
with async_timeout.timeout(10, loop=self.loop):
request = yield from self.websession.get(
"http://{}{}".format(self._ip, "/supervisor/ping")
)
Expand All @@ -97,12 +104,12 @@ def command_proxy(self, path, request):
This method is a coroutine.
"""
read_timeout = 0 if path in NO_TIMEOUT else 300
read_timeout = _get_timeout(path)

try:
data = None
headers = None
with async_timeout.timeout(TIMEOUT, loop=self.loop):
with async_timeout.timeout(10, loop=self.loop):
data = yield from request.read()
if data:
headers = {CONTENT_TYPE: request.content_type}
Expand Down Expand Up @@ -140,7 +147,7 @@ def __init__(self, hassio):
@asyncio.coroutine
def _handle(self, request, path):
"""Route data to hassio."""
if path != 'panel' and not request[KEY_AUTHENTICATED]:
if _need_auth(path) and not request[KEY_AUTHENTICATED]:
return web.Response(status=401)

client = yield from self.hassio.command_proxy(path, request)
Expand Down Expand Up @@ -173,3 +180,19 @@ def _create_response_log(client, data):
status=client.status,
content_type=CONTENT_TYPE_TEXT_PLAIN,
)


def _get_timeout(path):
"""Return timeout for a url path."""
for re_path in NO_TIMEOUT:
if re_path.match(path):
return 0
return 300


def _need_auth(path):
"""Return if a path need a auth."""
for re_path in NO_AUTH:
if re_path.match(path):
return False
return True
22 changes: 22 additions & 0 deletions tests/components/test_hassio.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ def test_forward_request_no_auth_for_panel(hassio_client):
assert mresp.mock_calls[0][1] == (response, 'data')


@asyncio.coroutine
def test_forward_request_no_auth_for_logo(hassio_client):
"""Test no auth needed for ."""
response = MagicMock()
response.read.return_value = mock_coro('data')

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'
resp = yield from hassio_client.get('/api/hassio/addons/bl_b392/logo')

# Check we got right response
assert resp.status == 200
body = yield from resp.text()
assert body == 'response'

# Check we forwarded command
assert len(mresp.mock_calls) == 1
assert mresp.mock_calls[0][1] == (response, 'data')


@asyncio.coroutine
def test_forward_log_request(hassio_client):
"""Test fetching normal log path."""
Expand Down

0 comments on commit 51108b8

Please sign in to comment.