According to the new Google Apps Marketplace documentation, in order to get the status of a user license, it should be enough to make a simple GET request to https://www.googleapis.com/appsmarket/v2/userLicense/{applicationId}/{userId}?key={ApiKey} where applicationId is a number, userId an email and ApiKey a string taken directly from the Google Cloud Console under APIs -> {App name} -> Server Key -> Api Key. I have also enabled the Google Apps Marketplace API in Google Cloud Console.
However, I always get the following error message:
{"error":
{"errors":[{"domain":"global","reason":"authError","message":"Invalid OAuth header","locationType":"header","location":"Authorization"}],
"code":401,"message":"Invalid OAuth header"}}
Can you help me?
EDIT: Following Arun Nagarajan's suggestion, I tried using a scope, but it still does not work. Here is my code (in Python on Google Appengine):
credentials = oauth2client.appengine.AppAssertionCredentials(scope='https://www.googleapis.com/auth/appsmarketplace.license')
http = credentials.authorize(http=httplib2.Http())
client = apiclient.discovery.build('appsmarket', 'v2', http=http, developerKey='XXXXXXXX')
entry = client.userLicense().get(applicationId='123456', userId='some_user#email.com').execute()
You have to use OAuth 2 with the https://www.googleapis.com/auth/appsmarketplace.license scope.
You cannot just get the license with just the server key.
Related
I want to create an automatic deployment of GCP for clients.
In order to do that, I have opened a page for them to login with google, and then enabled the IAM API and the Service Usage API.
Then I have created a service account that I want to use from this point forward in order to enable other required APIs on demand and not all at once.
When I try to enable the cloudkms API, I get
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://serviceusage.googleapis.com/v1/projects/x-y-z/services/cloudkms.googleapis.com?alt=json returned "The caller does not have permission"
I tried using the service account credentials (google.auth.jwt.Credentials) that I have created from the response of creating the service account, and I have added all the required permissions. I don't want to grant the role owner to the service account, because I want the account to have as less permissions as possible.
When I try to get the status of cloudkms API using the user's permissions, it works.
I have seen some solutions addressing me needing to create credentials for the service account here : https://console.developers.google.com/apis/credentials but I really need to do this programatically as well.
My code:
credentials = jwt.Credentials.from_service_account_file(service_account_info['email'] + '.json', audience="https://www.googleapis.com/auth/cloud-platform")
# credentials = GoogleCredentials.get_application_default() - it works with this
service_usage = googleapiclient.discovery.build('serviceusage', 'v1', credentials=credentials)
service_usage.services().get(name="projects/<project_id>/services/cloudkms.googleapis.com").execute()
The error was mentioned above.
You need the Cloud IAM permission serviceusage.services.enable to enable services. Depending on what features your require, such as listing services, you need serviceusage.services.list.
Typically you add the role roles/serviceusage.serviceUsageAdmin which includes the following permissions:
serviceusage.services.get
serviceusage.services.list
serviceusage.services.enable
serviceusage.services.disable
Goto IAM
Edit user selected
Add new rol
Type Service Usage Admin
Save
I tried to get data from Google Analytics API with Python client(google-api-python-client). Here's the code I used:
from apiclient import discovery
from oauth2client.client import SignedJwtAssertionCredentials
from httplib2 import Http
with open("ManagementGate-622edd43c0dd.p12") as f:
private_key = f.read()
credentials = SignedJwtAssertionCredentials(
'XXXXXXXX#developer.gserviceaccount.com',
private_key,
'https://www.googleapis.com/auth/analytics.readonly')
http_auth = credentials.authorize(Http())
service = discovery.build('analytics', 'v3', http=http_auth)
result = service.data().ga().get(
ids='ga:79873569',
start_date='7daysAgo',
end_date='today',
metrics='ga:visits,ga:sessions,ga:pageviews').execute()
I created a Service Account on Credentials Page. However, I got an error as below:
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/analytics/v3/data/ga?metrics=ga%3Avisits%2Cga%3Asessions%2Cga%3Apageviews&alt=json&end-date=today&ids=ga%3A79873569&start-date=7daysAgo returned "User does not have any Google Analytics account.">
The instructions I followed are from: https://developers.google.com/accounts/docs/OAuth2ServiceAccount
Is there anything else I need to do? And why did I get this error? I already enabled Analytics API on APIs page.
You are trying to access the Google Analytics API using a service account. A service account by default does not have access to any Google Analytics accounts.
What you need to do is take the Service account email address from the Google Developer console. Go to the Admin section of the Google Analytics Website. Give this service account access at the ACCOUNT level it must be the ACCOUNT level to the Google Analytics account you wish to access.
It wont work at the Web property or the view level it must be the Account level.
When I follow the Quickstart Tutorial: https://developers.google.com/drive/web/quickstart/quickstart-python
Entering the URL for authentication shows the following error on the website:
Error: disabled_client
The OAuth client was disabled. Request Details
cookie_policy_enforce=false
scope=https://www.googleapis.com/auth/drive
response_type=code
redirect_uri=urn:ietf:wg:oauth:2.0:oob
access_type=offline
client_id=1086226639551-hgv3m4atq7jmsdgie1d5t92qbo8k9b1g.apps.googleusercontent.com
I created id and secret for an "Installed Application" in the developer console:
https://console.developers.google.com/project
And selected "Other" as application type.
Any idea what causes the problem might help.
[EDIT] I just used PyDrive for authentication without problems:
https://github.com/googledrive/PyDrive
So I will settle for PyDrive.
I have a google app engine site, and what I want to do, is get access to the files on my drive and publish them. Note that, my account owns both the drive and the app engine page.
I have tried looking at the google drive api, and the problem is that I don't know where to start with the following boilerplate code located in their documentation.
If you take a look at this function:
def get_credentials(authorization_code, state):
"""Retrieve credentials using the provided authorization code.
This function exchanges the authorization code for an access token and queries
the UserInfo API to retrieve the user's e-mail address.
If a refresh token has been retrieved along with an access token, it is stored
in the application database using the user's e-mail address as key.
If no refresh token has been retrieved, the function checks in the application
database for one and returns it if found or raises a NoRefreshTokenException
with the authorization URL to redirect the user to.
Args:
authorization_code: Authorization code to use to retrieve an access token.
state: State to set to the authorization URL in case of error.
Returns:
oauth2client.client.OAuth2Credentials instance containing an access and
refresh token.
Raises:
CodeExchangeError: Could not exchange the authorization code.
NoRefreshTokenException: No refresh token could be retrieved from the
available sources.
"""
email_address = ''
try:
credentials = exchange_code(authorization_code)
user_info = get_user_info(credentials)
email_address = user_info.get('email')
user_id = user_info.get('id')
if credentials.refresh_token is not None:
store_credentials(user_id, credentials)
return credentials
else:
credentials = get_stored_credentials(user_id)
if credentials and credentials.refresh_token is not None:
return credentials
except CodeExchangeException, error:
logging.error('An error occurred during code exchange.')
# Drive apps should try to retrieve the user and credentials for the current
# session.
# If none is available, redirect the user to the authorization URL.
error.authorization_url = get_authorization_url(email_address, state)
raise error
except NoUserIdException:
logging.error('No user ID could be retrieved.')
# No refresh token has been retrieved.
authorization_url = get_authorization_url(email_address, state)
raise NoRefreshTokenException(authorization_url)
This is a part of the boilerplate code. However, where am I supposed to get authorisation_code from?
I recently had to implement something similar, and it is quite tricky to find the relevant pieces of documentation.
This is what worked for me.
One-time setup to enable Google Drive for your Google App Engine project
Go to the Google APIs Console and select your App Engine project. If you don't see your App Engine project listed, you need to enable the cloud integration in the App Engine admin tool first (Administration > Application Settings > Cloud Integration > Create project)
In Google APIs Console, now go to Services and look for the "Drive API" in that long list. Turn it on.
Go to the API Access section on Google APIs Console, and find back the "Simple API Access" API Key. (see screenshot below)
Getting and installing the Python Drive API Client
Download the Python Drive API Client: https://developers.google.com/api-client-library/python/start/installation#appengine
Documentation on this Python API: https://google-api-client-libraries.appspot.com/documentation/drive/v2/python/latest/
Using the Python Drive API Client
To create the Drive service object, I use this:
import httplib2
def createDriveService():
"""Builds and returns a Drive service object authorized with the
application's service account.
Returns:
Drive service object.
"""
from oauth2client.appengine import AppAssertionCredentials
from apiclient.discovery import build
credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/drive')
http = httplib2.Http()
http = credentials.authorize(http)
return build('drive', 'v2', http=http, developerKey=API_KEY)
You can then use this service object to execute Google Drive API calls, for example, to create a folder:
service = createDriveService()
res = {'title': foldername,
'mimeType': "application/vnd.google-apps.folder"}
service.files().insert(body=res).execute()
Caveats
I was not able to get the Drive API to work in unittesting, nor on the dev_appserver. I always get an error that my credentials are not valid. However, it works fine on the real app engine server.
I'm getting an error while calling the Reports API:
<HttpError 403 when requesting https://www.googleapis.com/admin/reports/v1/usage/users/all/dates/2013-08-01?alt=json&maxResults=1 returned "Caller does not have access to the customers reporting data.">
Have anyone seen this error before? What am I missing?
I just can't see why this is showing or what I should be checking.
Regards.
EDIT:
Auth:
credentials = SignedJwtAssertionCredentials(
service_account_name='5163XXXXX#developer.gserviceaccount.com',
private_key=oauth2_private_key,
scope='https://www.googleapis.com/auth/admin.reports.usage.readonly')
# https://developers.google.com/api-client-library/python/guide/thread_safety
http = credentials.authorize(httplib2.Http())
service = apiclient.discovery.build('admin', 'reports_v1', http=http)
The actual call:
result = service.userUsageReport().get(
userKey='all',
date='2013-08-01',
maxResults=1).execute()
Other APIs just work fine with that service account.
'https://www.googleapis.com/auth/admin.reports.usage.readonly' has been properly added to OAuth2 domain config page.
Try:
credentials = SignedJwtAssertionCredentials(
service_account_name='5163XXXXX#developer.gserviceaccount.com',
private_key=oauth2_private_key,
scope='https://www.googleapis.com/auth/admin.reports.usage.readonly',
sub='super-admin#yourdomain.com')
when using Service Accounts with Admin SDK, you still need to act on behalf of an admin within the Google Apps instance.
Also, make sure that the Service Account Client ID has been granted rights to use the Reports API scopes in the Google Apps Control Panel. The Google Drive docs describe this process well, just sub in the Reports scopes instead.