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
15 changes: 13 additions & 2 deletions homeassistant/components/emulated_hue/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from homeassistant.helpers.deprecation import get_deprecated
import homeassistant.helpers.config_validation as cv
from homeassistant.util.json import load_json, save_json
from homeassistant.components.http import real_ip

from .hue_api import (
HueUsernameView, HueAllLightsStateView, HueOneLightStateView,
HueOneLightChangeView, HueGroupView)
Expand Down Expand Up @@ -81,12 +83,20 @@
ATTR_EMULATED_HUE_HIDDEN = 'emulated_hue_hidden'


def setup(hass, yaml_config):
async def async_setup(hass, yaml_config):
"""Activate the emulated_hue component."""
config = Config(hass, yaml_config.get(DOMAIN, {}))

app = web.Application()
app['hass'] = hass

real_ip.setup_real_ip(app, False, [])
# We misunderstood the startup signal. You're not allowed to change
# anything during startup. Temp workaround.
# pylint: disable=protected-access
app._on_startup.freeze()
await app.startup()

handler = None
server = None

Expand Down Expand Up @@ -131,7 +141,8 @@ async def start_emulated_hue_bridge(event):
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, stop_emulated_hue_bridge)

hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_emulated_hue_bridge)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
start_emulated_hue_bridge)

return True

Expand Down
23 changes: 23 additions & 0 deletions homeassistant/components/emulated_hue/hue_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
SPEED_MEDIUM, SPEED_HIGH
)
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.const import KEY_REAL_IP
from homeassistant.util.network import is_local


_LOGGER = logging.getLogger(__name__)

Expand All @@ -46,6 +49,10 @@ async def post(self, request):
return self.json_message('devicetype not specified',
HTTP_BAD_REQUEST)

if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)

return self.json([{'success': {'username': '12345678901234567890'}}])


Expand All @@ -63,6 +70,10 @@ def __init__(self, config):
@core.callback
def put(self, request, username):
"""Process a request to make the Logitech Pop working."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)

return self.json([{
'error': {
'address': '/groups/0/action/scene',
Expand All @@ -86,6 +97,10 @@ def __init__(self, config):
@core.callback
def get(self, request, username):
"""Process a request to get the list of available lights."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)

hass = request.app['hass']
json_response = {}

Expand Down Expand Up @@ -114,6 +129,10 @@ def __init__(self, config):
@core.callback
def get(self, request, username, entity_id):
"""Process a request to get the state of an individual light."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)

hass = request.app['hass']
entity_id = self.config.number_to_entity_id(entity_id)
entity = hass.states.get(entity_id)
Expand Down Expand Up @@ -146,6 +165,10 @@ def __init__(self, config):

async def put(self, request, username, entity_number):
"""Process a request to set the state of an individual light."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)

config = self.config
hass = request.app['hass']
entity_id = config.number_to_entity_id(entity_number)
Expand Down
10 changes: 10 additions & 0 deletions tests/components/emulated_hue/test_hue_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""The tests for the emulated Hue component."""
import asyncio
import json
from ipaddress import ip_address
from unittest.mock import patch

from aiohttp.hdrs import CONTENT_TYPE
Expand Down Expand Up @@ -484,3 +485,12 @@ def perform_put_light_state(hass_hue, client, entity_id, is_on,
yield from hass_hue.async_block_till_done()

return result


async def test_external_ip_blocked(hue_client):
"""Test external IP blocked."""
with patch('homeassistant.components.http.real_ip.ip_address',
return_value=ip_address('45.45.45.45')):
result = await hue_client.get('/api/username/lights')

assert result.status == 400