mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Prevent legacy api password with empty password (#16127)
* Prevent legacy api password with empty password * Typing
This commit is contained in:
parent
8e173f1658
commit
249981de96
@ -46,13 +46,6 @@ class LegacyApiPasswordAuthProvider(AuthProvider):
|
|||||||
"""Helper to validate a username and password."""
|
"""Helper to validate a username and password."""
|
||||||
hass_http = getattr(self.hass, 'http', None) # type: HomeAssistantHTTP
|
hass_http = getattr(self.hass, 'http', None) # type: HomeAssistantHTTP
|
||||||
|
|
||||||
if not hass_http:
|
|
||||||
raise ValueError('http component is not loaded')
|
|
||||||
|
|
||||||
if hass_http.api_password is None:
|
|
||||||
raise ValueError('http component is not configured using'
|
|
||||||
' api_password')
|
|
||||||
|
|
||||||
if not hmac.compare_digest(hass_http.api_password.encode('utf-8'),
|
if not hmac.compare_digest(hass_http.api_password.encode('utf-8'),
|
||||||
password.encode('utf-8')):
|
password.encode('utf-8')):
|
||||||
raise InvalidAuthError
|
raise InvalidAuthError
|
||||||
@ -87,6 +80,12 @@ class LegacyLoginFlow(LoginFlow):
|
|||||||
"""Handle the step of the form."""
|
"""Handle the step of the form."""
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
|
hass_http = getattr(self.hass, 'http', None)
|
||||||
|
if hass_http is None or not hass_http.api_password:
|
||||||
|
return self.async_abort(
|
||||||
|
reason='no_api_password_set'
|
||||||
|
)
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
try:
|
try:
|
||||||
cast(LegacyApiPasswordAuthProvider, self._auth_provider)\
|
cast(LegacyApiPasswordAuthProvider, self._auth_provider)\
|
||||||
|
@ -3,7 +3,7 @@ from unittest.mock import Mock
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant import auth
|
from homeassistant import auth, data_entry_flow
|
||||||
from homeassistant.auth import auth_store
|
from homeassistant.auth import auth_store
|
||||||
from homeassistant.auth.providers import legacy_api_password
|
from homeassistant.auth.providers import legacy_api_password
|
||||||
|
|
||||||
@ -51,17 +51,6 @@ async def test_only_one_credentials(manager, provider):
|
|||||||
assert credentials2.is_new is False
|
assert credentials2.is_new is False
|
||||||
|
|
||||||
|
|
||||||
async def test_verify_not_load(hass, provider):
|
|
||||||
"""Test we raise if http module not load."""
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
provider.async_validate_login('test-password')
|
|
||||||
hass.http = Mock(api_password=None)
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
provider.async_validate_login('test-password')
|
|
||||||
hass.http = Mock(api_password='test-password')
|
|
||||||
provider.async_validate_login('test-password')
|
|
||||||
|
|
||||||
|
|
||||||
async def test_verify_login(hass, provider):
|
async def test_verify_login(hass, provider):
|
||||||
"""Test login using legacy api password auth provider."""
|
"""Test login using legacy api password auth provider."""
|
||||||
hass.http = Mock(api_password='test-password')
|
hass.http = Mock(api_password='test-password')
|
||||||
@ -69,3 +58,45 @@ async def test_verify_login(hass, provider):
|
|||||||
hass.http = Mock(api_password='test-password')
|
hass.http = Mock(api_password='test-password')
|
||||||
with pytest.raises(legacy_api_password.InvalidAuthError):
|
with pytest.raises(legacy_api_password.InvalidAuthError):
|
||||||
provider.async_validate_login('invalid-password')
|
provider.async_validate_login('invalid-password')
|
||||||
|
|
||||||
|
|
||||||
|
async def test_login_flow_abort(hass, manager):
|
||||||
|
"""Test wrong config."""
|
||||||
|
for http in (
|
||||||
|
None,
|
||||||
|
Mock(api_password=None),
|
||||||
|
Mock(api_password=''),
|
||||||
|
):
|
||||||
|
hass.http = http
|
||||||
|
|
||||||
|
result = await manager.login_flow.async_init(
|
||||||
|
handler=('legacy_api_password', None)
|
||||||
|
)
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
assert result['reason'] == 'no_api_password_set'
|
||||||
|
|
||||||
|
|
||||||
|
async def test_login_flow_works(hass, manager):
|
||||||
|
"""Test wrong config."""
|
||||||
|
hass.http = Mock(api_password='hello')
|
||||||
|
result = await manager.login_flow.async_init(
|
||||||
|
handler=('legacy_api_password', None)
|
||||||
|
)
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
|
||||||
|
result = await manager.login_flow.async_configure(
|
||||||
|
flow_id=result['flow_id'],
|
||||||
|
user_input={
|
||||||
|
'password': 'not-hello'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_FORM
|
||||||
|
assert result['errors']['base'] == 'invalid_auth'
|
||||||
|
|
||||||
|
result = await manager.login_flow.async_configure(
|
||||||
|
flow_id=result['flow_id'],
|
||||||
|
user_input={
|
||||||
|
'password': 'hello'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||||
|
Loading…
x
Reference in New Issue
Block a user