diff --git a/engine/apps/social_auth/pipeline/google.py b/engine/apps/social_auth/pipeline/google.py index 065a69db..0d5fc609 100644 --- a/engine/apps/social_auth/pipeline/google.py +++ b/engine/apps/social_auth/pipeline/google.py @@ -22,6 +22,16 @@ def persist_access_and_refresh_tokens(backend: typing.Type[BaseAuth], response: def disconnect_user_google_oauth2_settings(backend: typing.Type[BaseAuth], user: User, *args, **kwargs): + """ + Don't use `google_oauth2_user.access_token` when revoking token, use `refresh_token` instead. If we use + the access token, we may get an HTTP 400 from Google because the token may be invalid or revoked. + + https://stackoverflow.com/a/18578660/3902555 + """ + logger.info(f"Disconnecting user {user.pk} from Google OAuth2") + # 2nd argument, uid, is not needed for GoogleOauth2 backend - backend.revoke_token(user.google_oauth2_user.access_token, "") + backend.revoke_token(user.google_oauth2_user.refresh_token, "") user.finish_google_oauth2_disconnection_flow() + + logger.info(f"Successfully disconnected user {user.pk} from Google OAuth2") diff --git a/grafana-plugin/src/containers/UserSettings/parts/tabs/GoogleCalendar/GoogleCalendar.tsx b/grafana-plugin/src/containers/UserSettings/parts/tabs/GoogleCalendar/GoogleCalendar.tsx index 1dc44487..efa91cc0 100644 --- a/grafana-plugin/src/containers/UserSettings/parts/tabs/GoogleCalendar/GoogleCalendar.tsx +++ b/grafana-plugin/src/containers/UserSettings/parts/tabs/GoogleCalendar/GoogleCalendar.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { css } from '@emotion/css'; -import { Button, HorizontalGroup, InlineSwitch, VerticalGroup, useStyles2 } from '@grafana/ui'; +import { Button, HorizontalGroup, Switch, VerticalGroup, useStyles2 } from '@grafana/ui'; import { observer } from 'mobx-react'; import { Block } from 'components/GBlock/Block'; @@ -21,11 +21,16 @@ const GoogleCalendar: React.FC<{ id: ApiSchemas['User']['pk'] }> = observer(({ i const styles = useStyles2(getStyles); - const user = userStore.items[id]; - const [googleCalendarSettings, setGoogleCalendarSettings] = useState(user?.google_calendar_settings); - const [showSchedulesDropdown, setShowSchedulesDropdown] = useState( - user.google_calendar_settings?.oncall_schedules_to_consider_for_shift_swaps?.length > 0 - ); + const [googleCalendarSettings, setGoogleCalendarSettings] = + useState(); + const [showSchedulesDropdown, setShowSchedulesDropdown] = useState(); + + useEffect(() => { + userStore.fetchItemById({ userPk: id }).then((user) => { + setGoogleCalendarSettings(user.google_calendar_settings); + setShowSchedulesDropdown(user.google_calendar_settings.oncall_schedules_to_consider_for_shift_swaps?.length > 0); + }); + }, []); const handleShowSchedulesDropdownChange = (event: React.ChangeEvent) => { const value = event.target.checked; @@ -36,12 +41,6 @@ const GoogleCalendar: React.FC<{ id: ApiSchemas['User']['pk'] }> = observer(({ i } }; - useEffect(() => { - if (user) { - setGoogleCalendarSettings(user.google_calendar_settings); - } - }, [user]); - const handleSchedulesChange = (value) => { setGoogleCalendarSettings((v) => ({ ...v, oncall_schedules_to_consider_for_shift_swaps: value })); @@ -50,10 +49,12 @@ const GoogleCalendar: React.FC<{ id: ApiSchemas['User']['pk'] }> = observer(({ i }); }; + const user = userStore.items[id]; + return ( - + {user.has_google_oauth2_connected ? ( @@ -71,7 +72,7 @@ const GoogleCalendar: React.FC<{ id: ApiSchemas['User']['pk'] }> = observer(({ i ) : ( - +
@@ -93,13 +94,10 @@ const GoogleCalendar: React.FC<{ id: ApiSchemas['User']['pk'] }> = observer(({ i {user.has_google_oauth2_connected && ( - + + + Specify the schedules to sync with Google calendar + {showSchedulesDropdown && (