Open aristosv opened 2 years ago
This is the actual error
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Token has been expired or revoked.
For some reason the token expired
I have the same issue:
In documentation https://developers.google.com/identity/protocols/oauth2#expiration there is written:
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
So the app needs to be published, which required google verification. :-(
I have not found a solution yet.
Duplicate of https://github.com/insanum/gcalcli/issues/611 ?
@aristosv @dequeckerp You guys can try this work around:
If you are using KDE, add that url to kOrganizer, restart your system. Then use konsolekalendar in terminal.
I don't see how that iCal link can be used with gcalcli command line options.
Per https://github.com/insanum/gcalcli/issues/611 , if we can figure out how to get gcalcli to pass a redirect_uri parameter to the Python Google OAuth2 module, it should be possible to publish the app without Google review and have longer-lasting tokens. I also filed an Ubuntu bug report at https://bugs.launchpad.net/ubuntu/+source/python-oauth2client/+bug/1983216 since it appears upstream is no longer maintaining the relevant library https://github.com/googleapis/oauth2client/issues/317
Does the replacement library google-auth support the required functionality?
I believe so. The deprecated Python module doesn't allow the code to specify redirect_uri. If we want to publish a web app in production rather than testing (thus extending the token expiration period), while foregoing Google verification, we need to be able to set redirect_uri. There's probably some way to hack around this in the existing gcalcli code but it wasn't something I could solve in a few minutes.
I've published my own google app I was using to connect and I haven't had issues since. It gave an ugly warning about not being verified when logging in, but you can say you don't care :)
I've published my own google app I was using to connect and I haven't had issues since. It gave an ugly warning about not being verified when logging in, but you can say you don't care :)
How did you publish it? Doesn't it need to pass a manual review by Google?
On Sun Apr 16, 2023 at 14:55, Feraidoon Mehri wrote:
I've published my own google app I was using to connect and I haven't had issues since. It gave an ugly warning about not being verified when logging in, but you can say you don't care :)
How did you publish it? Doesn't it need to pass a manual review by Google?
No, it doesn't, unless you want to make that warning go away.
Likely fixed now that I merged #683. Please let me know if issues remain. Thanks!
Was this fix merged to release 4.4.0?
Today I wanted to use gcalcli, but got this error again:
Token has been expired or revoked
I followed the instructions how to create the token from the page here, but I got this error anyway. Is there something I can try to make it work for longer?
@dbarnett:
Here is the error I got:
Traceback (most recent call last):
File "/usr/local/bin/gcalcli", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/cli.py", line 169, in main
gcal.CalQuery(
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 1248, in CalQuery
event_list = self._search_for_events(start, end, None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 1096, in _search_for_events
event_list.extend(
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 1041, in _GetAllEvents
self.get_events()
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 183, in get_events
return self.get_cal_service().events()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 178, in get_cal_service
credentials=self._google_auth())
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 171, in _google_auth
auth.refresh_if_expired(self.credentials)
File "/usr/local/lib/python3.11/dist-packages/gcalcli/auth.py", line 26, in refresh_if_expired
credentials.refresh(Request())
File "/usr/local/lib/python3.11/dist-packages/google/oauth2/credentials.py", line 431, in refresh
) = reauth.refresh_grant(
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/google/oauth2/reauth.py", line 366, in refresh_grant
_client._handle_error_response(response_data, retryable_error)
File "/usr/local/lib/python3.11/dist-packages/google/oauth2/_client.py", line 68, in _handle_error_response
raise exceptions.RefreshError(
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})
Could you peek in your ~/.gcalcli_oauth file with a text editor and see if you can find "232867676714.apps.googleusercontent.com" in there, or a different ID before the .apps.…? (It may be a binary file but I think the "apps.googleusercontent.com" part should still be visible if you tell your text editor to open it anyway.)
Also when this happens, does renewing with the same client_id/client_secret work, or do you have to update anything else?
Yes, the oauth
file.
By renewing you mean to do:
gcalcli --client-id=<ID>.apps.googleusercontent.com init
or do something elese? I tried this command, but gcalcli says that I should use one of the following commands (invalid choice error).
But is the ID in there "232867676714", was my question.
By renewing you mean to do …
I think on 4.4.0 init
isn't a valid command, you'd need to use list
or whatever placeholder command, but I was more asking what exactly you do when it tells you the token is expired to get it running for another 7 days.
No, there is no such string in the ID. Should I post it here?
If I do list command, then it list my calendar.
If I do the calw
then I get this error.
But with any other option I cannot triger the init.
No, there is no such string in the ID. Should I post it here?
Nah, if it's not the old default then it would have to be one you set up. Just wanted to double check.
If I do the
calw
then I get this error.
Ah, weird! I did feel like I saw auth treated differently for calm
/calw
vs. list
once a while back (https://github.com/insanum/gcalcli/issues/691#issue-2483533199) but since I posted that I haven't seen any further weirdness like that. I wonder if there's some difference in the scopes used or something...
So IIUC you're saying that after you see this error...
gcalcli list
still works finecalw
/calm
fail with the RefreshError you posted abovegcalcli --client-id=xxx calw
to refresh the authentication?
FYI I'll probably add a gcalcli util inspect-auth
command to simplify some of this auth troubleshooting in the future, but hopefully we can isolate the problem on your current install.
I wonder if there's some difference in the scopes used or something...
Looks like if there is a missing scope here it'd be https://www.googleapis.com/auth/calendar.events
, which is needed for listing events but not for listing calendars. I looked through the code and didn't see anything else specialized for calw
/calm
vs. list
... ultimately one does self.get_cal_service().events()
where the other does self.get_cal_service().calendarList().list()
. But on my system calw
works fine without any explicit calendar.events scope being attached to my token.
I'll have to look into whether calendar
scope is supposed to imply calendar.events
with the same prefix or how that works for OAuth scopes. I see we only request the calendar
scope explicitly in the auth flow.
I ran the following:
user@trekstor:~$ gcalcli --config-folder=/home/user/.config/gcalcli/new --client-id=797412254427-ulo8vk53ea8arjimabkahqjo8emte84j.apps.googleusercontent.com calw
Not yet authenticated. Starting auth flow...
NOTE: See https://github.com/insanum/gcalcli/blob/HEAD/docs/api-auth.md for help/troubleshooting.
You'll be asked for a client_secret that you should have set up for yourself in Google dev console.
Client Secret: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Now click the link below and follow directions to authenticate.
You will likely see a security warning page and need to click "Advanced" and "Go to gcalcli (unsafe)" to proceed.
Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=797412254427-ulo8vk53ea8arjimabkahqjo8emte84j.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar&state=WsmhBeYCLqXXRRTjI43O27J7IBSoYk&access_type=offline
Traceback (most recent call last):
File "/usr/local/bin/gcalcli", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/cli.py", line 142, in main
gcal = GoogleCalendarInterface(
^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 73, in __init__
self._get_cached()
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 219, in _get_cached
self.get_cal_service().calendarList().list(
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 178, in get_cal_service
credentials=self._google_auth())
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/gcal.py", line 167, in _google_auth
self.credentials = auth.authenticate(client_id, client_secret)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gcalcli/auth.py", line 20, in authenticate
credentials = flow.run_local_server(open_browser=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/google_auth_oauthlib/flow.py", line 458, in run_local_server
self.fetch_token(
File "/usr/local/lib/python3.11/dist-packages/google_auth_oauthlib/flow.py", line 285, in fetch_token
return self.oauth2session.fetch_token(self.client_config["token_uri"], **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/requests_oauthlib/oauth2_session.py", line 406, in fetch_token
self._client.parse_request_body_response(r.text, scope=self.scope)
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 427, in parse_request_body_response
self.token = parse_token_response(body, scope=scope)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/parameters.py", line 441, in parse_token_response
validate_token_parameters(params)
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/parameters.py", line 448, in validate_token_parameters
raise_from_error(params.get('error'), params)
File "/usr/lib/python3/dist-packages/oauthlib/oauth2/rfc6749/errors.py", line 399, in raise_from_error
raise cls(**kwargs)
oauthlib.oauth2.rfc6749.errors.InvalidClientError: (invalid_client) Unauthorized
But why?
Agreed that's weird. The errors are coming from deep in google_auth_oauthlib deps so there's not a lot of self-contained troubleshooting info, but it does seem like for one reason or another gcalcli really doesn't like something about this 797412254427-ulo8vk53ea8arjimabkahqjo8emte84j.apps.googleusercontent.com
client. That's something you got from a project you set up yourself in Google Cloud Console, right? Maybe if you check on the Google end there might be some kind of advisory message about the project? Have you tried creating a fresh "project" to see if the same issues repro with a new client?
I created a clean project with OAuth and for now it is working. Let's see it in a week if it start behaving wrongly.
Sounds good, and in the meantime if you want to swap out your oauth files and work on narrowing down the issue I'm game, but that might also be easier after I push a new release w/ a util inspect-auth
command. At the very least it'd be nice to improve the error message output and behavior in some of these failure cases, if we can make sense of the different errors getting thrown and what they're supposed to mean.
I wonder if there's some difference in the scopes used or something...
Looks like if there is a missing scope here it'd be
https://www.googleapis.com/auth/calendar.events
, which is needed for listing events but not for listing calendars.
Alright, the scopes shouldn't be the problem from my read of the API docs. I noticed it says "This request allows authorization with at least one of the following scopes:", and likewise every other method that looks for the calendar.events
scope also accepts calendar
.
I suspect the only reason calw
/calm
seemed to be acting any different was because of the cache: https://github.com/insanum/gcalcli/issues/622#issuecomment-2378125839.
So I can't find anything else to make more robust "just in case", hoping that indeed the only problem was something in the OAuth client, and if it keeps misbehaving I've implemented the util inspect-auth
command (#780) to make troubleshooting easier.
Every 7 days, I start getting the following error in my log files
Basically the error is
code = input('Enter verification code: ').strip()
To fix it, I have to create a new OAuth2 token and run this command again
gcalcli --noauth_local_webserver --client-id=$clientid --client-secret=$clientsecret --config-folder $parentdir/clients/$clientdir/auth agenda
And then it lasts for 7 more days, and I have to repeat the process again.
What I'm I doing wrong here?