155 lines
4.5 KiB
Python
155 lines
4.5 KiB
Python
"""Test cors for the HTTP component."""
|
|
from unittest.mock import patch
|
|
|
|
from aiohttp import web
|
|
from aiohttp.hdrs import (
|
|
ACCESS_CONTROL_ALLOW_ORIGIN,
|
|
ACCESS_CONTROL_ALLOW_HEADERS,
|
|
ACCESS_CONTROL_REQUEST_HEADERS,
|
|
ACCESS_CONTROL_REQUEST_METHOD,
|
|
AUTHORIZATION,
|
|
ORIGIN
|
|
)
|
|
import pytest
|
|
|
|
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'
|
|
|
|
|
|
async def test_cors_middleware_loaded_by_default(hass):
|
|
"""Test accessing to server from banned IP when feature is off."""
|
|
with patch('homeassistant.components.http.setup_cors') as mock_setup:
|
|
await async_setup_component(hass, 'http', {
|
|
'http': {}
|
|
})
|
|
|
|
assert len(mock_setup.mock_calls) == 1
|
|
|
|
|
|
async def test_cors_middleware_loaded_from_config(hass):
|
|
"""Test accessing to server from banned IP when feature is off."""
|
|
with patch('homeassistant.components.http.setup_cors') as mock_setup:
|
|
await async_setup_component(hass, 'http', {
|
|
'http': {
|
|
'cors_allowed_origins': ['http://home-assistant.io']
|
|
}
|
|
})
|
|
|
|
assert len(mock_setup.mock_calls) == 1
|
|
|
|
|
|
async def mock_handler(request):
|
|
"""Return if request was authenticated."""
|
|
return web.Response(status=200)
|
|
|
|
|
|
@pytest.fixture
|
|
def client(loop, aiohttp_client):
|
|
"""Fixture to set up a web.Application."""
|
|
app = web.Application()
|
|
app.router.add_get('/', mock_handler)
|
|
setup_cors(app, [TRUSTED_ORIGIN])
|
|
return loop.run_until_complete(aiohttp_client(app))
|
|
|
|
|
|
async def test_cors_requests(client):
|
|
"""Test cross origin requests."""
|
|
req = await client.get('/', headers={
|
|
ORIGIN: TRUSTED_ORIGIN
|
|
})
|
|
assert req.status == 200
|
|
assert req.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == \
|
|
TRUSTED_ORIGIN
|
|
|
|
# With password in URL
|
|
req = await client.get('/', params={
|
|
'api_password': 'some-pass'
|
|
}, headers={
|
|
ORIGIN: TRUSTED_ORIGIN
|
|
})
|
|
assert req.status == 200
|
|
assert req.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == \
|
|
TRUSTED_ORIGIN
|
|
|
|
# With password in headers
|
|
req = await client.get('/', headers={
|
|
HTTP_HEADER_HA_AUTH: 'some-pass',
|
|
ORIGIN: TRUSTED_ORIGIN
|
|
})
|
|
assert req.status == 200
|
|
assert req.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == \
|
|
TRUSTED_ORIGIN
|
|
|
|
# With auth token in headers
|
|
req = await client.get('/', headers={
|
|
AUTHORIZATION: 'Bearer some-token',
|
|
ORIGIN: TRUSTED_ORIGIN
|
|
})
|
|
assert req.status == 200
|
|
assert req.headers[ACCESS_CONTROL_ALLOW_ORIGIN] == \
|
|
TRUSTED_ORIGIN
|
|
|
|
|
|
async def test_cors_preflight_allowed(client):
|
|
"""Test cross origin resource sharing preflight (OPTIONS) request."""
|
|
req = await client.options('/', headers={
|
|
ORIGIN: TRUSTED_ORIGIN,
|
|
ACCESS_CONTROL_REQUEST_METHOD: 'GET',
|
|
ACCESS_CONTROL_REQUEST_HEADERS: 'x-ha-access'
|
|
})
|
|
|
|
assert req.status == 200
|
|
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()
|
|
|
|
|
|
async def test_cors_works_with_frontend(hass, hass_client):
|
|
"""Test CORS works with the frontend."""
|
|
assert await async_setup_component(hass, 'frontend', {
|
|
'http': {
|
|
'cors_allowed_origins': ['http://home-assistant.io']
|
|
}
|
|
})
|
|
client = await hass_client()
|
|
resp = await client.get('/')
|
|
assert resp.status == 200
|