From 51e409c1c73cceb10027f350e1baca1ea1ea5c36 Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 17 Oct 2024 11:25:09 +0200 Subject: [PATCH] Check all services --- homeassistant/core.py | 4 ++++ homeassistant/helpers/config_validation.py | 25 +++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/homeassistant/core.py b/homeassistant/core.py index cdfb5570b44..9b210e1ca28 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -2610,6 +2610,10 @@ class ServiceRegistry: This method must be run in the event loop. """ + # pylint: disable-next=import-outside-toplevel + from .helpers import config_validation as cv + + cv.raise_on_templated_service(domain, service, schema) domain = domain.lower() service = service.lower() service_obj = Service( diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index f9d8071f773..66de8266122 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1380,12 +1380,32 @@ def _make_entity_service_schema(schema: dict, extra: int) -> VolSchemaType: BASE_ENTITY_SCHEMA = _make_entity_service_schema({}, vol.PREVENT_EXTRA) -def _raise_on_templated_service(schema: VolDictType | None) -> None: +def _raise_on_templated_service( + domain: str, _service: str, schema: VolDictType | None +) -> None: if not schema: return for key, val in schema.items(): if val in (dynamic_template, template, template_complex): - raise ValueError(f"Template in service data is not allowed! {key}") + raise ValueError( + f"Template in service data is not allowed! {domain}.{_service}:{key}" + ) + + +def raise_on_templated_service( + domain: str, _service: str, schema: VolDictType | VolSchemaType | None +) -> None: + """Raise if service schema explicitly allows templates.""" + if not schema: + return + if isinstance(schema, dict): + _raise_on_templated_service(domain, _service, schema) + return + if isinstance(schema, (vol.All, vol.Any)): + for val in schema.validators: + raise_on_templated_service(domain, _service, val) + if isinstance(schema, (vol.Schema)): + raise_on_templated_service(domain, _service, schema.schema) def make_entity_service_schema( @@ -1397,7 +1417,6 @@ def make_entity_service_schema( # the base schema and avoid compiling a new schema which is the case # for ~50% of services. return BASE_ENTITY_SCHEMA - _raise_on_templated_service(schema) return _make_entity_service_schema(schema or {}, extra)