Adjust logic for per-backup agent encryption (#137420)

This commit is contained in:
Erik Montnemery 2025-02-05 12:14:06 +01:00 committed by GitHub
parent 28cedc4c13
commit 2f116eab9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 3 deletions

View File

@ -1439,7 +1439,11 @@ class CoreBackupReaderWriter(BackupReaderWriter):
manager = self._hass.data[DATA_MANAGER] manager = self._hass.data[DATA_MANAGER]
agent_config = manager.config.data.agents.get(self._local_agent_id) agent_config = manager.config.data.agents.get(self._local_agent_id)
if agent_config and not agent_config.protected: if (
self._local_agent_id in agent_ids
and agent_config
and not agent_config.protected
):
password = None password = None
backup = AgentBackup( backup = AgentBackup(

View File

@ -46,6 +46,7 @@ from homeassistant.components.backup.manager import (
RestoreBackupState, RestoreBackupState,
WrittenBackup, WrittenBackup,
) )
from homeassistant.components.backup.util import password_to_key
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import issue_registry as ir from homeassistant.helpers import issue_registry as ir
@ -3207,17 +3208,21 @@ async def test_restore_backup_file_error(
@pytest.mark.parametrize( @pytest.mark.parametrize(
("commands", "password", "protected_backup"), ("commands", "agent_ids", "password", "protected_backup", "inner_tar_key"),
[ [
( (
[], [],
["backup.local", "test.remote"],
None, None,
{"backup.local": False, "test.remote": False}, {"backup.local": False, "test.remote": False},
None,
), ),
( (
[], [],
["backup.local", "test.remote"],
"hunter2", "hunter2",
{"backup.local": True, "test.remote": True}, {"backup.local": True, "test.remote": True},
password_to_key("hunter2"),
), ),
( (
[ [
@ -3229,8 +3234,10 @@ async def test_restore_backup_file_error(
}, },
} }
], ],
["backup.local", "test.remote"],
"hunter2", "hunter2",
{"backup.local": False, "test.remote": False}, {"backup.local": False, "test.remote": False},
None, # None of the agents are protected
), ),
( (
[ [
@ -3242,8 +3249,10 @@ async def test_restore_backup_file_error(
}, },
} }
], ],
["backup.local", "test.remote"],
"hunter2", "hunter2",
{"backup.local": False, "test.remote": True}, {"backup.local": False, "test.remote": True},
None, # Local agent is not protected
), ),
( (
[ [
@ -3255,8 +3264,10 @@ async def test_restore_backup_file_error(
}, },
} }
], ],
["backup.local", "test.remote"],
"hunter2", "hunter2",
{"backup.local": True, "test.remote": False}, {"backup.local": True, "test.remote": False},
password_to_key("hunter2"), # Local agent is protected
), ),
( (
[ [
@ -3268,8 +3279,10 @@ async def test_restore_backup_file_error(
}, },
} }
], ],
["backup.local", "test.remote"],
"hunter2", "hunter2",
{"backup.local": True, "test.remote": True}, {"backup.local": True, "test.remote": True},
password_to_key("hunter2"),
), ),
( (
[ [
@ -3281,8 +3294,40 @@ async def test_restore_backup_file_error(
}, },
} }
], ],
["backup.local", "test.remote"],
None, None,
{"backup.local": False, "test.remote": False}, {"backup.local": False, "test.remote": False},
None, # No password supplied
),
(
[
{
"type": "backup/config/update",
"agents": {
"backup.local": {"protected": False},
"test.remote": {"protected": True},
},
}
],
["test.remote"],
"hunter2",
{"test.remote": True},
password_to_key("hunter2"),
),
(
[
{
"type": "backup/config/update",
"agents": {
"backup.local": {"protected": False},
"test.remote": {"protected": False},
},
}
],
["test.remote"],
"hunter2",
{"test.remote": False},
password_to_key("hunter2"), # Temporary backup protected when password set
), ),
], ],
) )
@ -3291,13 +3336,15 @@ async def test_initiate_backup_per_agent_encryption(
hass: HomeAssistant, hass: HomeAssistant,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
generate_backup_id: MagicMock, generate_backup_id: MagicMock,
mocked_tarfile: Mock,
path_glob: MagicMock, path_glob: MagicMock,
commands: dict[str, Any], commands: dict[str, Any],
agent_ids: list[str],
password: str | None, password: str | None,
protected_backup: dict[str, bool], protected_backup: dict[str, bool],
inner_tar_key: bytes | None,
) -> None: ) -> None:
"""Test generate backup where encryption is selectively set on agents.""" """Test generate backup where encryption is selectively set on agents."""
agent_ids = ["backup.local", "test.remote"]
local_agent = local_backup_platform.CoreLocalBackupAgent(hass) local_agent = local_backup_platform.CoreLocalBackupAgent(hass)
remote_agent = BackupAgentTest("remote", backups=[]) remote_agent = BackupAgentTest("remote", backups=[])
@ -3373,6 +3420,10 @@ async def test_initiate_backup_per_agent_encryption(
await hass.async_block_till_done() await hass.async_block_till_done()
mocked_tarfile.return_value.create_inner_tar.assert_called_once_with(
ANY, gzip=True, key=inner_tar_key
)
result = await ws_client.receive_json() result = await ws_client.receive_json()
assert result["event"] == { assert result["event"] == {
"manager_state": BackupManagerState.CREATE_BACKUP, "manager_state": BackupManagerState.CREATE_BACKUP,