Add a VoIP user (#91884)

* Add a VoIP user

* Fix tests
pull/91888/head
Paulus Schoutsen 2023-04-22 23:44:13 -04:00 committed by GitHub
parent 7fcf07c964
commit f18056f0a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 8 deletions

View File

@ -8,6 +8,7 @@ import logging
from voip_utils import SIP_PORT
from homeassistant.auth.const import GROUP_ID_USER
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
@ -43,6 +44,18 @@ class DomainData:
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up VoIP integration from a config entry."""
# Make sure there is a valid user ID for VoIP in the config entry
if (
"user" not in entry.data
or (await hass.auth.async_get_user(entry.data["user"])) is None
):
voip_user = await hass.auth.async_create_system_user(
"Voice over IP", group_ids=[GROUP_ID_USER]
)
hass.config_entries.async_update_entry(
entry, data={**entry.data, "user": voip_user.id}
)
devices = VoIPDevices(hass, entry)
devices.async_setup()
transport = await _create_sip_server(
@ -87,3 +100,11 @@ async def async_remove_config_entry_device(
) -> bool:
"""Remove device from a config entry."""
return True
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Remove VoIP entry."""
if "user" in entry.data and (
user := await hass.auth.async_get_user(entry.data["user"])
):
await hass.auth.async_remove_user(user)

View File

@ -2,16 +2,11 @@
"config": {
"step": {
"user": {
"data": {
"ip_address": "IP Address"
}
"description": "Receive Voice over IP calls to interact with Assist."
}
},
"abort": {
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
},
"error": {
"invalid_ip_address": "Invalid IPv4 address."
}
},
"entity": {

View File

@ -55,6 +55,7 @@ class HassVoipDatagramProtocol(VoipDatagramProtocol):
hass,
hass.config.language,
devices.async_get_or_create(call_info),
Context(user_id=devices.config_entry.data["user"]),
),
invalid_protocol_factory=lambda call_info: NotConfiguredRtpDatagramProtocol(
hass,
@ -77,6 +78,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol):
hass: HomeAssistant,
language: str,
voip_device: VoIPDevice,
context: Context,
pipeline_timeout: float = 30.0,
audio_timeout: float = 2.0,
listening_tone_enabled: bool = True,
@ -94,7 +96,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol):
self.listening_tone_enabled = listening_tone_enabled
self._audio_queue: asyncio.Queue[bytes] = asyncio.Queue()
self._context = Context()
self._context = context
self._conversation_id: str | None = None
self._pipeline_task: asyncio.Task | None = None
self._session_id: str | None = None

View File

@ -0,0 +1,13 @@
# serializer version: 1
# name: test_user_management
list([
dict({
'id': 'system-users',
'name': 'Users',
'policy': dict({
'entities': True,
}),
'system_generated': True,
}),
])
# ---

View File

@ -1,4 +1,6 @@
"""Test VoIP init."""
from syrupy.assertion import SnapshotAssertion
from homeassistant.core import HomeAssistant
@ -9,3 +11,22 @@ async def test_unload_entry(
) -> None:
"""Test adding/removing VoIP."""
assert await hass.config_entries.async_unload(config_entry.entry_id)
async def test_user_management(
hass: HomeAssistant, config_entry, setup_voip, snapshot: SnapshotAssertion
) -> None:
"""Test creating and removing voip user."""
user = await hass.auth.async_get_user(config_entry.data["user"])
assert user is not None
assert user.is_active
assert user.system_generated
assert not user.is_admin
assert user.name == "Voice over IP"
assert user.groups == snapshot
assert len(user.credentials) == 0
assert len(user.refresh_tokens) == 0
await hass.config_entries.async_remove(config_entry.entry_id)
assert await hass.auth.async_get_user(user.id) is None

View File

@ -6,7 +6,7 @@ import async_timeout
from homeassistant.components import assist_pipeline, voip
from homeassistant.components.voip.devices import VoIPDevice
from homeassistant.core import HomeAssistant
from homeassistant.core import Context, HomeAssistant
from homeassistant.setup import async_setup_component
_ONE_SECOND = 16000 * 2 # 16Khz 16-bit
@ -86,6 +86,7 @@ async def test_pipeline(
hass,
hass.config.language,
voip_device,
Context(),
listening_tone_enabled=False,
)
rtp_protocol.transport = Mock()
@ -133,6 +134,7 @@ async def test_pipeline_timeout(hass: HomeAssistant, voip_device: VoIPDevice) ->
hass,
hass.config.language,
voip_device,
Context(),
pipeline_timeout=0.001,
listening_tone_enabled=False,
)
@ -170,6 +172,7 @@ async def test_stt_stream_timeout(hass: HomeAssistant, voip_device: VoIPDevice)
hass,
hass.config.language,
voip_device,
Context(),
audio_timeout=0.001,
listening_tone_enabled=False,
)