Allow token authentication for 'hook' switch component (#6922)

The Hook switch component currently uses username/password to get a token
from the Hook web app to use for subsequent requests. This adds an option
to specify the token directly in config.

Makes the 'password' and 'token' options mutually exclusive since
otherwise one would have to take precedence, and it seems worth
preventing people from filling their config with passwords that don't
even need to be there.
This commit is contained in:
Klaas Hoekema 2017-04-04 04:55:43 -04:00 committed by Pascal Vizeli
parent aff8c0f695
commit 57a00c1fbf

View File

@ -12,7 +12,7 @@ import async_timeout
import aiohttp import aiohttp
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, CONF_TOKEN
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
@ -22,8 +22,12 @@ HOOK_ENDPOINT = 'https://api.gethook.io/v1/'
TIMEOUT = 10 TIMEOUT = 10
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_USERNAME): cv.string, vol.Exclusive(CONF_PASSWORD, 'hook_secret', msg='hook: provide ' +
vol.Required(CONF_PASSWORD): cv.string, 'username/password OR token'): cv.string,
vol.Exclusive(CONF_TOKEN, 'hook_secret', msg='hook: provide ' +
'username/password OR token'): cv.string,
vol.Inclusive(CONF_USERNAME, 'hook_auth'): cv.string,
vol.Inclusive(CONF_PASSWORD, 'hook_auth'): cv.string,
}) })
@ -32,8 +36,10 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
"""Set up Hook by getting the access token and list of actions.""" """Set up Hook by getting the access token and list of actions."""
username = config.get(CONF_USERNAME) username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD) password = config.get(CONF_PASSWORD)
token = config.get(CONF_TOKEN)
websession = async_get_clientsession(hass) websession = async_get_clientsession(hass)
# If password is set in config, prefer it over token
if username is not None and password is not None:
try: try:
with async_timeout.timeout(TIMEOUT, loop=hass.loop): with async_timeout.timeout(TIMEOUT, loop=hass.loop):
response = yield from websession.post( response = yield from websession.post(
@ -56,7 +62,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
with async_timeout.timeout(TIMEOUT, loop=hass.loop): with async_timeout.timeout(TIMEOUT, loop=hass.loop):
response = yield from websession.get( response = yield from websession.get(
'{}{}'.format(HOOK_ENDPOINT, 'device'), '{}{}'.format(HOOK_ENDPOINT, 'device'),
params={"token": data['data']['token']}) params={"token": token})
data = yield from response.json() data = yield from response.json()
except (asyncio.TimeoutError, aiohttp.ClientError) as error: except (asyncio.TimeoutError, aiohttp.ClientError) as error:
_LOGGER.error("Failed getting devices: %s", error) _LOGGER.error("Failed getting devices: %s", error)