Ask Google for the calendar access the entry is set to (#180612)

This commit is contained in:
Franck Nijhof
2026-08-29 20:20:28 -07:00
committed by GitHub
parent e4455e9626
commit 26f6b47c31
2 changed files with 65 additions and 7 deletions
+12 -7
View File
@@ -86,12 +86,22 @@ class OAuth2FlowHandler(
"""Return logger."""
return logging.getLogger(__name__)
@property
def _calendar_access(self) -> FeatureAccess:
"""Return the access the entry being authorized asks for."""
if self.source == SOURCE_REAUTH and (
reauth_options := self._get_reauth_entry().options
):
return FeatureAccess[reauth_options[CONF_CALENDAR_ACCESS]]
return DEFAULT_FEATURE_ACCESS
@property
@override
def extra_authorize_data(self) -> dict[str, Any]:
"""Extra data that needs to be appended to the authorize url."""
return {
"scope": DEFAULT_FEATURE_ACCESS.scope,
"scope": self._calendar_access.scope,
# Add params to ensure we get back a refresh token
"access_type": "offline",
"prompt": "consent",
@@ -121,17 +131,12 @@ class OAuth2FlowHandler(
self.flow_impl,
)
return self.async_abort(reason="oauth_error")
calendar_access = DEFAULT_FEATURE_ACCESS
if self.source == SOURCE_REAUTH and (
reauth_options := self._get_reauth_entry().options
):
calendar_access = FeatureAccess[reauth_options[CONF_CALENDAR_ACCESS]]
try:
device_flow = await async_create_device_flow(
self.hass,
self.flow_impl.client_id,
self.flow_impl.client_secret,
calendar_access,
self._calendar_access,
)
except TimeoutError as err:
_LOGGER.error("Timeout initializing device flow: %s", str(err))
@@ -740,6 +740,59 @@ async def test_web_auth_compatibility(
assert len(mock_setup.mock_calls) == 1
@pytest.mark.parametrize(
("options", "expected_scope"),
[
({}, "https://www.googleapis.com/auth/calendar"),
(
{CONF_CALENDAR_ACCESS: FeatureAccess.read_write.name},
"https://www.googleapis.com/auth/calendar",
),
(
{CONF_CALENDAR_ACCESS: FeatureAccess.read_only.name},
"https://www.googleapis.com/auth/calendar.readonly",
),
],
)
async def test_web_reauth_flow_asks_for_configured_access(
hass: HomeAssistant,
mock_code_flow: Mock,
options: dict[str, Any],
expected_scope: str,
) -> None:
"""Test reauth asks for the access the entry is configured for."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_CREDENTIAL_TYPE: CredentialType.WEB_AUTH,
"auth_implementation": DOMAIN,
"token": {"access_token": "OLD_ACCESS_TOKEN"},
},
options=options,
)
config_entry.add_to_hass(hass)
await async_import_client_credential(
hass, DOMAIN, ClientCredential(CLIENT_ID, CLIENT_SECRET)
)
result = await config_entry.start_reauth_flow(hass)
assert result["step_id"] == "reauth_confirm"
with patch(
"homeassistant.components.google.api.OAuth2WebServerFlow.step1_get_device_and_user_codes",
side_effect=OAuth2DeviceCodeError(
"Invalid response 401. Error: invalid_client"
),
):
result = await hass.config_entries.flow.async_configure(
flow_id=result["flow_id"],
user_input={},
)
assert result.get("type") is FlowResultType.EXTERNAL_STEP
assert f"&scope={expected_scope}&" in result["url"]
@pytest.mark.parametrize(
"entry_data",
[