diff --git a/homeassistant/backup_restore.py b/homeassistant/backup_restore.py index c42cc900a7b0df..24ad411ec91911 100644 --- a/homeassistant/backup_restore.py +++ b/homeassistant/backup_restore.py @@ -28,10 +28,8 @@ class RestoreBackupFileContent: password: str | None = None -def password_to_key(password: str | None) -> bytes | None: +def password_to_key(password: str) -> bytes: """Generate a AES Key from password.""" - if password is None: - return None key: bytes = password.encode() for _ in range(100): key = hashlib.sha256(key).digest() @@ -105,7 +103,7 @@ def _extract_backup( f"homeassistant.tar{'.gz' if backup_meta["compressed"] else ''}", ), gzip=backup_meta["compressed"], - key=password_to_key(password), + key=password_to_key(password) if password is not None else None, mode="r", ) as istf: istf.extractall( diff --git a/homeassistant/components/backup/manager.py b/homeassistant/components/backup/manager.py index 1734194cb79cd1..59b621957524e7 100644 --- a/homeassistant/components/backup/manager.py +++ b/homeassistant/components/backup/manager.py @@ -129,6 +129,7 @@ async def load_platforms(self) -> None: async def async_restore_backup( self, slug: str, + *, password: str | None = None, **kwargs: Any, ) -> None: @@ -137,6 +138,7 @@ async def async_restore_backup( @abc.abstractmethod async def async_create_backup( self, + *, password: str | None = None, **kwargs: Any, ) -> Backup: @@ -235,6 +237,7 @@ async def async_remove_backup(self, *, slug: str, **kwargs: Any) -> None: async def async_create_backup( self, + *, password: str | None = None, **kwargs: Any, ) -> Backup: @@ -308,7 +311,7 @@ def _mkdir_and_generate_backup_contents( with outer_secure_tarfile.create_inner_tar( "./homeassistant.tar.gz", gzip=True, - key=password_to_key(password=password), + key=password_to_key(password) if password is not None else None, ) as core_tar: atomic_contents_add( tar_file=core_tar, @@ -321,6 +324,7 @@ def _mkdir_and_generate_backup_contents( async def async_restore_backup( self, slug: str, + *, password: str | None = None, **kwargs: Any, ) -> None: diff --git a/tests/test_backup_restore.py b/tests/test_backup_restore.py index e5b6dfbfba5e0e..7f69d4db728a96 100644 --- a/tests/test_backup_restore.py +++ b/tests/test_backup_restore.py @@ -236,7 +236,6 @@ def _patched_path_read_text(path: Path, **kwargs): @pytest.mark.parametrize( ("password", "expected"), [ - (None, None), ("test", b"\xf0\x9b\xb9\x1f\xdc,\xff\xd5x\xd6\xd6\x8fz\x19.\x0f"), ("lorem ipsum...", b"#\xe0\xfc\xe0\xdb?_\x1f,$\rQ\xf4\xf5\xd8\xfb"), ], @@ -244,3 +243,17 @@ def _patched_path_read_text(path: Path, **kwargs): def test_pw_to_key(password: str | None, expected: bytes | None) -> None: """Test password to key conversion.""" assert backup_restore.password_to_key(password) == expected + + +@pytest.mark.parametrize( + ("password", "expected"), + [ + (None, None), + ("test", b"\xf0\x9b\xb9\x1f\xdc,\xff\xd5x\xd6\xd6\x8fz\x19.\x0f"), + ("lorem ipsum...", b"#\xe0\xfc\xe0\xdb?_\x1f,$\rQ\xf4\xf5\xd8\xfb"), + ], +) +def test_pw_to_key_none(password: str | None, expected: bytes | None) -> None: + """Test password to key conversion.""" + with pytest.raises(AttributeError): + backup_restore.password_to_key(None)