Add user events (#17328)
parent
44477f3d32
commit
61bf4d8a29
|
@ -16,6 +16,9 @@ from . import auth_store, models
|
|||
from .mfa_modules import auth_mfa_module_from_config, MultiFactorAuthModule
|
||||
from .providers import auth_provider_from_config, AuthProvider, LoginFlow
|
||||
|
||||
EVENT_USER_ADDED = 'user_added'
|
||||
EVENT_USER_REMOVED = 'user_removed'
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
_MfaModuleDict = Dict[str, MultiFactorAuthModule]
|
||||
_ProviderKey = Tuple[str, Optional[str]]
|
||||
|
@ -126,13 +129,19 @@ class AuthManager:
|
|||
|
||||
async def async_create_system_user(self, name: str) -> models.User:
|
||||
"""Create a system user."""
|
||||
return await self._store.async_create_user(
|
||||
user = await self._store.async_create_user(
|
||||
name=name,
|
||||
system_generated=True,
|
||||
is_active=True,
|
||||
groups=[],
|
||||
)
|
||||
|
||||
self.hass.bus.async_fire(EVENT_USER_ADDED, {
|
||||
'user_id': user.id
|
||||
})
|
||||
|
||||
return user
|
||||
|
||||
async def async_create_user(self, name: str) -> models.User:
|
||||
"""Create a user."""
|
||||
group = (await self._store.async_get_groups())[0]
|
||||
|
@ -145,7 +154,13 @@ class AuthManager:
|
|||
if await self._user_should_be_owner():
|
||||
kwargs['is_owner'] = True
|
||||
|
||||
return await self._store.async_create_user(**kwargs)
|
||||
user = await self._store.async_create_user(**kwargs)
|
||||
|
||||
self.hass.bus.async_fire(EVENT_USER_ADDED, {
|
||||
'user_id': user.id
|
||||
})
|
||||
|
||||
return user
|
||||
|
||||
async def async_get_or_create_user(self, credentials: models.Credentials) \
|
||||
-> models.User:
|
||||
|
@ -165,12 +180,18 @@ class AuthManager:
|
|||
info = await auth_provider.async_user_meta_for_credentials(
|
||||
credentials)
|
||||
|
||||
return await self._store.async_create_user(
|
||||
user = await self._store.async_create_user(
|
||||
credentials=credentials,
|
||||
name=info.name,
|
||||
is_active=info.is_active,
|
||||
)
|
||||
|
||||
self.hass.bus.async_fire(EVENT_USER_ADDED, {
|
||||
'user_id': user.id
|
||||
})
|
||||
|
||||
return user
|
||||
|
||||
async def async_link_user(self, user: models.User,
|
||||
credentials: models.Credentials) -> None:
|
||||
"""Link credentials to an existing user."""
|
||||
|
@ -188,6 +209,10 @@ class AuthManager:
|
|||
|
||||
await self._store.async_remove_user(user)
|
||||
|
||||
self.hass.bus.async_fire(EVENT_USER_REMOVED, {
|
||||
'user_id': user.id
|
||||
})
|
||||
|
||||
async def async_activate_user(self, user: models.User) -> None:
|
||||
"""Activate a user."""
|
||||
await self._store.async_activate_user(user)
|
||||
|
|
|
@ -10,6 +10,7 @@ from homeassistant import auth, data_entry_flow
|
|||
from homeassistant.auth import (
|
||||
models as auth_models, auth_store, const as auth_const)
|
||||
from homeassistant.auth.const import MFA_SESSION_EXPIRATION
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.util import dt as dt_util
|
||||
from tests.common import (
|
||||
MockUser, ensure_auth_manager_loaded, flush_store, CLIENT_ID)
|
||||
|
@ -138,6 +139,14 @@ async def test_auth_manager_from_config_auth_modules(mock_hass):
|
|||
|
||||
async def test_create_new_user(hass):
|
||||
"""Test creating new user."""
|
||||
events = []
|
||||
|
||||
@callback
|
||||
def user_added(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen('user_added', user_added)
|
||||
|
||||
manager = await auth.auth_manager_from_config(hass, [{
|
||||
'type': 'insecure_example',
|
||||
'users': [{
|
||||
|
@ -160,6 +169,10 @@ async def test_create_new_user(hass):
|
|||
assert user.is_owner is False
|
||||
assert user.name == 'Test Name'
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 1
|
||||
assert events[0].data['user_id'] == user.id
|
||||
|
||||
|
||||
async def test_login_as_existing_user(mock_hass):
|
||||
"""Test login as existing user."""
|
||||
|
@ -331,6 +344,14 @@ async def test_cannot_retrieve_expired_access_token(hass):
|
|||
|
||||
async def test_generating_system_user(hass):
|
||||
"""Test that we can add a system user."""
|
||||
events = []
|
||||
|
||||
@callback
|
||||
def user_added(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen('user_added', user_added)
|
||||
|
||||
manager = await auth.auth_manager_from_config(hass, [], [])
|
||||
user = await manager.async_create_system_user('Hass.io')
|
||||
token = await manager.async_create_refresh_token(user)
|
||||
|
@ -338,6 +359,10 @@ async def test_generating_system_user(hass):
|
|||
assert token is not None
|
||||
assert token.client_id is None
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 1
|
||||
assert events[0].data['user_id'] == user.id
|
||||
|
||||
|
||||
async def test_refresh_token_requires_client_for_user(hass):
|
||||
"""Test create refresh token for a user with client_id."""
|
||||
|
@ -797,3 +822,50 @@ async def test_enable_mfa_for_user(hass, hass_storage):
|
|||
|
||||
# disable mfa for user don't enabled just silent fail
|
||||
await manager.async_disable_user_mfa(user, 'insecure_example')
|
||||
|
||||
|
||||
async def test_async_remove_user(hass):
|
||||
"""Test removing a user."""
|
||||
events = []
|
||||
|
||||
@callback
|
||||
def user_removed(event):
|
||||
events.append(event)
|
||||
|
||||
hass.bus.async_listen('user_removed', user_removed)
|
||||
|
||||
manager = await auth.auth_manager_from_config(hass, [{
|
||||
'type': 'insecure_example',
|
||||
'users': [{
|
||||
'username': 'test-user',
|
||||
'password': 'test-pass',
|
||||
'name': 'Test Name'
|
||||
}]
|
||||
}], [])
|
||||
hass.auth = manager
|
||||
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_models.Credentials(
|
||||
id='mock-id',
|
||||
auth_provider_type='insecure_example',
|
||||
auth_provider_id=None,
|
||||
data={'username': 'test-user'},
|
||||
is_new=False,
|
||||
))
|
||||
assert len(user.credentials) == 1
|
||||
|
||||
await hass.auth.async_remove_user(user)
|
||||
|
||||
assert len(await manager.async_get_users()) == 0
|
||||
assert len(user.credentials) == 0
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 1
|
||||
assert events[0].data['user_id'] == user.id
|
||||
|
|
Loading…
Reference in New Issue