Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions homeassistant/components/google/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,22 @@ def logger(self) -> logging.Logger:
"""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",
Expand Down Expand Up @@ -121,17 +131,12 @@ async def async_step_auth(
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))
Expand Down
53 changes: 53 additions & 0 deletions tests/components/google/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
[
Expand Down
Loading