Which credentials should I choose and how? - python-3.x

I want to use Google Drive API, Sheet API, Gmail API in my Python program.
I follow this page. It says
"Create credentials to use the Google Drive API
After Enabling the Google Drive API, Google should take you to the Google Drive API console for your project.
Click Create credentials."
It will create credentials for using only Drive? I read a lot of docs, official, blogs, tutorials, etc. I'm beginner in this topic, so please give some details also, because not everything is clear for me.

There are four types of credentials and they are used for different purposes and require different code to use them.
Browser credentials used for applications which will be hosted on a website. For use with accessing private user data.
Native credentials (other) used for installed applications. ex: A windows desktop application. For use with accessing private user data.
Service account credentials used for server to server communication where the developer has access to the account which will be accessing the API.
Mobile applications.
The first thing you need to do is decide whose data you will be accessing. Are you expecting to access a users data then you will need to use OAuth2 and request the users permission to access the data. If you are acting a static drive account and only that account and you personal have access to set it up you could use a service account.
Browser credentials
Uses OAuth2 to request permission of a user to access their data. Response will be returned to a web site. web app sample
Native credentials
Use OAuth2 to request permission of a user to access their data. Response will be returned to the host where it was sent from. installed app
Service account credentials
Service accounts are dummy users which we as developers can use to pre-authorize a user with access. This method will not require user sign-in or consent. service account
Note
You will probably only need to create one credential type. You will need to enable all of the APIs you intend to use in the Google Developer Console. (Google Drive API, Sheet API, Gmail API) You should know that service accounts do not support gmail API unless you have a GSuite account and can set up the authorization.
You will need to create a service for each of the API types.
drive = build('drive', 'v2', credentials=credentials)
sheets = build('sheets', 'v2', credentials=credentials)
gmail = build('gmail', 'v2', credentials=credentials)

Related

Impersonate Google Cloud Patform user through OAuth2.0 flow

I want to set up an OAuth2.0 flow for users that have access to GCP.
The user will login to a web app.
Then, the OAuth2.0 flow will need to ask for the consent that will allow the app to perform things on their behalf, based on their permissions.
Therefore, the scopes that need to be requested should be those that cover their actual permissions on GCP.
Is something like that possible when it comes to OAuth2.0 and GCP?
Had you seen? https://developers.google.com/identity/protocols/oauth2
Looks like that might address your question.
Separately from that link --> Yes that is something that could be done. You login via OAuth, and once authenticated that service can use GCP Service Accounts https://cloud.google.com/iam/docs/service-accounts to work with GCP Services.
A user can be granted permission to impersonate a service account.
A service account can be granted permission to impersonate a user account via Domain Wide Delegation (Google Workspace).
A user cannot impersonate another user. There is no mechanism to grant the required permissions.
In a GCP project you can access Google APIs using these types of credentials:
API keys
OAuth 2.0 client IDs
service accounts
So, to answer you question, using OAuth 2.0 in GCP is certainly possible.
However, without knowing what data your application needs to access, it's hard to tell if it's more appropriate to use a service account or an OAuth 2.0 client. In a GCP project, if you go to APIs and services > Credentials > CREATE CREDENTIALS > Help me choose, a wizard will guide you through the process of creating the most appropriate credential for each authentication scenario:
Lastly, when you say this:
for users that have access to GCP
Do you mean that these users have a Google account that can access the Google APIs used in your project? If that's the case, and your project doesn't need to access user's data, then a service account might be a better choice than an OAuth 2.0 consent screen. I think you could let a service account impersonate a user via Domain Wide Delegation, but please keep in mind that Google itself discourages this feature.
See also Create access credentials.

How to read private Google Sheets using Google Sheets API without service account or downloading credentials

Background
I have a google sheet, who's data I need to process on my local system. The nature of processing is very tedious and long so I wrote a script for it.
Problem
I need to access the google sheet through the python script to process it further. Online it is mentioned that to read the private google sheet directly, I need to create a GCP project and within that project, I need to create a service account. After that I should download the credentials and share the google sheet with that service account email.
Two problems here are :
Downloading the credentials -- insecure and my organization prohibits it.
Sharing of google sheet with service account email. organization also prohibits sharing sheet with outside organization emails.
What I found as a solution
I came across a solution of impersonating a service account but I could not find anything as to how can I do that. (Would appreciate any insights on that). All the other solutions suggested to download credentials which is a big NO.
For the sharing of sheets thing, I guess we can use drive API, but same problems are with that.
I tried using gcloud auth login and gcloud auth application-default login but was getting errors
Request had insufficient authentication scopes.". Details: "Insufficient Permission: Request had insufficient authentication scopes.
using ['https://www.googleapis.com/auth/spreadsheets', https://www.googleapis.com/auth/drive'] as scopes
What I need? (Summary)
How to access google sheets API (or download the Sheet from google drive) without downloading any sort of credentials.json.
problem
Your only option to access private user data is to be authorized as a user who can access the file. Either logging in using Oauth2 or using a service account
Downloading the credentials -- insecure and my organization prohibits it.
In order to use a google api you must first register your application on google developer console and download the client credentials then a user must authorize the application using Oauth2, which would mean both downloading the credentials.json file from google developer console and you getting user token credentials from the authorized user.
Sharing of google sheet with service account email. organization also prohibits sharing sheet with outside organization emails.
In order to use a service account you would again need to first register your application on google developer console and download the client credentials for the service account. Then you would need to share the sheet with the service account.
service account impersonation.
Service account impersonation is used by GSuite domain. You create a normal service account again downloading the credentials, and then the GSuite admin is able to delegate authority to the service account which will allow it to impersonate a user on the domain.
This would require you to have GSuite domain and the owner of the file being also on the GSuite domain, and you creating a project on google developer console and downloading the credentials.json for the service account, which you already stated you couldn't do.
conclusion
I guess what i am saying is there is no way with the limitations imposed by your organization for you to access a private google sheet or any private user data on googles system, via any api.
I assume you're looking at an example that looks a bit like this:
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
SCOPES = ['https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive']
def main():
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
drive_svc = build('drive', 'v3', credentials=creds)
sheets_svc = build('sheets', 'v4', credentials=creds)
The library does it for you in two lines of code, but you can read the details of how this works at:
OAuth 2.0 for Mobile & Desktop Apps
The credentials.json file mentioned above is not an authorized set of user credentials. It consists of a client ID (public) identifier for your application and a client secret (private) known only to your application. Neither of these can be used to access your data, but they can be used to ask a user for permission to allow app access.
Your organization may have a policy disallowing data access from untrusted applications. In that case, you'll need your admin to trust your application (and your client ID). That's how the policy is intended to work.
A quick note on service accounts in Google Drive:
See the warning at Drive API - Authenticate your users. Generally speaking, service accounts should never act as themselves in Drive. They should only be used from an administrative capacity to impersonate users. They aren't, and shouldn't be relevant to your use case.

How to authenticate with gmail api from node container

I have been trying to create a connection with the gmail api. It worked when I followed this example: https://developers.google.com/gmail/api/quickstart/nodejs
The problem is, this requires the user to browse to a URL and then enter an authentication code in the CLI. This is possible on my local dev machine, but I don't see how this should be done when deployed on a production server, in a docker container. Additionally this method requires you to store a file in your project folder containing your credentials (sensitive data that I don't want to have in my Dockerfile obviously).
My second attempt was using JWT. I followed these steps Send mail via Google Apps Gmail using service account domain wide delegation in nodejs. This works until I actually try to retreive the email from the inbox. I get an error saying GaxiosError: unauthorized_client: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested.. I have created a service account with domain wide delegation so the account should be authorized to do anything.
Then I read this:
"Service accounts only work with GSuite because you have to be able to preauthorize the service account and grant it access to the users account. There is no way to preauthorize a normal user Gmail account. So no you cant use a service account with a normal users gmail account." source: Client is unauthorized to retrieve access tokens using this method Gmail API C#
I have also looked at using just an api key, but this option is not available for gmail.
How the hell am I supposed to authenticate from my container?
So it turns out the account I was using didn't have the correct rights. We did have a gsuite. Everything is working as expected now! :)

Google Drive users do not have permissions to read file

I would like to create an application where the users could access to all my data in Google Drive.
I have implemented a 2-legged OAuth to obtain all the data from Google Drive with my server app with no user authorization. The server can obtain all the data with the 2-legged OAuth.
The problem arrives when using, for example, the link of a drive document, the users connected to my app cannot access it due to they have no permissions.
I would like to know if it is mandatory give them permissions to access the files or maybe there is another service provided by google to have a comun storage for all the users without get the authorization or permissions for every single user.
I would like to know to if it is posible to use the Drive interface to show the users the documents.
There are actually three ways to access Google data.
Api key used to access public data.
Oauth2 used to access private data. Prompts for user to give permissions to access data and grants a refresh token.
Service accounts. Service accounts are preauthorized. there is no prompt to request a user permission to access the data.
I am not exactly sure what you mean by 2-legged Oauth. It sounds like you are talking about a service. You can grant the service account access to your personal drive account by sharing one or more folders with it. Note: I am not sure if you can share the root folder or not.
When you wish to allow one of your users to access a file you should have the service account add the user as reader of the file then they will have access. this can be done by inserting permissions.
Note. I am not a Node.js developer and I am not sure that service accounts are supported by Node.Js you may have to switch to a server sided language I don't know enough about it.
I do have a blog post that explains service accounts in more detail.

Access a user's Google Calendar events once having logged into a web app

I am creating a Node JS (Express) web app that will display a user's Google Calendar events, once they have logged in.
There will be multiple users, with data such as name and email address stored in a database.
Once a user has logged in, how can I retrieve a user's Google Calendar events associated to them without requiring any additional user input?
I have implemented Google's quick start sample here https://developers.google.com/google-apps/calendar/quickstart/nodejs
However this provides only access to a single authenticated user (authenticated via a terminal authentication process), with no opportunity to request a calendar of another user.
-
Question
How can I authenticate multiple users via a signup page (rather than using the nodeJS terminal) and access these google calendar events later via the data stored in a database? (Server side, with no interaction required )
Thanks
You can try to use Domain Wide Delegation in the Service Account. It is stated here that:
If you have a Google Apps domain—if you use Google Apps for Work, for
example—an administrator of the Google Apps domain can authorize an
application to access user data on behalf of users in the Google Apps
domain. For example, an application that uses the Google Calendar API
to add events to the calendars of all users in a Google Apps domain
would use a service account to access the Google Calendar API on
behalf of users. Authorizing a service account to access data on
behalf of users in a domain is sometimes referred to as "delegating
domain-wide authority" to a service account.
Just remember that you need a service account here to enable the domain wide authority. For more information, just read this link. It also discussed here on how to create service account.

Resources