mirror of
https://github.com/home-assistant/core.git
synced 2026-09-16 13:38:26 +01:00
Require admin for the mqtt.publish and mqtt.dump actions (#182045)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: frenck <195327+frenck@users.noreply.github.com>
This commit is contained in:
co-authored by
copilot-swe-agent[bot]
frenck
parent
7ee22de22c
commit
ce436dda45
@@ -370,8 +370,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
message_expiry_interval=message_expiry_interval,
|
||||
)
|
||||
|
||||
hass.services.async_register(
|
||||
DOMAIN, SERVICE_PUBLISH, async_publish_service, schema=MQTT_PUBLISH_SCHEMA
|
||||
async_register_admin_service(
|
||||
hass, DOMAIN, SERVICE_PUBLISH, async_publish_service, MQTT_PUBLISH_SCHEMA
|
||||
)
|
||||
|
||||
async def async_dump_service(call: ServiceCall) -> None:
|
||||
@@ -395,7 +395,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
||||
ev.async_call_later(hass, call.data["duration"], finish_dump)
|
||||
|
||||
hass.services.async_register(
|
||||
async_register_admin_service(
|
||||
hass,
|
||||
DOMAIN,
|
||||
SERVICE_DUMP,
|
||||
async_dump_service,
|
||||
|
||||
@@ -37,7 +37,12 @@ from homeassistant.const import (
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||
from homeassistant.exceptions import (
|
||||
HomeAssistantError,
|
||||
ServiceValidationError,
|
||||
Unauthorized,
|
||||
UnknownUser,
|
||||
)
|
||||
from homeassistant.helpers import (
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
@@ -56,6 +61,7 @@ from tests.common import (
|
||||
MockEntity,
|
||||
MockEntityPlatform,
|
||||
MockMqttReasonCode,
|
||||
MockUser,
|
||||
async_capture_events,
|
||||
async_fire_mqtt_message,
|
||||
async_fire_time_changed,
|
||||
@@ -1113,6 +1119,77 @@ async def test_dump_service(
|
||||
assert writes[0][1][0] == ["bla/1,test1\n", "bla/2,test2\n"]
|
||||
|
||||
|
||||
ADMIN_SERVICE_CALLS = [
|
||||
pytest.param(
|
||||
mqtt.SERVICE_PUBLISH,
|
||||
{mqtt.ATTR_TOPIC: "test/topic", mqtt.ATTR_PAYLOAD: "payload"},
|
||||
id="publish",
|
||||
),
|
||||
pytest.param(mqtt.SERVICE_DUMP, {"topic": "bla/#", "duration": 3}, id="dump"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("service", "service_data"), ADMIN_SERVICE_CALLS)
|
||||
async def test_admin_service_as_admin(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
hass_admin_user: MockUser,
|
||||
service: str,
|
||||
service_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test an admin user can call the action."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
context=ha.Context(user_id=hass_admin_user.id),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("service", "service_data"), ADMIN_SERVICE_CALLS)
|
||||
async def test_admin_service_as_non_admin(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
hass_read_only_user: MockUser,
|
||||
service: str,
|
||||
service_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test a non-admin user cannot call the action."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
with pytest.raises(Unauthorized):
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
context=ha.Context(user_id=hass_read_only_user.id),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("service", "service_data"), ADMIN_SERVICE_CALLS)
|
||||
async def test_admin_service_as_unknown_user(
|
||||
hass: HomeAssistant,
|
||||
mqtt_mock_entry: MqttMockHAClientGenerator,
|
||||
service: str,
|
||||
service_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test a user that no longer exists cannot call the action."""
|
||||
await mqtt_mock_entry()
|
||||
|
||||
with pytest.raises(UnknownUser):
|
||||
await hass.services.async_call(
|
||||
mqtt.DOMAIN,
|
||||
service,
|
||||
service_data,
|
||||
blocking=True,
|
||||
context=ha.Context(user_id="i-am-not-a-user"),
|
||||
)
|
||||
|
||||
|
||||
async def test_mqtt_ws_remove_discovered_device(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
|
||||
Reference in New Issue
Block a user