google API - python outh2 application authentication - python

I have a simple scenario for which I can't find solution. I'd like to use Docs API for my application, but I want to use only one application account to store documents and perform all the API calls. So I don't want to use all this redirect_uri stuff, that needs any kind of user interaction - only my app and it's own Google account.
I've found similar question here: gdata-python-api + Analytics with simple auth but the solution still involves user interaction (yes, probably only once but I still don't like it as most of the interactions with API will be done by some daemon).
I'm using gdata-python-client for interactions with API. I'm not sure if I understand correctly if ServiceAccount authentication might be a solution, but couldn't find any examples of how to perform it via gdata-python-client lib (can somebody share working code?).

To access the documents owned by this single user, you must have an access token for that user. There's not really any way around this. The access token is how Google identifies your project, which user's data you'd like access to, and that you have all of the necessary permissions granted.
It sounds like you've already found the solution: You must go through the OAuth 2.0 dance at some point in time and store the refresh_token for subsequent access. Be aware, though, that refresh_tokens may not last forever. For example, if access is revoked, it will stop working. For this reason, it's wise to expose the ability to execute the OAuth 2.0 dance again from an administrative page in your application.

Related

Is there a way to retrieve Google Analytics 4 data on a schedule using Node.js?

This is what I want to achieve:
Ask the user to authorize the collection of their data on a Google Analytics 4 property (or Universal Analytics but I would rather not)
Programmatically retrieve and store the data every n-hours
I was able to do (1) client-side by asking for authorization with google's OAUTH2 and making a call to Reporting API v4 https://developers.google.com/analytics/devguides/reporting/core/v4 using gapi on the front-end.
However, I'm not sure how to do it on a schedule without user interaction. I've searched Google's API docs and I believe there's a way to do it in python https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-py but I am currently limited to Node and the browser. I guess I could make a server in python that does the data fetching and connects with the Node application, but that's yet another layer of complications that I'm trying to avoid. Is there a way to do everything in Node?
GCP APIs are all documented in a way which allows everyone to generate client libraries in a variety of languages, including node.js. The documentation for the node.js client for Analytics Reporting is here.
For the question of how to schedule this on GCP, I would recommend you to use Cloud Scheduler. This will hit an endpoint running on Cloud Run, which will do the actual work. Alternatively, if you already have a service running somewhere else, you can simply add the required endpoints there and point Cloud Scheduler to it.
The overall design which I would suggest you goes something like this:
Build a site which takes the user through the OAUTH2 login process,
requesting the relevant Google Analytics Reporting API scopes
required to make the request.
Store the obtained credentials in their user database.(preferably
Firestore in Datastore mode)
Set up a Cloud Run service (or anything else), with two endpoints
Iteration endpoint: Iterate through the list of users and add tasks
to Cloud Tasks to hit the download endpoint for each one.
Download endpoint: Takes a user ID (e.g. as a query parameter) and
performs the download for this user. You will need to load the
credentials for the user from the database and use this to access the
reporting API.
Store the downloaded data in the desired location, e.g. Cloud
Storage, Firestore, Cloud SQL, etc.
Set up Cloud Scheduler to hit the iteration endpoint at the desired
frequency.
For the GCP services mentioned above, basically everything other than Analytics, you may use the "cloud" clients for node.js, which are available here
Note : The question you have asked is a very broad question and this answer is just a suggestion. You may think about other designs whichever works best for you.

How to Authenticate to use the YouTube API from a Cloud Function (Python 3)

I can successfully authenticate with the pattern outlined here:
https://developers.google.com/youtube/v3/docs/videos/list?apix=true
for a simple prototype in Google Colab. However I cannot for the life of me figure out how to authenticate in a Cloud Function as there is no user to complete the flow. I'm sure it's a standard pattern, however I'm more familiar with the GCP APIs and the googleapiclient is a new one for me.
I have set up service account credentials with the right access, but I'm not even sure whether it makes sense to use these in a Cloud Function (maybe stored on GCS), or whether there is (as I hope) a more elegant solution.
Any help would be hugely appreciated, thanks!
Not really familiar with Youtube Data API, however based on the API reference for some details you need to issue a call as a video owner (e.g. processingDetails). This means that you need to use three-legged OAuth2 flow. For that you can either:
Setup another function that will generate an authorization URL ->
present it to the user -> setup another function as redirect_uri to
obtain authorization code -> exchange it for access and refresh
tokens -> store refresh token someplace safe where original function
can fetch it.
Obtain refresh token outside of Cloud Functions and hardcode it.
Hardcoding credentials is generally not a good practice, hence a better option would be to have a service account make requests on behalf of a user, but this is only possible for GSuite users via domain-wide delegation. With this, after setup, you would use sub claim with the email address of the impersonated user. You can see more here (make sure to switch to HTTP/REST to understand how JWT is created or, if you're not interested in details, just select Python.

Azure AD / Python AA

I have a quite simple usecase. From my product I have to implement some kind of authentication / authorization backend for my custom application. The application itself supports LDAP as AA backend (w/o kerberos), but I'm not sure if Azure AD can be used this way externally. Is this possible?
If not, I'm going to implement some authentication / authorization using standard python libraries. I've already found a lots of resources on this, however the whole picture still quite foggy. Basically I need two functions, authenticate the user (by evaluating the username/password received by the python script), and also check some kind of group membership for authorization as I would do in LDAP.
I don't want to invent the hot water, so, if there is any snippet for this, it would be great
Thank you
L:
If you want to use Azure AD for that, you would want to work against Azure Graph API
High level steps:
Create Azure AD Application
Figure out token auth
And using the REST API link figure the API calls to find appropriate permissions (probably adal can do that, not sure)

Google Cloud endpoints and service accounts returning :Oauth framework user didn't match oauth token user

Im trying to access a google cloud endpoint from a cmdline using service account similar to
https://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py
As instructed from the example, I created a clientid + pk12 cert and using them to create the credential with the SignedJwtAsertionCredential call from the oauth2client.client module.
Works as expected when I call my cloud endpoint running on my local devserver however when I call the deployed gae cloud endpoint I get
Oauth framework user didn't match oauth token user.
Seems to be failing on the oauth.get_client_id(scope) call from user_id_token._set_bearer_user_vars().
When I added a traceback on the exception, it looks to be coming from _maybe_raise_exception
E 2014-01-02 10:30:53.926 raise NotAllowedError(error_detail)
E 2014-01-02 10:30:53.926 NotAllowedError
Is there a way to resolve this error without changing the app's authentication type? Seems to be not allowing the request due to the domain restriction?
My goal is to call the cloud-endpoint without having a user involved, not sure if i'm the right path using the SignedJwtAsertionCredential call or if possible?
Additional info.
The authentication type of the endpoint is set to "Google App Domain"
The user_required is True on the endpoint method
The access token generated from the SignedJwtAssertCredential is as expected when i use
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.
The endpoint works as expected from the api explorer and when there is the auth flow involved.
Using the endpoints_proto_datastore library.
From extensive research I have come to the conclusion that implementing OAuth is not a viable authentication method for apps because of the simple fact that it is horrible to implement. After spending countless hours debugging and asking questions on Stackoverflow about a simple Twitter oAuth implementation, all while receiving countless wrong answers(which safely lets me deduce that a large percentage of developers don't know how to use OAuth) I decided to never again use OAUTH.
So I leave you with the words of the great French Emperor Napoleon Bonaparte
"Una retirada a tiempo es una victoria" -Napoleon Bonaparte
which basically means get out while your ahead and dont waste your time with OAUTH!
Additional information
while experiencing my frustrations with OAUTH I ended up doing some research on who actually came up with this headache inducing concept, and it turns out that the creator has quit this project and has actually publicly denounced OAUTH in his blog:
http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ interestingly titled the road the hell. So if the creator is not using OAUTH then you definitely shouldn't either. I have started a petition on https://petitions.whitehouse.gov/ to make the use of OAUTH illegal, so if you like you can join the fight and give us a vote, it is currently gaining traction and we appreciate any support, so go ahead and give it a vote.
The issue was due to the "Google Apps" Authentication Type selected for the application. This setting requires all accounts using the users api to be example.com accounts and the service account is obviously not one.
Once we changed the Auth Type to Google accounts, there was no issue with using service account and validating the client_id.

How can I call an endpoint in my appengine instance without doing oAuth? (Mirror API)

I am trying to create some Glassware with the Mirror API. I am new to using AppEngine and Jinja2. I have python experience but never with a web framework before. So basically I am very new at this.
I have modified the Python quickstart for the mirror API to include many of my endpoints and designs. Basically I want to be able to be able to POST data from a constrained device to Glass. I have an endpoint all setup which works to accept and parse out the data and send the timeline item.
My problem is that the device itself is acting all on it's own and cannot provide input, therefore when I call my app from it e.g. https://foo.appspot.com?operation=deviceData the app presents the auth page and then nothing happens. I can see in the logs that the auth page is being sent, but the device has no idea what to do with this.
Basically, I need a way where I can hardcode credentials and get around having to do oauth everytime. What is the recommended way to do this? Another app which doesn't require auth which passes the data along? This would be fine as I only need to set this up with one user right now, it is for an internal demo only.
Is it possible to set my credentials in a header and auth automatically without handling any return, more like how basic auth works?
There are also the "Simple API access" keys. Would these work in this situation, I tried creating browser and server keys and tried them on the device and in the browser by doinghttps://foo.appspot.com?operation=deviceData&key=KEY_HERE but in both cases I was still prompted to login. Is this what simple access keys are for? Do they not work with the mirror API?
Basically my question is, what's the easiest way to allow access to my apps endpoints without having to oAuth or having a hard coded user which auto-auths?
Here is the project that I started with: https://github.com/googleglass/mirror-quickstart-python

Categories