Skip to content

Commit

Permalink
0.74.2 (#15671)
Browse files Browse the repository at this point in the history
* Fix CORS duplicate registration (#15670)

* Bumped version to 0.74.2
  • Loading branch information
balloob authored Jul 25, 2018
1 parent 5e9c109 commit 9d59bfb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 22 deletions.
38 changes: 22 additions & 16 deletions homeassistant/components/http/cors.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,36 @@ def setup_cors(app, origins):
) for host in origins
})

def allow_cors(route, methods):
cors_added = set()

def _allow_cors(route, config=None):
"""Allow cors on a route."""
cors.add(route, {
'*': aiohttp_cors.ResourceOptions(
allow_headers=ALLOWED_CORS_HEADERS,
allow_methods=methods,
)
})
if hasattr(route, 'resource'):
path = route.resource
else:
path = route

path = path.canonical

if path in cors_added:
return

cors.add(route, config)
cors_added.add(path)

app['allow_cors'] = allow_cors
app['allow_cors'] = lambda route: _allow_cors(route, {
'*': aiohttp_cors.ResourceOptions(
allow_headers=ALLOWED_CORS_HEADERS,
allow_methods='*',
)
})

if not origins:
return

async def cors_startup(app):
"""Initialize cors when app starts up."""
cors_added = set()

for route in list(app.router.routes()):
if hasattr(route, 'resource'):
route = route.resource
if route in cors_added:
continue
cors.add(route)
cors_added.add(route)
_allow_cors(route)

app.on_startup.append(cors_startup)
8 changes: 3 additions & 5 deletions homeassistant/components/http/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,13 @@ def register(self, app, router):
handler = request_handler_factory(self, handler)

for url in urls:
routes.append(
(method, router.add_route(method, url, handler))
)
routes.append(router.add_route(method, url, handler))

if not self.cors_allowed:
return

for method, route in routes:
app['allow_cors'](route, [method.upper()])
for route in routes:
app['allow_cors'](route)


def request_handler_factory(view, handler):
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 74
PATCH_VERSION = '1'
PATCH_VERSION = '2'
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 5, 3)
Expand Down
32 changes: 32 additions & 0 deletions tests/components/http/test_cors.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from homeassistant.const import HTTP_HEADER_HA_AUTH
from homeassistant.setup import async_setup_component
from homeassistant.components.http.cors import setup_cors
from homeassistant.components.http.view import HomeAssistantView


TRUSTED_ORIGIN = 'https://home-assistant.io'
Expand Down Expand Up @@ -96,3 +97,34 @@ async def test_cors_preflight_allowed(client):
assert req.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == TRUSTED_ORIGIN
assert req.headers[ACCESS_CONTROL_ALLOW_HEADERS] == \
HTTP_HEADER_HA_AUTH.upper()


async def test_cors_middleware_with_cors_allowed_view(hass):
"""Test that we can configure cors and have a cors_allowed view."""
class MyView(HomeAssistantView):
"""Test view that allows CORS."""

requires_auth = False
cors_allowed = True

def __init__(self, url, name):
"""Initialize test view."""
self.url = url
self.name = name

async def get(self, request):
"""Test response."""
return "test"

assert await async_setup_component(hass, 'http', {
'http': {
'cors_allowed_origins': ['http://home-assistant.io']
}
})

hass.http.register_view(MyView('/api/test', 'api:test'))
hass.http.register_view(MyView('/api/test', 'api:test2'))
hass.http.register_view(MyView('/api/test2', 'api:test'))

hass.http.app._on_startup.freeze()
await hass.http.app.startup()

0 comments on commit 9d59bfb

Please sign in to comment.