Google Calendar API Python Authorization - python

I've requested access to an OAuth key through the google api console for the calendar api. I've also set my scope up to match the read/write permission setting, but during testing - had authenticated with the "read-only" permissions. Now when I'm testing to insert an event into my calendar, I receive the error "Insufficient Permission". **I'm using python for all of this.
I've tried resetting the client_secret, disabling the api (and renabling), as well as adjusting the auth url.... but to no avail.
Any advice on how to change my permissions in order to create events?

To fix it , I had to revoked access to the app at https://accounts.google.com/IssuedAuthSubTokens and retired after then I was able to access the API correctly.
Despite having the scope in the list, and the scope showing up on Google's OAuth2 grant page, the additional scope wasn't granted.

Related

Having trouble getting MSAL Authorization Code workflow to work

I am building a desktop python application that uses the MSAL authorization code workflow by opening up a browser window for authentication. I keep getting back an invalid grant error (code 70000) for some accounts but not others when trying to get an authorization token. It seems to work just fine for the personal Microsoft account through which the application is registered in the Azure portal. It also works fine for my university account (a school Microsoft account), but not for other personal Microsoft accounts.
Through the Azure portal, the application is registered with the ability for all Microsoft accounts to work with it. The scopes listed there also match the scopes that I am requesting in the python application.
The authorize endpoint does return a valid looking authorization code, but then when I try to use that code to get a valid token, I get the error. More specifically, the message associated with the error says:
AADSTS70000: The request was denied because one or more scopes requested are unauthorized or expired. The user must first sign in and grant the client application access to the requested scope.\r\nTrace ID: 6afddbd2-308e-44df-8640-976dc1c1f601\r\nCorrelation ID: bdb626d0-0a3d-4333-ac8f-b5ff510ca046\r\nTimestamp: 2022-07-24 18:50:23Z
What might be causing this issue to occur?
It turns out this was an issue with the scopes I was providing to the authorization endpoint. The scopes profile, openid, and offline_access should be specified to allow some features of Microsoft's Graph API to function properly. In my case, it was the offline_access scope that did the trick. Also note that these scopes cannot be added to the authorization token request, at least through the Python MSAL library. These scopes need to be specified during the process of getting the authorization code only, not the token.

Obtaining `gmail.compose` privileges for single G Suite email account to send emails via GMail API

I am trying to compose drafts programmatically via the GMail API, using this tutorial and the following line of code:
service.users().drafts().create(userId=user_id, body=message).execute()
but I receive the following error:
An error occurred: <HttpError 403 when requesting https://www.googleapis.com/gmail/v1/users/me/drafts?alt=json returned "Insufficient Permission">
Note that directly sending messages with gmail.send privileges does not work for me - I want to thread messages.
In the API console, I tried enabling the following scope ../auth/gmail.compose, but there is a warning message that Because you've added a sensitive scope, your consent screen requires verification by Google before it's published.
I have submitted my app for verification, but I just received an email stating that "We've extended the deadline to fully complete your verification from May 15th to June 26th, 2019".
Actually, no users will use my G Suite email accounts (so my app cannot be used to spy on their messages) and I only need access to a single email account info#example.com to send notifications to users who use my site on example.com.
Is there any way to get server-side access to my info#example.com account using my password and programmatically draft messages without having to go through the lengthy and unnecessary app verification process?
It turns out that you can have an "internal", rather than a client facing "public" app, for which all GMail scopes are automatically available.
Here is the response from the Google team that describes the steps (it worked for me):
It appears your app is only used by the people in your domain.
If this is correct, please reply to this email to confirm that is the
case. We will then reject your request so that you are able to update
your project from public to internal.
In addition, you will need to associate your project with your
organization by following the steps below:
If you have not already done so, create an Organization by following
the Quickstart Using Organizations instructions.
Migrate the project into the organization you created as shown in
Migrating Existing Projects into the Organization. Once you have
associated your project with your organization, you and the project
users in your organization can use the app to directly access OAuth
scopes. No verification will be required.

Authenticating google cloud behind corporate firewall

I am trying to use Google cloud's natural language API at work, and I believe my corporate firewall is blocking communication between python and google cloud.
After entering the following in the terminal:
gcloud auth application-default login
My browser opens up to log into my google account successfully. After I log in, however, I get
ERROR: There was a problem with web authentication. Try running a
gain with --no-launch-browser.
ERROR: (gcloud.auth.application-default.login) Could not reach th
e login server. A potential cause of this could be because you ar
e behind a proxy. Please set the environment variables HTTPS_PROX
Y and HTTP_PROXY to the address of the proxy in the format "proto
col://address:port" (without quotes) and try again.
Example: HTTPS_PROXY=https://192.168.0.1:8080
I believe I need to contact my IT department to add an exception to our firewall. Does anyone know what the address / port for google cloud's natural language processing API is?
I can't directly answer your question but I can provide some general guidance that might workaround your issue.
The command
gcloud auth application-default login
Is a convenience helper for running sample code locally but it's really not the best auth strategy for a variety of reasons. It uses a special client ID that won't always have all your quota.
The way I would recommend using the API is Service Accounts. You can create a Service Account in the Cloud Console under API credentials, and then download a JSON key. Then you set the environment variable GOOGLE_APPLICATION_CREDENTIALS to point to your file, and it will automatically work assuming you are using Application Default Credentials (which most samples and client libraries use).
On App Engine, and Compute Engine (assuming you created the VM with the correct scopes) Service Accounts exist by default so you don't even need to download the JSON and set the environment variable.
The other way you can use the API is just creating an API Key, then hit the HTTP endpoints with ?key=api-key at the end of the URL. API Keys are also less than ideal (no idea who client is, no scopes), but are a simple option.
In your case, I'd recommend using JSON service account keys and the environment variable, but it's worth reading the official authentication guide.

Google App Engine auth for Google APIs using service account

TL;DR What is the preferred way of doing this now that service accounts need domain-wide delegation set up?
I have a GAE project (python 2.7 runtime) that uses the Google Calendar API v3. Up until last week, I had been using the default GAE service account to connect to the calendar API, and the service account was given read/write permission to the calendar under calendar sharing settings.
Since last Thursday Oct 20, the service account cannot write to the calendar (events.post or events.patch) -- returns a 403 Forbidden -- and reads (events.list) return 200, but no records. Checking the permissions for the account under calendar sharing, it has been changed to "See Free/Busy only".
I believe this is related to this announcement from Google about winding down OAuth 1.0 service accounts on Oct 20: https://developers.googleblog.com/2016/04/saying-goodbye-to-oauth-10-2lo.html
The recommendation seems to be to grant Domain Wide Delegation to the service account: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority However, the GAE default service account does not list a client_id. So we set up a new service account, and granted it Domain-Wide Delegation.
But the new service account doesn't work any better. I tried using both AppAssertionCredentials, and created a JSON key file and tried using ServiceAccountCredentials, as detailed on https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
AppAssertionCredentials doesn't seem to work because the account is not the default service account, even passing in a service_account_id param.
ServiceAccountCredentials does refresh the key etc. but I get the same behavior as with the default service account: 403 Forbidden errors on writes and no records returned on reads.
I have double-checked the new service account has domain-wide delegation set up and under the calendar permissions it is listed as "Make changes to events".
EDIT:
We also were able to set domain-wide delegation for the default GAE service account. However, it still does not work using either AppAssertionCredentials or ServiceAccountCredentials. I get the same behavior: 403 Forbidden errors on writes and no records returned on reads.
EDIT #2:
We also tried setting up a new service account from scratch, setting DwD, and permissions for the account on the calendar. Same behavior, and the calendar permissions are forced to "See only free/busy", with the other options greyed out.

google contacts api service account oauth2.0 sub user

I am trying to use the Google Contacts API to connect to a user's contact information, on my Google apps domain.
Generating an access_token using the gdata api's ContactsService clientlogin function while using the API key for my project works fine, but I would prefer to not store the user's credentials, and from the information I have found that method uses OAuth1.0
So, to use OAuth2.0 I have:
Generated a Service Account in the developer's console for my project
Granted access to the service account for the scope of https://www.google.com/m8/feeds/ in the Google apps domain admin panel
Attempted to generate credentials using SignedJwtAssertionCredentials:
credentials = SignedJwtAssertionCredentials(
service_account_name=service_account_email,
private_key=key_from_p12_file,
scope='https://www.google.com/m8/feeds/',
sub=user_email')
The problem I am running into is that attempting to generate an access token using this method fails. It succeeds in generating the token when I remove the sub parameter, but then that token fails when I try to fetch the user's contacts.
Does anyone know why this might be happening?

Categories