-
Notifications
You must be signed in to change notification settings - Fork 307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stripping "Z" from expiry date parsing in Credentials may lead to incorrect expires_at timestamp #1264
Comments
Hey @IslandJohn, Thank you for the detailed and high effort investigation. Can you provide detailed reproduction steps for this issue? Either a bash or python script would be very useful to help investigate this. Thanks! Carl |
I did not discover any particular reason this is being done after digging in the git history. There seems to be an inconsistency with how $ rg "strptime" -C 3 -g '!*tests*'
google/oauth2/credentials.py
395- # access token expiry (datetime obj); auto-expire if not saved
396- expiry = info.get("expiry")
397- if expiry:
398: expiry = datetime.strptime(
399- expiry.rstrip("Z").split(".")[0], "%Y-%m-%dT%H:%M:%S"
400- )
401- else:
google/auth/external_account_authorized_user.py
315- """
316- expiry = info.get("expiry")
317- if expiry:
318: expiry = datetime.datetime.strptime(
319- expiry.rstrip("Z").split(".")[0], "%Y-%m-%dT%H:%M:%S"
320- )
321- return cls(
google/auth/impersonated_credentials.py
105- try:
106- token_response = json.loads(response_body)
107- token = token_response["accessToken"]
108: expiry = datetime.strptime(token_response["expireTime"], "%Y-%m-%dT%H:%M:%SZ")
109-
110- return token, expiry
111- |
I don't have a script to test this explicitly, but here's my setup:
What appears to be happening is that the time being parsed includes a "Z" to indicate UTC time (e.g. 22:00Z). Since this is stripped, the time is interpreted in the time zone the script is running in. In my case, 22:00 EDT, which is +4 hours from when the token should actually expire. If I force my local time zone to UTC (export TZ=UTC) it works correctly, because the the time is being parsed in the same zone. |
RFC 3339 seems to indicate the use of Z (or other offset) for the time zone and it should not be ignored. Based on this, none of the implementations above seem correct since they either assume "Z" (which it may not be, since it could be a +/- offset), or Z is assumed and ignored. |
Sorry for the delay. Picking this back up. Here is a simple script for a repro.
The assertion fails, which isn't desirable since the token was not refreshed when it is deserialized from the file system. |
Following up with a simple repro that is more accurate to the reported symptoms.
I will now investigate next steps. |
Okay. Digging in further and I do not believe this is the cause of your issue. While I do believe the code should be cleaned up, and not strip the timezone data (and serialize without an actual timezone), that is a separate issue. I pushed the code I used to investigate here in case there are any gaps. I'll leave this open for now but this should not cause any issues for your reported flow. I will dig into google-oauth-library-python next. |
Do you believe this is a time zone parsing issue somewhere else? |
Actually, I'd say it's working correctly now:
Stripping the Maybe the main problem is that this library doesn't document that its datetimes are in UTC, so all the readers have to guess (and can guess incorrectly and cause bugs?). So, the bug must be somewhere else 🤷 |
Cross-posting: gilesknap/gphotos-sync#413 (comment) TL;DR: The However, this mistake is very easy to make, probably even very likely that most would do the same. I tried a couple of variations with Copilot which also always produced this bug. Just FYI. |
Thanks for digging through this. |
Environment details
google-auth
version: 2.17.0Steps to reproduce
Notes
I believe the culprit may be here. The symptom investigations are here.
The text was updated successfully, but these errors were encountered: