mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-07-16 21:56:29 +00:00
Fix fallback to non-SSL whoami call (#4751)
* Fix fallback to non-SSL whoami call In case of an exception "data" is not set leading to an error: cannot access local variable 'data' where it is not associated with a value Make sure to fallback to the non-SSL whoami call properly. * Add pytests * Ignore protected access in pytests * Add test when system time is behind by more than 3 days * Fix test_adjust_system_datetime_if_time_behind test and cleanup
This commit is contained in:
parent
c64744dedf
commit
7fef92c480
@ -28,7 +28,7 @@ from .homeassistant.core import LANDINGPAGE
|
|||||||
from .resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
from .resolution.const import ContextType, IssueType, SuggestionType, UnhealthyReason
|
||||||
from .utils.dt import utcnow
|
from .utils.dt import utcnow
|
||||||
from .utils.sentry import capture_exception
|
from .utils.sentry import capture_exception
|
||||||
from .utils.whoami import retrieve_whoami
|
from .utils.whoami import WhoamiData, retrieve_whoami
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
_LOGGER: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -363,6 +363,13 @@ class Core(CoreSysAttributes):
|
|||||||
self.sys_config.last_boot = self.sys_hardware.helper.last_boot
|
self.sys_config.last_boot = self.sys_hardware.helper.last_boot
|
||||||
self.sys_config.save_data()
|
self.sys_config.save_data()
|
||||||
|
|
||||||
|
async def _retrieve_whoami(self, with_ssl: bool) -> WhoamiData | None:
|
||||||
|
try:
|
||||||
|
return await retrieve_whoami(self.sys_websession, with_ssl)
|
||||||
|
except WhoamiSSLError:
|
||||||
|
_LOGGER.info("Whoami service SSL error")
|
||||||
|
return None
|
||||||
|
|
||||||
async def _adjust_system_datetime(self):
|
async def _adjust_system_datetime(self):
|
||||||
"""Adjust system time/date on startup."""
|
"""Adjust system time/date on startup."""
|
||||||
# If no timezone is detect or set
|
# If no timezone is detect or set
|
||||||
@ -375,21 +382,15 @@ class Core(CoreSysAttributes):
|
|||||||
|
|
||||||
# Get Timezone data
|
# Get Timezone data
|
||||||
try:
|
try:
|
||||||
data = await retrieve_whoami(self.sys_websession)
|
data = await self._retrieve_whoami(True)
|
||||||
except WhoamiSSLError:
|
|
||||||
pass
|
# SSL Date Issue & possible time drift
|
||||||
|
if not data:
|
||||||
|
data = await self._retrieve_whoami(False)
|
||||||
except WhoamiError as err:
|
except WhoamiError as err:
|
||||||
_LOGGER.warning("Can't adjust Time/Date settings: %s", err)
|
_LOGGER.warning("Can't adjust Time/Date settings: %s", err)
|
||||||
return
|
return
|
||||||
|
|
||||||
# SSL Date Issue & possible time drift
|
|
||||||
if not data:
|
|
||||||
try:
|
|
||||||
data = await retrieve_whoami(self.sys_websession, with_ssl=False)
|
|
||||||
except WhoamiError as err:
|
|
||||||
_LOGGER.error("Can't adjust Time/Date settings: %s", err)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.sys_config.timezone = self.sys_config.timezone or data.timezone
|
self.sys_config.timezone = self.sys_config.timezone or data.timezone
|
||||||
|
|
||||||
# Calculate if system time is out of sync
|
# Calculate if system time is out of sync
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
"""Testing handling with CoreState."""
|
"""Testing handling with CoreState."""
|
||||||
|
# pylint: disable=W0212
|
||||||
|
import datetime
|
||||||
|
from unittest.mock import AsyncMock, PropertyMock, patch
|
||||||
|
|
||||||
from supervisor.const import CoreState
|
from supervisor.const import CoreState
|
||||||
from supervisor.coresys import CoreSys
|
from supervisor.coresys import CoreSys
|
||||||
|
from supervisor.exceptions import WhoamiSSLError
|
||||||
|
from supervisor.host.control import SystemControl
|
||||||
|
from supervisor.host.info import InfoCenter
|
||||||
|
from supervisor.supervisor import Supervisor
|
||||||
|
from supervisor.utils.whoami import WhoamiData
|
||||||
|
|
||||||
|
|
||||||
def test_write_state(run_dir, coresys: CoreSys):
|
def test_write_state(run_dir, coresys: CoreSys):
|
||||||
@ -14,3 +22,58 @@ def test_write_state(run_dir, coresys: CoreSys):
|
|||||||
coresys.core.state = CoreState.SHUTDOWN
|
coresys.core.state = CoreState.SHUTDOWN
|
||||||
|
|
||||||
assert run_dir.read_text() == CoreState.SHUTDOWN
|
assert run_dir.read_text() == CoreState.SHUTDOWN
|
||||||
|
|
||||||
|
|
||||||
|
async def test_adjust_system_datetime(coresys: CoreSys):
|
||||||
|
"""Test _adjust_system_datetime method with successful retrieve_whoami."""
|
||||||
|
utc_ts = datetime.datetime.now().replace(tzinfo=datetime.UTC)
|
||||||
|
with patch(
|
||||||
|
"supervisor.core.retrieve_whoami",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
side_effect=[WhoamiData("Europe/Zurich", utc_ts)],
|
||||||
|
) as mock_retrieve_whoami:
|
||||||
|
await coresys.core._adjust_system_datetime()
|
||||||
|
mock_retrieve_whoami.assert_called_once()
|
||||||
|
assert coresys.core.sys_config.timezone == "Europe/Zurich"
|
||||||
|
|
||||||
|
# Validate we don't retrieve whoami once timezone has been set
|
||||||
|
mock_retrieve_whoami.reset_mock()
|
||||||
|
await coresys.core._adjust_system_datetime()
|
||||||
|
mock_retrieve_whoami.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_adjust_system_datetime_without_ssl(coresys: CoreSys):
|
||||||
|
"""Test _adjust_system_datetime method when retrieve_whoami raises WhoamiSSLError."""
|
||||||
|
utc_ts = datetime.datetime.now().replace(tzinfo=datetime.UTC)
|
||||||
|
with patch(
|
||||||
|
"supervisor.core.retrieve_whoami",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
side_effect=[WhoamiSSLError("SSL error"), WhoamiData("Europe/Zurich", utc_ts)],
|
||||||
|
) as mock_retrieve_whoami:
|
||||||
|
await coresys.core._adjust_system_datetime()
|
||||||
|
assert mock_retrieve_whoami.call_count == 2
|
||||||
|
assert mock_retrieve_whoami.call_args_list[0].args[1]
|
||||||
|
assert not mock_retrieve_whoami.call_args_list[1].args[1]
|
||||||
|
assert coresys.core.sys_config.timezone == "Europe/Zurich"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_adjust_system_datetime_if_time_behind(coresys: CoreSys):
|
||||||
|
"""Test _adjust_system_datetime method when current time is ahead more than 3 days."""
|
||||||
|
utc_ts = datetime.datetime.now().replace(tzinfo=datetime.UTC) + datetime.timedelta(
|
||||||
|
days=4
|
||||||
|
)
|
||||||
|
with patch(
|
||||||
|
"supervisor.core.retrieve_whoami",
|
||||||
|
new_callable=AsyncMock,
|
||||||
|
side_effect=[WhoamiData("Europe/Zurich", utc_ts)],
|
||||||
|
) as mock_retrieve_whoami, patch.object(
|
||||||
|
SystemControl, "set_datetime"
|
||||||
|
) as mock_set_datetime, patch.object(
|
||||||
|
InfoCenter, "dt_synchronized", new=PropertyMock(return_value=False)
|
||||||
|
), patch.object(
|
||||||
|
Supervisor, "check_connectivity"
|
||||||
|
) as mock_check_connectivity:
|
||||||
|
await coresys.core._adjust_system_datetime()
|
||||||
|
mock_retrieve_whoami.assert_called_once()
|
||||||
|
mock_set_datetime.assert_called_once()
|
||||||
|
mock_check_connectivity.assert_called_once()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user