Refactor SamsungTV auth check (#117834)

This commit is contained in:
epenet
2024-05-21 09:14:17 +02:00
committed by GitHub
parent ae0988209b
commit aaa5df9981
3 changed files with 25 additions and 22 deletions

View File

@@ -10,7 +10,7 @@ from urllib.parse import urlparse
import getmac import getmac
from homeassistant.components import ssdp from homeassistant.components import ssdp
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_HOST,
CONF_MAC, CONF_MAC,
@@ -135,6 +135,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: SamsungTVConfigEntry) ->
) )
bridge = await _async_create_bridge_with_updated_data(hass, entry) bridge = await _async_create_bridge_with_updated_data(hass, entry)
@callback
def _access_denied() -> None:
"""Access denied callback."""
LOGGER.debug("Access denied in getting remote object")
hass.create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"entry_id": entry.entry_id,
},
data=entry.data,
)
)
bridge.register_reauth_callback(_access_denied)
# Ensure updates get saved against the config_entry # Ensure updates get saved against the config_entry
@callback @callback
def _update_config_entry(updates: Mapping[str, Any]) -> None: def _update_config_entry(updates: Mapping[str, Any]) -> None:

View File

@@ -165,6 +165,7 @@ class SamsungTVBridge(ABC):
self.host = host self.host = host
self.token: str | None = None self.token: str | None = None
self.session_id: str | None = None self.session_id: str | None = None
self.auth_failed: bool = False
self._reauth_callback: CALLBACK_TYPE | None = None self._reauth_callback: CALLBACK_TYPE | None = None
self._update_config_entry: Callable[[Mapping[str, Any]], None] | None = None self._update_config_entry: Callable[[Mapping[str, Any]], None] | None = None
self._app_list_callback: Callable[[dict[str, str]], None] | None = None self._app_list_callback: Callable[[dict[str, str]], None] | None = None
@@ -335,6 +336,7 @@ class SamsungTVLegacyBridge(SamsungTVBridge):
# A removed auth will lead to socket timeout because waiting # A removed auth will lead to socket timeout because waiting
# for auth popup is just an open socket # for auth popup is just an open socket
except AccessDenied: except AccessDenied:
self.auth_failed = True
self._notify_reauth_callback() self._notify_reauth_callback()
raise raise
except (ConnectionClosed, OSError): except (ConnectionClosed, OSError):
@@ -607,6 +609,7 @@ class SamsungTVWSBridge(
self.host, self.host,
repr(err), repr(err),
) )
self.auth_failed = True
self._notify_reauth_callback() self._notify_reauth_callback()
self._remote = None self._remote = None
except ConnectionClosedError as err: except ConnectionClosedError as err:

View File

@@ -28,7 +28,7 @@ from homeassistant.components.media_player import (
MediaPlayerState, MediaPlayerState,
MediaType, MediaType,
) )
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
@@ -37,7 +37,7 @@ from homeassistant.util.async_ import create_eager_task
from . import SamsungTVConfigEntry from . import SamsungTVConfigEntry
from .bridge import SamsungTVBridge, SamsungTVWSBridge from .bridge import SamsungTVBridge, SamsungTVWSBridge
from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, DOMAIN, LOGGER from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, LOGGER
from .entity import SamsungTVEntity from .entity import SamsungTVEntity
SOURCES = {"TV": "KEY_TV", "HDMI": "KEY_HDMI"} SOURCES = {"TV": "KEY_TV", "HDMI": "KEY_HDMI"}
@@ -105,8 +105,6 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity):
if self._ssdp_rendering_control_location: if self._ssdp_rendering_control_location:
self._attr_supported_features |= MediaPlayerEntityFeature.VOLUME_SET self._attr_supported_features |= MediaPlayerEntityFeature.VOLUME_SET
self._auth_failed = False
self._bridge.register_reauth_callback(self.access_denied)
self._bridge.register_app_list_callback(self._app_list_callback) self._bridge.register_app_list_callback(self._app_list_callback)
self._dmr_device: DmrDevice | None = None self._dmr_device: DmrDevice | None = None
@@ -132,28 +130,13 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity):
self._update_sources() self._update_sources()
self._app_list_event.set() self._app_list_event.set()
def access_denied(self) -> None:
"""Access denied callback."""
LOGGER.debug("Access denied in getting remote object")
self._auth_failed = True
self.hass.create_task(
self.hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"entry_id": self._config_entry.entry_id,
},
data=self._config_entry.data,
)
)
async def async_will_remove_from_hass(self) -> None: async def async_will_remove_from_hass(self) -> None:
"""Handle removal.""" """Handle removal."""
await self._async_shutdown_dmr() await self._async_shutdown_dmr()
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update state of device.""" """Update state of device."""
if self._auth_failed or self.hass.is_stopping: if self._bridge.auth_failed or self.hass.is_stopping:
return return
old_state = self._attr_state old_state = self._attr_state
if self._bridge.power_off_in_progress: if self._bridge.power_off_in_progress:
@@ -316,7 +299,7 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity):
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return the availability of the device.""" """Return the availability of the device."""
if self._auth_failed: if self._bridge.auth_failed:
return False return False
return ( return (
self.state == MediaPlayerState.ON self.state == MediaPlayerState.ON