I'm trying to delegate my Google contacts (not GMail) to another account (same Workspace). People API does not have the option to delegate contacts so I tried Google Admin SDK - Contact Delegation API. However, I can't find a way to build the resource like other APIs.
How can I create the resource and then delegate my contacts? And what is the scope I need to allow for the credentials to work?
For other APIs, I use this code :
from googleapiclient.discovery import build
# Load client_config
# Define scopes to autorize like -> scopes = ['https://www.googleapis.com/auth/admin.directory.user']
# Get the credentials into the creds variable
admin_service = build('admin', 'directory_v1', credentials=creds)
# use admin_service to create/update users in the workspace
My end goal is to use a service account with delegated access to impersonnate users and automatically delegate gmail and contacts. I've been able to get the gmail delegation to work, but not the contacts delegation.
I'm fairly new with Google APIs so I may have overlooked something in the documentation.
The issue has been closed. It was not intended to have a discovery file, thus the clients cannot use it to generate the required methods. What you need to do is to make the calls to the REST API directly. Just remember to add the OAuth token on the headers.
Related
we want to use default application credentials (python code running in GCP) to perform domain-wide delegation to access Gmail/Drive APIs. The main reason for this is that using default credentials alleviates us from needing to create/manage a gcp service account key (which is very sensitive), whereas code running in GCP (appengine/cloud functions) handles key management for us securely.
We know that Google's professional services have published how to do this for accessing Admin SDK APIs here, however, we're not able to make this work with Gmail/Drive APIs.
Does anyone know if this is technically possible, and if so how?
For what I understood from your question you don't want to use a Service Account, but instead some Application Default Credentials (ADC).
Basically, you will always need to use a Service Account, but if you are running your app on Compute Engine, Kubernetes Engine, the App Engine flexible environment, or Cloud Functions, it will not be necessary for you to create it in your own as it is stated HERE.
You will only need to get the credentials needed to your project and then you will able to call the Gmail API as you would normally do:
from google.auth import compute_engine
credentials = compute_engine.Credentials()
I'm creating a Google App Engine project which is going to automatically trigger a function each 5 minutes to analyze a Google sheet.
OAuth authorization
The to-be-analyzed sheet is a G Suite sheet, public to only company members. So I need OAuth2 to authorize the access. How do I do this?
I think I need a Service Account client ID, because as this is going to run automatically in the server, there cannot be a OAuth2 flow, right? Who is going to click the buttons if the function is ran in the server?
I need some directions.
Thanks
https://developers.google.com/identity/protocols/OAuth2ServiceAccount
Yes, it is an OAuth2 flow, but not one involving a manual user operation - the actions are performed by the servers, automatically, based on pre-configured information. From the very document you mentioned:
The Google OAuth 2.0 system supports server-to-server interactions
such as those between a web application and a Google service. For this
scenario you need a service account, which is an account that belongs
to your application instead of to an individual end user. Your
application calls Google APIs on behalf of the service account, so
users aren't directly involved. This scenario is sometimes called
"two-legged OAuth," or "2LO." (The related term "three-legged OAuth"
refers to scenarios in which your application calls Google APIs on
behalf of end users, and in which user consent is sometimes required.)
Basically you need:
on the GAE side to locate an existing (or create a new) service account for your app (in the cloud project's IAM & Admin Service Accounts page). One service account is automatically created when your app is created.
on the G Suite side to allow access by Delegating domain-wide authority to the service account:
To delegate domain-wide authority to a service account, first enable
domain-wide delegation for an existing service account in the Service
accounts page or create a new service account with domain-wide
delegation enabled.
Then, an administrator of the G Suite domain must complete the
following steps:
Go to your G Suite domain’s Admin console.
Select Security from the list of controls. If you don't see Security listed, select More controls from the gray bar at the bottom
of the page, then select Security from the list of controls. If you
can't see the controls, make sure you're signed in as an administrator
for the domain.
Select Show more and then Advanced settings from the list of options.
Select Manage API client access in the Authentication section.
In the Client Name field enter the service account's Client ID. You can find your service account's client ID in the Service accounts
page.
In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your
application needs domain-wide access to the Google Drive API and the
Google Calendar API, enter: https://www.googleapis.com/auth/drive,
https://www.googleapis.com/auth/calendar.
Click Authorize.
Your application now has the authority to make API calls as users in
your domain (to "impersonate" users). When you prepare to make
authorized API calls, you specify the user to impersonate.
Finally I solved it this way:
Setup a new App Engine service account (I don't know if a "new" one was neccesary really)
Take note of that new service account email
Share the Sheet with that service account mail (I've not yet tested it without this step)
Download its service secrets as a JSON.
Use this code(inspired in (1) and (2))
class analysisHandler(Handler):
def get(self):
credentials = ServiceAccountCredentials.from_json_keyfile_name('service-secrets.json',
["https://www.googleapis.com/auth/spreadsheets"])
http = httplib2.Http()
#if credentials are still valid
if not credentials.invalid:
logging.info("Valid credentials, entering main function")
http = credentials.authorize(http)
main(http)
else:
credentials.refresh(http)
main(http)
Then in main():
sheetService = discovery.build('sheets', 'v4', http=authorized_http)
logging.info("Reading Google Sheet")
result = sheetService.spreadsheets().values().get(spreadsheetId=spreadsheet_id, range=range_name).execute(http=authorized_http)
urlfetch.set_default_fetch_deadline(45)
logging.info("Printing in Google Sheet")
sheetService.spreadsheets().values().append(spreadsheetId=spreadsheet_id, range="Log", body=body, valueInputOption="USER_ENTERED").execute(http=authorized_http)
Where the authorized_http parameter is the one built before with credentials.authorize()
I think this can be improved however.
(1) How to use "Service account" authorization (rather than user based access refresh tokens)
(2) Creating and sharing Google Sheet spreadsheets using Python
The documentation google + domains api to create a post using the 'service' object, obtained here by this method. But in my project to authenticate via google and other sites I use the python social auth
and after authorization I have a ready access token.
The problem lies in the fact that I need a service object to work with api, but I can not figure out how to get it already having access token. Please help me and sorry for my english.
For the domains API, you typically will implement using a service account authorization flow - which is not retrieved in the same way as a user OAuth flow. This is because service accounts can be authorized for services that users typically should not be authorized for (e.g. retrieving domain-wide lists of user names).
The service account credentials, used to authorize your application, are created using the Google Developer Console and then are downloaded as a JSON or p12 file that is used to authenticate your Python client, as shown in this example.
That said, you still can do some actions with that access token which is why the auth flow you're seeing is doing this. Service credentials are how you should be authorizing for domains-related management features which may explain the behavior you're seeing.
I try to use
service = build(service_name, "v1", http=http)
to access Google Groups Provisioning APi. However, I tried difference names: provisioning, groupsprovisioning, etc but unsuccessful. Does anyone know the name of Groups Provisioning service? How can I search for the list of the service names available in Google Apps API.
The Google Apps API is not available via the new API client. You need to use the old GData client, as documented on the Apps Provisioning API page.
To answer your second question, you can use the APIs Discovery Service to list the names of all the new-style APIs.
I want to get the list of all the users for the domain on a GAE app (using python). When I hit this URL https://apps-apis.google.com/a/feeds/domain/user/2.0 . I get an authorization error. How can I authenticate for this GET hit.
You'll need to use the Provisioning API, and you'll need to authenticate via OAuth first
To expand on the answer from Chris, prepare for a bit of pain around authentication. You have four options for read-only access, and one if you need read/write:
Marketplace authorization: if your app is on the Google Marketplace and a domain admin added you to the domain, you can use your app's Google Marketplace keys to access the provisioning API in read-only mode.
Domain OAuth: if you can get the domain admin to make a configuration change for you, your app can use the domain-wide OAuth keys for read-only access.
3-legged OAuth: if you are dealing with a superadmin user, you can request that they grant you temporary right to access the API in read-only mode.
Programmatic Login: lastly, you can ask them to give you an admin account username and password to login into the provisioning API. This is the only mechanism that will give you the ability to change anything.