Add websocket type hints in config (#80532)

pull/80596/head
epenet 2022-10-19 04:15:55 +02:00 committed by GitHub
parent 60640b4436
commit 971ac015e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 28 deletions

View File

@ -1,7 +1,10 @@
"""Offer API to configure Home Assistant auth."""
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant
WS_TYPE_LIST = "config/auth/list"
SCHEMA_WS_LIST = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
@ -29,7 +32,11 @@ async def async_setup(hass):
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_list(hass, connection, msg):
async def websocket_list(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Return a list of users."""
result = [_user_info(u) for u in await hass.auth.async_get_users()]
@ -38,7 +45,11 @@ async def websocket_list(hass, connection, msg):
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_delete(hass, connection, msg):
async def websocket_delete(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Delete a user."""
if msg["user_id"] == connection.user.id:
connection.send_message(
@ -69,7 +80,11 @@ async def websocket_delete(hass, connection, msg):
}
)
@websocket_api.async_response
async def websocket_create(hass, connection, msg):
async def websocket_create(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Create a user."""
user = await hass.auth.async_create_user(
msg["name"], group_ids=msg.get("group_ids"), local_only=msg.get("local_only")
@ -92,7 +107,11 @@ async def websocket_create(hass, connection, msg):
}
)
@websocket_api.async_response
async def websocket_update(hass, connection, msg):
async def websocket_update(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Update a user."""
if not (user := await hass.auth.async_get_user(msg.pop("user_id"))):
connection.send_message(

View File

@ -1,9 +1,11 @@
"""Offer API to configure the Home Assistant auth provider."""
from typing import Any
import voluptuous as vol
from homeassistant.auth.providers import homeassistant as auth_ha
from homeassistant.components import websocket_api
from homeassistant.components.websocket_api import decorators
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import Unauthorized
@ -16,7 +18,7 @@ async def async_setup(hass):
return True
@decorators.websocket_command(
@websocket_api.websocket_command(
{
vol.Required("type"): "config/auth_provider/homeassistant/create",
vol.Required("user_id"): str,
@ -26,7 +28,11 @@ async def async_setup(hass):
)
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_create(hass, connection, msg):
async def websocket_create(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Create credentials and attach to a user."""
provider = auth_ha.async_get_provider(hass)
@ -56,7 +62,7 @@ async def websocket_create(hass, connection, msg):
connection.send_result(msg["id"])
@decorators.websocket_command(
@websocket_api.websocket_command(
{
vol.Required("type"): "config/auth_provider/homeassistant/delete",
vol.Required("username"): str,
@ -64,7 +70,11 @@ async def websocket_create(hass, connection, msg):
)
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_delete(hass, connection, msg):
async def websocket_delete(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Delete username and related credential."""
provider = auth_ha.async_get_provider(hass)
credentials = await provider.async_get_or_create_credentials(
@ -90,7 +100,7 @@ async def websocket_delete(hass, connection, msg):
connection.send_result(msg["id"])
@decorators.websocket_command(
@websocket_api.websocket_command(
{
vol.Required("type"): "config/auth_provider/homeassistant/change_password",
vol.Required("current_password"): str,
@ -98,7 +108,11 @@ async def websocket_delete(hass, connection, msg):
}
)
@websocket_api.async_response
async def websocket_change_password(hass, connection, msg):
async def websocket_change_password(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Change current user password."""
if (user := connection.user) is None:
connection.send_error(msg["id"], "user_not_found", "User not found")
@ -130,7 +144,7 @@ async def websocket_change_password(hass, connection, msg):
connection.send_result(msg["id"])
@decorators.websocket_command(
@websocket_api.websocket_command(
{
vol.Required(
"type"
@ -139,9 +153,13 @@ async def websocket_change_password(hass, connection, msg):
vol.Required("password"): str,
}
)
@decorators.require_admin
@decorators.async_response
async def websocket_admin_change_password(hass, connection, msg):
@websocket_api.require_admin
@websocket_api.async_response
async def websocket_admin_change_password(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Change password of any user."""
if not connection.user.is_owner:
raise Unauthorized(context=connection.context(msg))

View File

@ -13,7 +13,6 @@ from homeassistant import config_entries, data_entry_flow
from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT
from homeassistant.components import websocket_api
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.websocket_api.connection import ActiveConnection
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import DependencyError, Unauthorized
from homeassistant.helpers.data_entry_flow import (
@ -291,7 +290,11 @@ def get_entry(
}
)
@websocket_api.async_response
async def config_entry_update(hass, connection, msg):
async def config_entry_update(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Update config entry."""
changes = dict(msg)
changes.pop("id")
@ -311,9 +314,10 @@ async def config_entry_update(hass, connection, msg):
"require_restart": False,
}
initial_state = entry.state
if (
old_disable_polling != entry.pref_disable_polling
and entry.state is config_entries.ConfigEntryState.LOADED
and initial_state is config_entries.ConfigEntryState.LOADED
):
if not await hass.config_entries.async_reload(entry.entry_id):
result["require_restart"] = (
@ -334,14 +338,18 @@ async def config_entry_update(hass, connection, msg):
}
)
@websocket_api.async_response
async def config_entry_disable(hass, connection, msg):
async def config_entry_disable(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Disable config entry."""
if (disabled_by := msg["disabled_by"]) is not None:
disabled_by = config_entries.ConfigEntryDisabler(disabled_by)
result = False
success = False
try:
result = await hass.config_entries.async_set_disabled_by(
success = await hass.config_entries.async_set_disabled_by(
msg["entry_id"], disabled_by
)
except config_entries.OperationNotAllowed:
@ -351,7 +359,7 @@ async def config_entry_disable(hass, connection, msg):
send_entry_not_found(connection, msg["id"])
return
result = {"require_restart": not result}
result = {"require_restart": not success}
connection.send_result(msg["id"], result)
@ -361,7 +369,11 @@ async def config_entry_disable(hass, connection, msg):
{"type": "config_entries/ignore_flow", "flow_id": str, "title": str}
)
@websocket_api.async_response
async def ignore_config_flow(hass, connection, msg):
async def ignore_config_flow(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Ignore a config flow."""
flow = next(
(
@ -399,7 +411,9 @@ async def ignore_config_flow(hass, connection, msg):
)
@websocket_api.async_response
async def config_entries_get(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Return matching config entries by type and/or domain."""
connection.send_result(
@ -418,7 +432,9 @@ async def config_entries_get(
)
@websocket_api.async_response
async def config_entries_subscribe(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Subscribe to config entry updates."""
type_filter = msg.get("type_filter")

View File

@ -1,10 +1,13 @@
"""Component to interact with Hassbian tools."""
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.components.http import HomeAssistantView
from homeassistant.config import async_check_ha_config_file
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import location, unit_system
@ -49,7 +52,11 @@ class CheckConfigView(HomeAssistantView):
}
)
@websocket_api.async_response
async def websocket_update_config(hass, connection, msg):
async def websocket_update_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Handle update core config command."""
data = dict(msg)
data.pop("id")
@ -65,12 +72,16 @@ async def websocket_update_config(hass, connection, msg):
@websocket_api.require_admin
@websocket_api.websocket_command({"type": "config/core/detect"})
@websocket_api.async_response
async def websocket_detect_config(hass, connection, msg):
async def websocket_detect_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Detect core config."""
session = async_get_clientsession(hass)
location_info = await location.async_detect_location_info(session)
info = {}
info: dict[str, Any] = {}
if location_info is None:
connection.send_result(msg["id"], info)