mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Use header URI in Plex config flow (#49915)
This commit is contained in:
parent
a2138a7642
commit
37e8571fe8
@ -10,6 +10,7 @@ import requests.exceptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import http
|
||||
from homeassistant.components.http.view import HomeAssistantView
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.const import (
|
||||
@ -25,7 +26,6 @@ from homeassistant.const import (
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.network import get_url
|
||||
|
||||
from .const import (
|
||||
AUTH_CALLBACK_NAME,
|
||||
@ -52,6 +52,8 @@ from .const import (
|
||||
from .errors import NoServersFound, ServerNotSpecified
|
||||
from .server import PlexServer
|
||||
|
||||
HEADER_FRONTEND_BASE = "HA-Frontend-Base"
|
||||
|
||||
_LOGGER = logging.getLogger(__package__)
|
||||
|
||||
|
||||
@ -286,7 +288,11 @@ class PlexFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_plex_website_auth(self):
|
||||
"""Begin external auth flow on Plex website."""
|
||||
self.hass.http.register_view(PlexAuthorizationCallbackView)
|
||||
hass_url = get_url(self.hass)
|
||||
if (req := http.current_request.get()) is None:
|
||||
raise RuntimeError("No current request in context")
|
||||
if (hass_url := req.headers.get(HEADER_FRONTEND_BASE)) is None:
|
||||
raise RuntimeError("No header in request")
|
||||
|
||||
headers = {"Origin": hass_url}
|
||||
payload = {
|
||||
"X-Plex-Device-Name": X_PLEX_DEVICE_NAME,
|
||||
|
@ -4,6 +4,7 @@ import ssl
|
||||
from unittest.mock import patch
|
||||
|
||||
import plexapi.exceptions
|
||||
import pytest
|
||||
import requests.exceptions
|
||||
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
@ -21,7 +22,6 @@ from homeassistant.components.plex.const import (
|
||||
PLEX_SERVER_CONFIG,
|
||||
SERVERS,
|
||||
)
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.config_entries import (
|
||||
ENTRY_STATE_LOADED,
|
||||
SOURCE_INTEGRATION_DISCOVERY,
|
||||
@ -45,13 +45,8 @@ from .mock_classes import MockGDM
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_bad_credentials(hass):
|
||||
async def test_bad_credentials(hass, current_request_with_host):
|
||||
"""Test when provided credentials are rejected."""
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -78,13 +73,8 @@ async def test_bad_credentials(hass):
|
||||
assert result["errors"][CONF_TOKEN] == "faulty_credentials"
|
||||
|
||||
|
||||
async def test_bad_hostname(hass, mock_plex_calls):
|
||||
async def test_bad_hostname(hass, mock_plex_calls, current_request_with_host):
|
||||
"""Test when an invalid address is provided."""
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -112,13 +102,8 @@ async def test_bad_hostname(hass, mock_plex_calls):
|
||||
assert result["errors"][CONF_HOST] == "not_found"
|
||||
|
||||
|
||||
async def test_unknown_exception(hass):
|
||||
async def test_unknown_exception(hass, current_request_with_host):
|
||||
"""Test when an unknown exception is encountered."""
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -141,15 +126,12 @@ async def test_unknown_exception(hass):
|
||||
assert result["reason"] == "unknown"
|
||||
|
||||
|
||||
async def test_no_servers_found(hass, mock_plex_calls, requests_mock, empty_payload):
|
||||
async def test_no_servers_found(
|
||||
hass, mock_plex_calls, requests_mock, empty_payload, current_request_with_host
|
||||
):
|
||||
"""Test when no servers are on an account."""
|
||||
requests_mock.get("https://plex.tv/api/resources", text=empty_payload)
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -173,14 +155,10 @@ async def test_no_servers_found(hass, mock_plex_calls, requests_mock, empty_payl
|
||||
assert result["errors"]["base"] == "no_servers"
|
||||
|
||||
|
||||
async def test_single_available_server(hass, mock_plex_calls):
|
||||
async def test_single_available_server(
|
||||
hass, mock_plex_calls, current_request_with_host
|
||||
):
|
||||
"""Test creating an entry with one server available."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -217,15 +195,13 @@ async def test_single_available_server(hass, mock_plex_calls):
|
||||
|
||||
|
||||
async def test_multiple_servers_with_selection(
|
||||
hass, mock_plex_calls, requests_mock, plextv_resources_base
|
||||
hass,
|
||||
mock_plex_calls,
|
||||
requests_mock,
|
||||
plextv_resources_base,
|
||||
current_request_with_host,
|
||||
):
|
||||
"""Test creating an entry with multiple servers available."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -273,15 +249,13 @@ async def test_multiple_servers_with_selection(
|
||||
|
||||
|
||||
async def test_adding_last_unconfigured_server(
|
||||
hass, mock_plex_calls, requests_mock, plextv_resources_base
|
||||
hass,
|
||||
mock_plex_calls,
|
||||
requests_mock,
|
||||
plextv_resources_base,
|
||||
current_request_with_host,
|
||||
):
|
||||
"""Test automatically adding last unconfigured server when multiple servers on account."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
@ -331,15 +305,14 @@ async def test_adding_last_unconfigured_server(
|
||||
|
||||
|
||||
async def test_all_available_servers_configured(
|
||||
hass, entry, requests_mock, plextv_account, plextv_resources_base
|
||||
hass,
|
||||
entry,
|
||||
requests_mock,
|
||||
plextv_account,
|
||||
plextv_resources_base,
|
||||
current_request_with_host,
|
||||
):
|
||||
"""Test when all available servers are already configured."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
MockConfigEntry(
|
||||
@ -470,14 +443,8 @@ async def test_option_flow_new_users_available(hass, entry, setup_plex_server):
|
||||
assert "[New]" in multiselect_defaults[user]
|
||||
|
||||
|
||||
async def test_external_timed_out(hass):
|
||||
async def test_external_timed_out(hass, current_request_with_host):
|
||||
"""Test when external flow times out."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -500,14 +467,8 @@ async def test_external_timed_out(hass):
|
||||
assert result["reason"] == "token_request_timeout"
|
||||
|
||||
|
||||
async def test_callback_view(hass, aiohttp_client):
|
||||
async def test_callback_view(hass, aiohttp_client, current_request_with_host):
|
||||
"""Test callback view."""
|
||||
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@ -529,12 +490,8 @@ async def test_callback_view(hass, aiohttp_client):
|
||||
assert resp.status == 200
|
||||
|
||||
|
||||
async def test_manual_config(hass, mock_plex_calls):
|
||||
async def test_manual_config(hass, mock_plex_calls, current_request_with_host):
|
||||
"""Test creating via manual configuration."""
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
class WrongCertValidaitionException(requests.exceptions.SSLError):
|
||||
"""Mock the exception showing an unmatched error."""
|
||||
@ -744,13 +701,11 @@ async def test_integration_discovery(hass):
|
||||
assert flow["step_id"] == "user"
|
||||
|
||||
|
||||
async def test_trigger_reauth(hass, entry, mock_plex_server, mock_websocket):
|
||||
async def test_trigger_reauth(
|
||||
hass, entry, mock_plex_server, mock_websocket, current_request_with_host
|
||||
):
|
||||
"""Test setup and reauthorization of a Plex token."""
|
||||
await async_setup_component(hass, "persistent_notification", {})
|
||||
await async_process_ha_core_config(
|
||||
hass,
|
||||
{"internal_url": "http://example.local:8123"},
|
||||
)
|
||||
|
||||
assert entry.state == ENTRY_STATE_LOADED
|
||||
|
||||
@ -791,3 +746,43 @@ async def test_trigger_reauth(hass, entry, mock_plex_server, mock_websocket):
|
||||
assert entry.data[CONF_SERVER_IDENTIFIER] == mock_plex_server.machine_identifier
|
||||
assert entry.data[PLEX_SERVER_CONFIG][CONF_URL] == PLEX_DIRECT_URL
|
||||
assert entry.data[PLEX_SERVER_CONFIG][CONF_TOKEN] == "BRAND_NEW_TOKEN"
|
||||
|
||||
|
||||
async def test_client_request_missing(hass):
|
||||
"""Test when client headers are not set properly."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
with patch("plexauth.PlexAuth.initiate_auth"), patch(
|
||||
"plexauth.PlexAuth.token", return_value=None
|
||||
):
|
||||
with pytest.raises(RuntimeError):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
|
||||
|
||||
async def test_client_header_issues(hass, current_request_with_host):
|
||||
"""Test when client headers are not set properly."""
|
||||
|
||||
class MockRequest:
|
||||
headers = {}
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
with patch("plexauth.PlexAuth.initiate_auth"), patch(
|
||||
"plexauth.PlexAuth.token", return_value=None
|
||||
), patch(
|
||||
"homeassistant.components.http.current_request.get", return_value=MockRequest()
|
||||
):
|
||||
with pytest.raises(RuntimeError):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user