Using Actions on Google and Google Drive together? - google-drive-api

I'm a hobbyist student developer playing around with the Actions on Google to create a simple "text adventure" game on Google Home. Since Google Home will be speaking to the player rather than the player reading the text, I'm hoping this will create an experience similar to the "Dungeons and Dragons" roleplaying game, with the computer working as the "Dungeon Master." With the natural language assistance offered by API.AI and Actions on Google, it seemed like a good fit, since the player can respond "naturally." Here's an example of an Amazon Alexa skill that does essentially what I'm going for.
However, every time I boot up the game, it's always a new game. I'd like to store a savegame with the user's previous state in a JSON file hosted on the user's Google Drive -- Since I'm just a student doing this for fun, I don't actually have an official website or anything beyond a free Heroku server I'm running the app from, making storing saves on my end pretty much out of the question.
I've walked through the Google Drive REST quickstart for Node.js, and I've gotten that working in the console just fine. The only problem is in that quickstart, the user has to click a link to authorize the application to read the stuff in their Google Drive account, and I'm not sure how I'd be able to "click a link" and give back an access token via voice on Google Home.
Is there a way to do this via Google Drive? Or is there a better way to provide persistent data between sessions? I don't normally work in web development, so any help would be appreciated.

The bad news is you won't be able to get away from the need for a user to use his web browser to authorise your app to access his Drive.
The good news is that you only need to do this once. When your app requests authoirsation, it should specify "offline", which will result in you being given a refresh token. You should save this somewhere in your database of users. Whenever you need to access the user's Drive, you can use the saved refresh token to request an access token and you're good to go.

You have a few problems that you need to solve here, and while they seem related, they're not as related as you might hope:
You need to get authorization to access a user's Drive space
You need to authenticate the user's Home (so you know this person has come back)
You have to connect the two relationships - so you know what Drive space to use for the Home device that is talking to you
You've found the answers to (1) already, and as noted, you'll need to use a browser for them to authorize you to access their Drive. You'll then store the refresh token and will be able to access it in the future.
But that is only part of the problem. Home does not provide you access to the user's Google account directly, so you'll have to manage your own account mechanism and tie it to Home. There are a few solutions here:
Home provides anonymous user identity in the JSON sent to your webhook. You can access this using getUser().user_id if you're using the Actions API library, or access this in the data.user.user_id field in the JSON. While this is similar to a browser cookie, it only stores the user ID and can't store additional data. There is also no concept of "local storage". On the plus side, this ID is consistent across devices.
You can request user information such as their name and address. But it doesn't have anything unique or account information, so this probably isn't useful to you.
You can implement an OAuth2 server and do account linking. Note that this is the other side from what you need to do with Google Drive - you'll be providing the access and refresh tokens to authenticate and authorize access to your account and the Google Home device will send these tokens back to you so you can determine who the user is. You don't actually need to store account information - you can provide token information using JSON Web Tokens (JWT) or other methods and have them store account information in a secure way. Users will use the Google Home app to actually sign-in to your service as a one-time event.
In order to handle (3), you may be thinking that (1) lets you get tokens and the OAuth solution for (2) requires you to hand out tokens. Can the two be combined? Well... probably, but it isn't as straightforward. You can't just give the Google OAuth2 endpoints to Home - they explicitly block that and you need to control your OAuth2 endpoints. You may, however, be able to build proxy endpoints - but I haven't explored the security implications of doing so.
I think you're on the right track - using Drive is a good place to store users' information. Using Home's account linking gives you a place where they have to come to your web site to authenticate and authorize their Home, and you can use this to do the same for their Drive.

Related

Simple Esri/ArcGIS Online connection using a link or iframe

I was asked by a potential client if I can have my software interact with Esri/ArcGIS Online.
Use case: users is logged into SomeRandomSoftwareApp and is looking at a Widget, this Widget includes an Esri asset id, the user clicks a link that passes that ID to Esri/ArcGIS Online and behind the scenes the user is logged into Esri and they see the data associated with the Esri/ArcGIS Online.
Thanks, Keith
If I understand correctly, you have two options for this: API Keys or Application Credentials.
The first one, is a permanent token generated by the owner of the data that will allow the application easy access to it. This is still in beta, and it was not ready for use the last time I check some time ago.
The second one, the owner of the data will generate credentials for your application. With this credentials you will have to request a token each time you want to access the data, all this via OAuth 2.0.
Check the docs for more details ArcGIS Services - Security

Reading other user's Google Fit data via REST API

We have a user who gave consent for our Cloud Project to read their Fit data through the Android app. We now want user's coach to access their Fit data through a web UI associated with our Cloud Project. Is this possible, and if so, what is the right way to do it?
Can cross-client identity be used? https://developers.google.com/identity/protocols/CrossClientAuth
I was trying to replace "me" with "user#gmail.com" in the REST endpoint but it doesn't work:
https://www.googleapis.com/fitness/v1/users/me/... ->
https://www.googleapis.com/fitness/v1/users/user#gmail.com/...
Thanks!
There is a mechanism for Android apps to obtain offline access for web back-ends highlighted in the CrossClientAuth guide from your question. With offline access, you can theoretically serve or store that data in any way that the user has consented to. Any access controls of that data to another person is something that you'd have to handle on your own.

Access Google Drive API without creating WebApp?

First I apologize if I'm a dolt and am missing something obvious, but I've spent a few hours scouring documentation and am lost.
I'm trying to write a python script that will upload a bunch of images to a single user's Google Drive. The user already exists and will never change. I am not writing a web app and don't plan to use any user interface whatsoever. Everything will be done through code.
As best I can understand from the Google documentation, I have two choices:
1) Write a web app and register it to use the Drive DSK. This of course requires having urls and such for the web app.
2) Create a service account, which ties my "app" to a new service account email.
Neither of these options works for me. Is there any way to simply log in to a single user account and access their drive through python scripting?
There is a deprecated API called ClientLogin that would enable you to use the username and password for a login to access that Drive data.
But the basic idea is that you should be using something more secure -- from your users' point of view -- that allows them to authorize you without giving you their password.
For your use case it is possible that the user is you or someone you know and that you are accessing their account through a more personal kind of authorization. In that case, ClientLogin may be your best choice. If this is an application designed to be used by arbitrary users, the deprecation of ClientLogin is for a good reason and I would urge you to bite the bullet and choose one of the supported options.
The correct solution is to separate the authorization phase from the access phase. The authorization process needs to be run one time only, and can be done from a simple web site. The result of this is a refresh token which is analogous to a username/password. You will need to be aware of the security implications. Make sure you only grant drive.file scope to minimise the impact of a security breach.
Since you are uploading images, you might also want to look at the picassa api.

Second authorization with same scope and offline access_type has unexpected permission dialog

If I specify access_type=offline in the auth url and a user attempts to auth a second time I get a box that says it is asking for offline access.
I would have expected it to be already authorised and so not require additional permissions
Any ideas?
Edit:
A bit more info. The first time around it makes no mention to the user of needing offline access. I would have thought the offline permission to be mentioned in the original auth anyway.
Edit 2:
Some more info on my use case. It is possible in our system for a person to have two accounts but then use the same google drive account. This means that we have no way of knowing that user has already authorized with google and so have to present the authorization again for the second user.
The first time around (for user 1) you are told that the app is asking for :
View and manage Google Drive files that you have opened or created
with this app
View and manage the files and documents in your Google
Drive
The second time around (for user 2) you are told the app is asking to:
Have offline access
This seems wrong to me.
As an aside:
The whole "have offline access" statement is very confusing for a user and also quite misleading. Most people assume this means the app can read the contents of your pc. In fact it means that the app can authenticate with your account with out you being there (i.e. using a refresh token).

Directing user from one app script as an anonymous user to another app script behind a domain

I am deeply into learning about App Script but there is so much the Google has to offer I'm a bit overwhelmed at figuring out what I need.
I'm designing an online volunteer application work-flow and eventually other things for a non-profit organization.
Here is how I envision the process flow going.
New user comes up first Web App page asks for first last middle and email address
First Last Middle are used together in some way to create a domain log on for the user using the provisioning API (already figured this part out) while prompting the user to create a password
At this point the user is passed to the actual application web app that runs only for domain users so that the relaxed rules of app script for user behind a domain can be leveraged and also so the entire ebb and flow of information stay behind our domain.
Now where I am unclear on is the jump from step 2 to step 3.
What would be the best and most painless (for the user not me) way to put together the transition from running the entry point app that creates the new users domain account as essentially an anonymous user identity to running the domain level app AS their new domain user identity.
I've been studying OAUTH but it seems that is more for external integration with things like drive and youtube etc. My goal with this project is to have everything (aside from things like client side validation and jQuery) running from Google's Cloud.
In #2 i asusume you have a pool of unused gapps accounts.
In #3 you need to get the user logged in in gapps first . For that you need to show a special login url that will redirect to fhe other app. Another is to do a manual oauth flow and use the redirect url to get to fhe new app.