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
159
tests/test_auth.py
Normal file
159
tests/test_auth.py
Normal file
|
@ -0,0 +1,159 @@
|
|||
"""Tests for the Home Assistant auth module."""
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant import auth, data_entry_flow
|
||||
from tests.common import MockUser, ensure_auth_manager_loaded
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_hass():
|
||||
"""Hass mock with minimum amount of data set to make it work with auth."""
|
||||
hass = Mock()
|
||||
hass.config.skip_pip = True
|
||||
return hass
|
||||
|
||||
|
||||
async def test_auth_manager_from_config_validates_config_and_id(mock_hass):
|
||||
"""Test get auth providers."""
|
||||
manager = await auth.auth_manager_from_config(mock_hass, [{
|
||||
'name': 'Test Name',
|
||||
'type': 'insecure_example',
|
||||
'users': [],
|
||||
}, {
|
||||
'name': 'Invalid config because no users',
|
||||
'type': 'insecure_example',
|
||||
'id': 'invalid_config',
|
||||
}, {
|
||||
'name': 'Test Name 2',
|
||||
'type': 'insecure_example',
|
||||
'id': 'another',
|
||||
'users': [],
|
||||
}, {
|
||||
'name': 'Wrong because duplicate ID',
|
||||
'type': 'insecure_example',
|
||||
'id': 'another',
|
||||
'users': [],
|
||||
}])
|
||||
|
||||
providers = [{
|
||||
'name': provider.name,
|
||||
'id': provider.id,
|
||||
'type': provider.type,
|
||||
} for provider in manager.async_auth_providers]
|
||||
assert providers == [{
|
||||
'name': 'Test Name',
|
||||
'type': 'insecure_example',
|
||||
'id': None,
|
||||
}, {
|
||||
'name': 'Test Name 2',
|
||||
'type': 'insecure_example',
|
||||
'id': 'another',
|
||||
}]
|
||||
|
||||
|
||||
async def test_create_new_user(mock_hass):
|
||||
"""Test creating new user."""
|
||||
manager = await auth.auth_manager_from_config(mock_hass, [{
|
||||
'type': 'insecure_example',
|
||||
'users': [{
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
'name': 'Test Name'
|
||||
}]
|
||||
}])
|
||||
|
||||
step = await manager.login_flow.async_init(('insecure_example', None))
|
||||
assert step['type'] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
||||
step = await manager.login_flow.async_configure(step['flow_id'], {
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
})
|
||||
assert step['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
credentials = step['result']
|
||||
user = await manager.async_get_or_create_user(credentials)
|
||||
assert user is not None
|
||||
assert user.is_owner is True
|
||||
assert user.name == 'Test Name'
|
||||
|
||||
|
||||
async def test_login_as_existing_user(mock_hass):
|
||||
"""Test login as existing user."""
|
||||
manager = await auth.auth_manager_from_config(mock_hass, [{
|
||||
'type': 'insecure_example',
|
||||
'users': [{
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
'name': 'Test Name'
|
||||
}]
|
||||
}])
|
||||
ensure_auth_manager_loaded(manager)
|
||||
|
||||
# Add fake user with credentials for example auth provider.
|
||||
user = MockUser(
|
||||
id='mock-user',
|
||||
is_owner=False,
|
||||
is_active=False,
|
||||
name='Paulus',
|
||||
).add_to_auth_manager(manager)
|
||||
user.credentials.append(auth.Credentials(
|
||||
id='mock-id',
|
||||
auth_provider_type='insecure_example',
|
||||
auth_provider_id=None,
|
||||
data={'username': 'test-user'},
|
||||
is_new=False,
|
||||
))
|
||||
|
||||
step = await manager.login_flow.async_init(('insecure_example', None))
|
||||
assert step['type'] == data_entry_flow.RESULT_TYPE_FORM
|
||||
|
||||
step = await manager.login_flow.async_configure(step['flow_id'], {
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
})
|
||||
assert step['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
credentials = step['result']
|
||||
|
||||
user = await manager.async_get_or_create_user(credentials)
|
||||
assert user is not None
|
||||
assert user.id == 'mock-user'
|
||||
assert user.is_owner is False
|
||||
assert user.is_active is False
|
||||
assert user.name == 'Paulus'
|
||||
|
||||
|
||||
async def test_linking_user_to_two_auth_providers(mock_hass):
|
||||
"""Test linking user to two auth providers."""
|
||||
manager = await auth.auth_manager_from_config(mock_hass, [{
|
||||
'type': 'insecure_example',
|
||||
'users': [{
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
}]
|
||||
}, {
|
||||
'type': 'insecure_example',
|
||||
'id': 'another-provider',
|
||||
'users': [{
|
||||
'username': 'another-user',
|
||||
'password': 'another-password',
|
||||
}]
|
||||
}])
|
||||
|
||||
step = await manager.login_flow.async_init(('insecure_example', None))
|
||||
step = await manager.login_flow.async_configure(step['flow_id'], {
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
})
|
||||
user = await manager.async_get_or_create_user(step['result'])
|
||||
assert user is not None
|
||||
|
||||
step = await manager.login_flow.async_init(('insecure_example',
|
||||
'another-provider'))
|
||||
step = await manager.login_flow.async_configure(step['flow_id'], {
|
||||
'username': 'another-user',
|
||||
'password': 'another-password',
|
||||
})
|
||||
await manager.async_link_user(user, step['result'])
|
||||
assert len(user.credentials) == 2
|
Loading…
Add table
Add a link
Reference in a new issue