Skip to content
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

Credentials object works even when incorrect access_code is provided #1370

Closed
psambit9791 opened this issue Aug 15, 2023 · 9 comments
Closed

Comments

@psambit9791
Copy link

I am trying to use google.auth and googleapiclient to pull calendar information from user. The problem I am encountering is that when I am creating a Credentials object using:

credentials = Credentials(token=loaded_tokens['token'], refresh_token=loaded_tokens['refresh_token'], id_token=loaded_tokens['id_token'], token_uri=loaded_tokens['token_uri'], client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=SCOPES)

and instead of using the actual token I hardcode any value like:

credentials = Credentials(token="abcde", refresh_token=loaded_tokens['refresh_token'], id_token=loaded_tokens['id_token'], token_uri=loaded_tokens['token_uri'], client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=SCOPES)

and I make a call to the calendar API like this:

service = build('calendar', 'v3', credentials=credentials)
start = '01-01-2023 00:00:00'
stop = '31-01-2023  23:59:59'
start = datetime.strptime(start, '%d-%m-%Y %H:%M:%S')
stop = datetime.strptime(stop, '%d-%m-%Y %H:%M:%S')
events_result = service.events().list(calendarId='primary', timeMin=start.isoformat() + 'Z', timeMax=stop.isoformat() + 'Z').execute()

it still pulls all the information despite the access_code being incorrect.

Environment details

  • OS: Windows 10
  • Python version: 3.10.9
  • pip version: 22.3.1
  • google-auth version: 2.22.0

Prerequisites

I have setup a consent screen and an OAuth2 client to access calendar for a test account in Google Cloud API & Services.

Steps to reproduce

  1. I have a function which loads credentials from a file.
def load_google_credentials(user_id):
  loaded_tokens = None
  with open(user_id+'_google_token.json', 'r') as f:
      loaded_tokens = json.load(f)
  credentials = Credentials(token=loaded_tokens['token'], refresh_token=loaded_tokens['refresh_token'], id_token=loaded_tokens['id_token'], token_uri=loaded_tokens['token_uri'], client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=SCOPES)
  return credentials
  1. Then I use the credentials from (1) to pull data from the calendar
creds = load_google_credentials('test_user')
service = build('calendar', 'v3', credentials=creds)
start = '01-01-2023 00:00:00'
stop = '31-01-2023  23:59:59'
start = datetime.strptime(start, '%d-%m-%Y %H:%M:%S')
stop = datetime.strptime(stop, '%d-%m-%Y %H:%M:%S')
events_result = service.events().list(calendarId='primary', timeMin=start.isoformat() + 'Z', timeMax=stop.isoformat() + 'Z').execute()
  1. Then I change the function load_google_credentials() to accept a hardcoded token:
def load_google_credentials(user_id):
  loaded_tokens = None
  with open(user_id+'_google_token.json', 'r') as f:
      loaded_tokens = json.load(f)
  credentials = Credentials(token="abcde", refresh_token=loaded_tokens['refresh_token'], id_token=loaded_tokens['id_token'], token_uri=loaded_tokens['token_uri'], client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=SCOPES)
  return credentials
  1. Then I use the credentials from (3) on the same code as in step 2 to pull calendar data.

The data still comes though.

I am not sure if this is expected behaviour or not. It does not appear to be since the access code is now incorrect.

@clundin25
Copy link
Contributor

A cursory look:

I imagine the credential is marked as invalid and automatically refreshed using the refresh token.

You could add a print statement to check if the token is valid after creation print(f'{credential.valid= credential.token=}'). Then after your request, print(f'{credential.valid= credential.token=}') to see if the credential is now valid, and the token has been updated.

@psambit9791
Copy link
Author

Tried this. But it says that the credentials are valid event when I change my access code.

For example, I tried this:

credentials = Credentials(token="abcde", refresh_token=loaded_tokens['refresh_token'], id_token=loaded_tokens['id_token'], token_uri=loaded_tokens['token_uri'], client_id=CLIENT_ID, client_secret=CLIENT_SECRET, scopes=SCOPES)
print(credentials.valid, credentials.token)

And the output to this was:

True abcde

When I call the calendar service with the same credentials, it returns all the relevant information. But when I try printing the credentials validity and token again, it is the exact same. If the object is mutable, any refresh happening at the service should be reflected afterwards.

service = build('calendar', 'v3', credentials=credentials)
events_result = service.events().list(calendarId='primary', timeMin=start.isoformat() + 'Z', timeMax=stop.isoformat() + 'Z').execute()
print(credentials.valid, credentials.token)

which displays:

True abcde

@clundin25
Copy link
Contributor

Okay, can you provide more information so I can work on reproducing?

Can you share what credential class you are instantiating? Could you share a docker image or repo that has a repro?

@psambit9791
Copy link
Author

Surely. I'll create a clean repo with the issue and share the link in this thread.

@psambit9791
Copy link
Author

Hi @clundin25, I have created a repo but it has to be kept private based on our company policy. I have added you as a collaborator - https://github.com/psambit9791/google_auth_test/. Can you please try and take a look?

@psambit9791
Copy link
Author

@clundin25 any update on this at all?

@clundin25
Copy link
Contributor

@psambit9791 I have been on vacation. Once I have caught up I will take a look at your test repo. Thank you for creating it!

@clundin25
Copy link
Contributor

So, taking a look, it looks like you are using the Oauth2.0 base credential type.

Here we see that it always refreshes the credentials before using them https://github.com/googleapis/google-auth-library-python/blob/main/google/oauth2/credentials.py#L543.

Here is where the underlying HTTP library is applying the credentials https://github.com/googleapis/google-auth-library-python-httplib2/blob/d7f949b112213f0959c233fe38050616093ba3c6/google_auth_httplib2.py#L209.

You could probably set a breakpoint on the credential's refresh method, to see where it gets called. I'm not sure why the credential appears to stay invalid, given that it is a self mutating method, but I don't see any print statements in the repro

@clundin25
Copy link
Contributor

Please re-open this with more information if this is still an issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants