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
1 change: 1 addition & 0 deletions homeassistant/components/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def __init__(self, host: str, port: Optional[int] = SERVER_PORT,
self.port = port
self.api_password = api_password

host = host.rstrip('/')
if host.startswith(("http://", "https://")):
self.base_url = host
elif use_ssl:
Expand Down
14 changes: 11 additions & 3 deletions homeassistant/components/webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
_LOGGER = logging.getLogger(__name__)


URL_WEBHOOK_PATH = "/api/webhook/{webhook_id}"
WS_TYPE_LIST = 'webhook/list'
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({
vol.Required('type'): WS_TYPE_LIST,
Expand Down Expand Up @@ -58,8 +59,15 @@ def async_generate_id():
@callback
@bind_hass
def async_generate_url(hass, webhook_id):
"""Generate a webhook_id."""
return "{}/api/webhook/{}".format(hass.config.api.base_url, webhook_id)
"""Generate the full URL for a webhook_id."""
return "{}{}".format(hass.config.api.base_url,
async_generate_path(webhook_id))


@callback
def async_generate_path(webhook_id):
"""Generate the path component for a webhook_id."""
return URL_WEBHOOK_PATH.format(webhook_id=webhook_id)


@bind_hass
Expand Down Expand Up @@ -97,7 +105,7 @@ async def async_setup(hass, config):
class WebhookView(HomeAssistantView):
"""Handle incoming webhook requests."""

url = "/api/webhook/{webhook_id}"
url = URL_WEBHOOK_PATH
name = "api:webhook"
requires_auth = False

Expand Down
16 changes: 16 additions & 0 deletions tests/components/http/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ def test_api_base_url_with_protocol_and_ssl_enable(hass):
api_config = http.ApiConfig('http://example.com', use_ssl=True)
assert api_config.base_url == 'http://example.com:8123'

def test_api_base_url_removes_trailing_slash(hass):
"""Test a trialing slash is removed when setting the API URL."""
api_config = http.ApiConfig('http://example.com/')
assert api_config.base_url == 'http://example.com:8123'


async def test_api_base_url_with_domain(hass):
"""Test setting API URL."""
Expand Down Expand Up @@ -124,6 +129,17 @@ async def test_api_no_base_url(hass):
assert hass.config.api.base_url == 'http://127.0.0.1:8123'


async def test_api_base_url_removes_trailing_slash(hass):
"""Test setting api url."""
result = await async_setup_component(hass, 'http', {
'http': {
'base_url': 'https://example.com/'
}
})
assert result
assert hass.config.api.base_url == 'https://example.com'


async def test_not_log_password(hass, aiohttp_client, caplog, legacy_auth):
"""Test access with password doesn't get logged."""
assert await async_setup_component(hass, 'api', {
Expand Down
6 changes: 6 additions & 0 deletions tests/components/test_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ async def test_generate_webhook_url(hass):
assert url == 'https://example.com/api/webhook/some_id'


async def test_async_generate_path(hass):
"""Test generating just the path component of the url correctly."""
path = hass.components.webhook.async_generate_path('some_id')
assert path == '/api/webhook/some_id'


async def test_posting_webhook_nonexisting(hass, mock_client):
"""Test posting to a nonexisting webhook."""
resp = await mock_client.post('/api/webhook/non-existing')
Expand Down