Accept login from approved ips without password (#3427)
parent
2c43d6718b
commit
11c07440fe
|
@ -74,7 +74,8 @@ def setup(hass, yaml_config):
|
|||
api_password=None,
|
||||
ssl_certificate=None,
|
||||
ssl_key=None,
|
||||
cors_origins=[]
|
||||
cors_origins=[],
|
||||
approved_ips=[]
|
||||
)
|
||||
|
||||
server.register_view(DescriptionXmlView(hass, config))
|
||||
|
|
|
@ -28,6 +28,7 @@ DOMAIN = 'http'
|
|||
REQUIREMENTS = ('cherrypy==8.1.0', 'static3==0.7.0', 'Werkzeug==0.11.11')
|
||||
|
||||
CONF_API_PASSWORD = 'api_password'
|
||||
CONF_APPROVED_IPS = 'approved_ips'
|
||||
CONF_SERVER_HOST = 'server_host'
|
||||
CONF_SERVER_PORT = 'server_port'
|
||||
CONF_DEVELOPMENT = 'development'
|
||||
|
@ -71,7 +72,8 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
vol.Optional(CONF_DEVELOPMENT): cv.string,
|
||||
vol.Optional(CONF_SSL_CERTIFICATE): cv.isfile,
|
||||
vol.Optional(CONF_SSL_KEY): cv.isfile,
|
||||
vol.Optional(CONF_CORS_ORIGINS): cv.ensure_list
|
||||
vol.Optional(CONF_CORS_ORIGINS): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_APPROVED_IPS): vol.All(cv.ensure_list, [cv.string])
|
||||
}),
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
@ -108,6 +110,7 @@ def setup(hass, config):
|
|||
ssl_certificate = conf.get(CONF_SSL_CERTIFICATE)
|
||||
ssl_key = conf.get(CONF_SSL_KEY)
|
||||
cors_origins = conf.get(CONF_CORS_ORIGINS, [])
|
||||
approved_ips = conf.get(CONF_APPROVED_IPS, [])
|
||||
|
||||
server = HomeAssistantWSGI(
|
||||
hass,
|
||||
|
@ -117,7 +120,8 @@ def setup(hass, config):
|
|||
api_password=api_password,
|
||||
ssl_certificate=ssl_certificate,
|
||||
ssl_key=ssl_key,
|
||||
cors_origins=cors_origins
|
||||
cors_origins=cors_origins,
|
||||
approved_ips=approved_ips
|
||||
)
|
||||
|
||||
def start_wsgi_server(event):
|
||||
|
@ -249,7 +253,8 @@ class HomeAssistantWSGI(object):
|
|||
# pylint: disable=too-many-arguments
|
||||
|
||||
def __init__(self, hass, development, api_password, ssl_certificate,
|
||||
ssl_key, server_host, server_port, cors_origins):
|
||||
ssl_key, server_host, server_port, cors_origins,
|
||||
approved_ips):
|
||||
"""Initilalize the WSGI Home Assistant server."""
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
|
@ -268,6 +273,7 @@ class HomeAssistantWSGI(object):
|
|||
self.server_host = server_host
|
||||
self.server_port = server_port
|
||||
self.cors_origins = cors_origins
|
||||
self.approved_ips = approved_ips
|
||||
self.event_forwarder = None
|
||||
self.server = None
|
||||
|
||||
|
@ -468,6 +474,9 @@ class HomeAssistantView(object):
|
|||
if self.hass.wsgi.api_password is None:
|
||||
authenticated = True
|
||||
|
||||
elif request.remote_addr in self.hass.wsgi.approved_ips:
|
||||
authenticated = True
|
||||
|
||||
elif hmac.compare_digest(request.headers.get(HTTP_HEADER_HA_AUTH, ''),
|
||||
self.hass.wsgi.api_password):
|
||||
# A valid auth header has been set
|
||||
|
|
|
@ -72,6 +72,15 @@ class TestHttp:
|
|||
|
||||
assert req.status_code == 401
|
||||
|
||||
def test_access_denied_with_ip_no_in_approved_ips(self, caplog):
|
||||
"""Test access deniend with ip not in approved ip."""
|
||||
hass.wsgi.approved_ips = ['134.4.56.1']
|
||||
|
||||
req = requests.get(_url(const.URL_API),
|
||||
params={'api_password': ''})
|
||||
|
||||
assert req.status_code == 401
|
||||
|
||||
def test_access_with_password_in_header(self, caplog):
|
||||
"""Test access with password in URL."""
|
||||
# Hide logging from requests package that we use to test logging
|
||||
|
@ -112,6 +121,15 @@ class TestHttp:
|
|||
# assert const.URL_API in logs
|
||||
assert API_PASSWORD not in logs
|
||||
|
||||
def test_access_with_ip_in_approved_ips(self, caplog):
|
||||
"""Test access with approved ip."""
|
||||
hass.wsgi.approved_ips = ['127.0.0.1', '134.4.56.1']
|
||||
|
||||
req = requests.get(_url(const.URL_API),
|
||||
params={'api_password': ''})
|
||||
|
||||
assert req.status_code == 200
|
||||
|
||||
def test_cors_allowed_with_password_in_url(self):
|
||||
"""Test cross origin resource sharing with password in url."""
|
||||
req = requests.get(_url(const.URL_API),
|
||||
|
|
Loading…
Reference in New Issue