Google Calendar refresh token expiration
Issue to discuss
Refresh tokens can expire for a variety of reasons and when they do the calendar integration will break (or will shortly afterwards when the access token also expires). As such, we need a way to handle this.
Potential mitigations
Inform the owner
Since their token has expired, they can re-authenticate with Google and it will give Chapter new tokens to work with. If we email the owner in the event we get a Invalid Credentials error, they can fix it.
To make sure we don't email them all the time, we should look for errors where the 'reason' is authError and the message is Invalid Credentials. Also, we can set a flag in the db when that error occurs and remove the flag when they re-authenticate. That flag could ensure the owner only gets emailed when it breaks, not on every failed request.
Have a backup
We currently have a single point of failure: the owner's account is the only one with access to the calendars and events. If we allow more than one account access, then as long as at least one token is valid, the integration can continue.
My thinking is we could have use two accounts and rotate which credentials we use. That way neither account's refresh token should expire due to inactivity.
There could be also displayed alert on page for instance owners, to not rely only on the email notification.
Do you know if there's any specific way to test if the integration (refresh_token) is still working/valid, which could be used periodically? Rather than handling it only after some action ends up with error. My searches for that are not yielding anything concrete.
More drastic condition for displaying alert could be the lack of entries in the google_tokens table, including time before first authorization. If refresh_token is invalid we can safely delete the entry, it can't be used anymore anyway.
That might be though annoying, if somebody is not planning to use integration with calendar.
Sorry, @gikf I was sure I replied to this.
Do you know if there's any specific way to test if the integration (refresh_token) is still working/valid, which could be used periodically?
We could do something like request a calendar list. It feels slightly sketchy as a health-check, but maybe it's okay. Any request that requires authentication should work, unless the user has revoked some scopes (if that's even possible).
More drastic condition for displaying alert could be the lack of entries in the google_tokens table, including time before first authorization. If refresh_token is invalid we can safely delete the entry, it can't be used anymore anyway.
That might be though annoying, if somebody is not planning to use integration with calendar.
How about something like this. if (tokensStored && tokensAreInvalid) showAlert();. That way we avoid annoying people who never integrated in the first place.
Bit of rundown, naming as usually is still rather rough
- Add
is_validfield ingoogle_tokenstable. - When Calendar api action fails due to
Invalid Credentialsmark token as invalid and send email to owner. - Possible actions with calendar depend on the Authentication status. Call checking Authentication status:
- (optionally) Perform Integration test first
- Exists token not marked as invalid ->
true - No token added ->
false - All tokens marked as invalid ->
null/undefined/throw/broken
When Authentication status is true:
- Authenticate button in Calendar dashboard is not visible.
- Integration test - in Calendar dashboard option to explicitly trigger some calendar api actions checking if saved token is still working.
- Buttons creating calendar/calendar event (if not created already) in dashboards are enabled.
- Calendar api actions will be normally attempted.
When Authentication status is false:
- Authenticate button in Calendar dashboard is visible.
- Buttons creating calendar/calendar event (if not created already) in dashboards are not visible.
- Calendar api actions will not be attempted.
When Authentication status is broken:
- Alert is displayed for instance owners (those with permission to authenticate).
- Re-authenticate button in Calendar dashboard is visible.
- Buttons creating calendar/calendar event (if not created already) in dashboards are disabled, possibly with information about broken integration. Or not visible.
- Calendar api actions will not be attempted until not re-authenticate.
Other changes?
- Display as who chapter is authenticated to the Calendar api in Calendar dashboard.
Multiple tokens:
google_tokenrelated to user account- Granting permission to calendars to authenticated users https://developers.google.com/calendar/api/concepts/sharing#sharing_calendars
Thanks for the detailed breakdown, @gikf, it's much clearer now.
One thing I would add is that, if we allow multiple users to add tokens, we'd want to show the Authenticate button to users with the appropriate permission, if they have not got a valid token. We'd have to rework the db slightly so that google_tokens rows are linked to specific users, but that's not a big deal.
Adding multiple tokens might not be complicated, but using probably will. From my understanding token from authentication of person A won't be usable, out of the box, on calendar created with token from authentication of person B. Unless they'd use the same account to authenticate, or there's some permission granted on the Google Calendar's side?
or there's some permission granted on the Google Calendar's side?
That's how it would have to work. When person B authenticates, we'd have to use person A's token to grant them access to the calendar.
The docs are here: https://developers.google.com/calendar/api/concepts/sharing#sharing_calendars. It looks like read/write access might be enough for our needs.
I should have said at the outset that this isn't desperately urgent. We'll see how it goes as we test it, but my guess is we can ship the MVP without it. As long as owners create a separate google account for this purpose they should avoid most pitfalls and we can make it more robust later down the line.