Asserting identity to Google APIs with App Engine development server - google-app-engine

I have a Golang app running on App Engine and I would like to call the Analytics API to process some metrics. Both on App Engine and on the development server.
This page describes the overall procedure using a service account for server-to-server communication and getting an access token using OAuth2. I would like to avoid doing this myself so I found Google APIs for Go and the following that describes how to do it for App Engine.
I have added the App Engine app's service account email to Google Analytics for read access.
I have played around with queries using the Query Explorer and that works great. I have even used the API Query URI from here that includes the proper access token and that works fine. That works fine with cURL or calling it through urlfetch on App Engine.
What I need is to get hold of an access token automatically on App Engine and also while using the development server.
In here is an example for URL shortener which a have modified to use the Analytics API instead.
client := http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(c, analytics.AnalyticsScope),
Base: &urlfetch.Transport{Context: c},
},
}
svc, err := analytics.New(&client)
if err != nil {
return nil, err
}
data, err := svc.Data.Ga.Get("...")
The response in the development server is 401 Invalid Credentials, authError.
Is this supposed to work like this or am I missing something?
UPDATE
So, the problem is half solved. It works fine now using the development server when I pass in the service account's email and .pem file. However, that very same service account that is in App Engine does not work with the above code!
googleapi: Error 403: User does not have any Google Analytics account., insufficientPermissions
User should be the service account that I already successfully use on the development server, so I don't really understand this problem. It's the exact same code on App Engine and on the development server as well.
Google Analytics is set up to have read access and I use the read-only API. And it already works on the development server so that should be fine.
What might be different that is the issue?

It is possible to provide the development server with the necessary information at start like here.
$ dev_appserver.py --appidentity_email_address email --appidentity_private_key_path file.pem
And for App Engine you need to not use this Service Account but the one with the app name:
app_name#appspot.gserviceaccount.com

Related

Production App on Google App Engine suddenly lost access to Google Cloud Storage

Our production app (python 2.7 standard environment) running on Google App Engine suddenly lost permissions to write (create objects) on Google Cloud Storage, without any change in the code on our side.
The code is able to create new buckets, but not new objects within them.
It seems that the default app engine service account is not granted the permission.
Needless to say, the service account has the Storage Object Creator role, as well as the Editor role on the project level.
Strangely, the exact same code running on the test environment project, continues to work perfectly.
We are using the api client library to obtain credentials, like so:
from oauth2client.appengine import AppAssertionCredentials
from apiclient.discovery import build as discovery_build
credentials = AppAssertionCredentials(scope=scope)
http = credentials.authorize(httplib2.Http())
service = discovery_build('storage', 'v1', http=http)
And then using the service to make the api call.
All calls to create objects are suddenly failing with the message:
"Anonymous caller does not have storage.objects.create access to /"
Any ideas what could suddenly have gone wrong ??
This turned up to be an issue with Google Cloud Storage (GCS).
A payed support ticket was opened, after approximately 90 hours, a rollback was made by Google GCS engineers which solved the issue, however, the root cause of the issue was not found or reported.
Very troubling that a production app can be affected this way for such a long time and eventually there is no explanation.

Replacing the existing Project on Google Cloud Platform

I have deployed a Java Web application on Google Cloud platform and have purchased a domain and SSL Certificate from GoDaddy.com.
Its a simple application with a login page and a registration, where a specific(only one user) will have login credentials and post login will submit a form which will be saved in google DATASTORE in Google Cloud Platform(GCP).
I have two queries here :
1)
My application works perfectly,on my machine and even few machines around my home (as i have verified in few cyber centres around) but not at a client place located in different city(150 miles away). I'm not sure,as the client is not running any firewall or any browser plugin, as i have not visited the client place yet.
The call is as below.
Domain purchased from godaddy.com is : "ABC.in"
App engine project linked to this domain is : "web-abc"
If we hit "ABC.in" in browser it will in-turn call "web-abc.appspot.com".
in the background.Now though the login page loads,the client complains that the next subsequent pages does not load and page becomes blank.But for me in my system it works perfectly,as i can see the updated DATASTORE in GCP.
2)
Once i configure my DNS at GoDaddy.com, i'm unable to make any changes to the project hosted on GCP app engine.So i decided to create a new project and host it on the GCP. But GCP app engine page does not show any option to replace a project as it showed me during my first project setup.
I need to replace project "web-abc" linked to "ABC.in" with "web-pqr".
Please Please help...!
Thanks
To answer your second query you can just rest your CNAME record in the GODADDY DNS configuration and add the web-pqr reqq. That should work. Rest of the question< i really don't get it. Please share some error message or the screenshot when you try make change to your exiting project.

Issue authorizing access with google analytics super proxy

I'm setting up google analytics super proxy to create some public queries on my google analytics data. I have followed the instructions given in the below link to setup a analytics super proxy in app engine:
https://developers.google.com/analytics/solutions/google-analytics-super-proxy
I have followed the steps specified, enabling access for analytics api and creating a client ID for the super proxy web application deployed in app engine. I updated the required properties in the app.yaml and config.py files in the super proxy and deployed it to app engine.
I'm able to open the admin page of the deployed super proxy, but when I try to authorize access, I get the an error saying 'invalid_client' (although the client id seems to match with the one I created in developer console):
I'm unable to figure out what has gone wrong, or if I've missed something? Can you please help?
Regards,
Anand
Go to the Dev Console -> Your Project -> APIs & auth -> Consent screen. Make sure all the non optional fields are filed in (specifically in your case PRODUCT NAME).

Is it possible to access Google Play Game Services API with service account?

I've created the game thru Google Play Developer Console (it is ready for testing, but not published yet).
Two service accounts are added there as testers - myappid#appspot.gserviceaccount.com (Google App Engine service account) and 64436212345-enq9gkd1abcdefghjec2kha39je5ojsc#developer.gserviceaccount.com (manually created service account, it was created before an access to Google Play Game Services API was given). First one is used for production GAE environment, second one is for development environment (run with --appidentity_email_address). Both accounts work well with Google Analytics API.
Now I try to use these accounts to work with Google Play Game Services API.
The following code is used for authorization and works fine:
credentials = AppAssertionCredentials(scope=['https://www.googleapis.com/auth/games', 'https://www.googleapis.com/auth/plus.login'])
http = credentials.authorize(httplib2.Http(memcache))
But I am getting an error when trying to access achievements definition (also tried to get application metadata - got the same issue):
response = service.achievementDefinitions().list().execute()
In development environment I get
<HttpError 404 when requesting https://www.googleapis.com/games/v1/achievements?alt=json returned "The requested application with ID 64436212345 was not found.">
and in production:
<HttpError 500 when requesting https://www.googleapis.com/games/v1/achievements?alt=json returned "">
What is wrong there? Are service accounts supported by Google Play Services API?
Upd. Further analysis showed that 64436212345 is an ID of my GAE application, when an ID of my Google Play application is 760943112345.
So, I went to Google Developer Console for application 760943112345 and added 64436212345-enq9gkd1abcdefghjec2kha39je5ojsc#developer.gserviceaccount.com and myappid#appspot.gserviceaccount.com as the member their. It didn't help.
Then I generated new service account ID there and run GAE locally with this service account. In result, I've started to get
<HttpError 401 when requesting https://www.googleapis.com/games/v1/applications/760943112345?alt=json returned "User has not completed registration.">
Of course, my service account doesn't have Google+ profile.
I am also struggling with service accounts and Google game services, and am stuck at the same point (my service account doesn't have a G+ account).
The only indication I have found in the Google literature (supposedly Updated Jan 22, 2014) says service accounts are not supported:
Warning: Very few Google APIs currently support Service Accounts. Service accounts are >currently supported by the following Google developer services:
Google Cloud Storage
Google Prediction API
Google URL Shortener
Google OAuth 2.0 Authorization Server
Google BigQuery
This is embedded in some google api php client documentation however, so I cannot attest its validity.
Let me know if you have any luck getting this to work and I'll do the same!
Edit: here is the actual answer:
You have to create another API project and link it to your game's project, as explained in Getting Started with the Google Play Games Services Publishing API. The service accounts that you add to your game's project won't work. Also, you have to add this new API project through Google Play Developer Console, and not through Google Developers Console. As far as I remember, you go to the latter to get your key only. This whole situation took me forever to figure out.
I'm keeping the below text for future reference:
Edit: I wrote the answer below, thinking that you did not talk about the Publishing API. But you are, it seems. Or an earlier version of it. I hope the below answer will be useful for people looking to access Management API with a service account:
I struggled with the same and concluded that service accounts do not work with the GPGS Management API, which is the API that deals with achievements and things of that sort. Here are the facts that I used to reach this conclusion:
The only place in GPGS docs that service accounts are mentioned is the Publishing API.
Management API Docs contains descriptions for each function about the authorization requirements such as: "This method is only available to user accounts for your developer console.", while Publishing API Docs have no such descriptions.
The sample app for Management API does not use a service account.
It would be nice if this was a bit clearer in the GPGS docs. The generic Google Cloud docs that they link from GPGS pages made me believe that service accounts would work.

OAuth: Starting a Google Compute Instance from within Google App Engine

I have a Google App Engine web app that runs the majority of my site. However, for certain functions, I need a linux machine. I would like my Google App Engine app to automatically spin-up a Google Compute Instance on certain events.
I understand that you can add Google Compute instances using the Compute Engine REST API. However, in order to access the Google Compute REST API, you need to get an access token using the OAuth2 authentication process.
How can I programmatically get an access token from within Google App Engine?
It seems that all of the authentication methods require a window to appear so you can type in your username and password, which is impractical from within Google App Engine.
Here is a complete example of using service accounts and App Engine cron tasks to stop instances after they've been running for a while:
(opposite of starting instances, but the authorization code will be the same)
https://github.com/GoogleCloudPlatform/compute-appengine-timeout-python
AppAssertionCredentials handles the access token using this code:
# Obtain App Engine AppAssertion credentials and authorize HTTP connection.
# https://developers.google.com/appengine/docs/python/appidentity/overview
credentials = AppAssertionCredentials(
scope='https://www.googleapis.com/auth/compute')
HTTP = credentials.authorize(httplib2.Http(memcache))
# Build object for the 'v1beta15' version of the GCE API.
# https://developers.google.com/compute/docs/reference/v1beta13/
compute = build('compute', 'v1beta15', http=HTTP)
You should be able to use the service account associated with your project to authenticate to the Compute Engine API and launch VMs.
Documentation on service accounts suggests that the following python code should fetch a service account token.
import httplib2
import discovery
from oauth2client.appengine import AppAssertionCredentials
...
credentials = AppAssertionCredentials(
scope='https://www.googleapis.com/auth/compute')
auth_http = credentials.authorize(httplib2.Http())
compute_service = discovery.build('compute', 'v1beta15', http=auth_http)
I'd thought that the Google I/O demo from this year where they built a video-sharing site was going to be available, but I don't see it on GitHub yet. There are a number of demos that use AppEngine to control GCE, but most of them seem to use the user's project and credentials, rather the app's own credentials.
Obviously, you probably don't want to spin up a VM on direct user input unless you've got a very large budget or some form of rate limiting in place, but it's quite helpful to spin up a VM now and then when you've got a lot of computation to do. (Transcoding, etc.)

Resources