Foundation for users (#13968)
* Add initial user foundation to Home Assistant * Address comments * Address comments * Allow non-ascii passwords * One more utf-8 hmac compare digest * Add new line
This commit is contained in:
parent
b994c10d7f
commit
cdd45e7878
22 changed files with 1774 additions and 59 deletions
|
@ -32,17 +32,19 @@ def setup_auth(app, trusted_networks, api_password):
|
|||
|
||||
if (HTTP_HEADER_HA_AUTH in request.headers and
|
||||
hmac.compare_digest(
|
||||
api_password, request.headers[HTTP_HEADER_HA_AUTH])):
|
||||
api_password.encode('utf-8'),
|
||||
request.headers[HTTP_HEADER_HA_AUTH].encode('utf-8'))):
|
||||
# A valid auth header has been set
|
||||
authenticated = True
|
||||
|
||||
elif (DATA_API_PASSWORD in request.query and
|
||||
hmac.compare_digest(api_password,
|
||||
request.query[DATA_API_PASSWORD])):
|
||||
hmac.compare_digest(
|
||||
api_password.encode('utf-8'),
|
||||
request.query[DATA_API_PASSWORD].encode('utf-8'))):
|
||||
authenticated = True
|
||||
|
||||
elif (hdrs.AUTHORIZATION in request.headers and
|
||||
validate_authorization_header(api_password, request)):
|
||||
await async_validate_auth_header(api_password, request)):
|
||||
authenticated = True
|
||||
|
||||
elif _is_trusted_ip(request, trusted_networks):
|
||||
|
@ -70,23 +72,38 @@ def _is_trusted_ip(request, trusted_networks):
|
|||
def validate_password(request, api_password):
|
||||
"""Test if password is valid."""
|
||||
return hmac.compare_digest(
|
||||
api_password, request.app['hass'].http.api_password)
|
||||
api_password.encode('utf-8'),
|
||||
request.app['hass'].http.api_password.encode('utf-8'))
|
||||
|
||||
|
||||
def validate_authorization_header(api_password, request):
|
||||
async def async_validate_auth_header(api_password, request):
|
||||
"""Test an authorization header if valid password."""
|
||||
if hdrs.AUTHORIZATION not in request.headers:
|
||||
return False
|
||||
|
||||
auth_type, auth = request.headers.get(hdrs.AUTHORIZATION).split(' ', 1)
|
||||
auth_type, auth_val = request.headers.get(hdrs.AUTHORIZATION).split(' ', 1)
|
||||
|
||||
if auth_type != 'Basic':
|
||||
if auth_type == 'Basic':
|
||||
decoded = base64.b64decode(auth_val).decode('utf-8')
|
||||
try:
|
||||
username, password = decoded.split(':', 1)
|
||||
except ValueError:
|
||||
# If no ':' in decoded
|
||||
return False
|
||||
|
||||
if username != 'homeassistant':
|
||||
return False
|
||||
|
||||
return hmac.compare_digest(api_password.encode('utf-8'),
|
||||
password.encode('utf-8'))
|
||||
|
||||
if auth_type != 'Bearer':
|
||||
return False
|
||||
|
||||
decoded = base64.b64decode(auth).decode('utf-8')
|
||||
username, password = decoded.split(':', 1)
|
||||
|
||||
if username != 'homeassistant':
|
||||
hass = request.app['hass']
|
||||
access_token = hass.auth.async_get_access_token(auth_val)
|
||||
if access_token is None:
|
||||
return False
|
||||
|
||||
return hmac.compare_digest(api_password, password)
|
||||
request['hass_user'] = access_token.refresh_token.user
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue