diff --git a/homeassistant/components/google/config_flow.py b/homeassistant/components/google/config_flow.py index cfc0959684439e..c7ee25f4869cb7 100644 --- a/homeassistant/components/google/config_flow.py +++ b/homeassistant/components/google/config_flow.py @@ -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", @@ -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)) diff --git a/tests/components/google/test_config_flow.py b/tests/components/google/test_config_flow.py index 4108806d16668b..2a7bf40438e923 100644 --- a/tests/components/google/test_config_flow.py +++ b/tests/components/google/test_config_flow.py @@ -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", [