Calling Google Service from Apps Script with oAuth - google-apps-script

I was trying to run the sample script of Google Apps Script here:
https://github.com/googlesamples/apps-script-oauth2/blob/master/samples/GoogleServiceAccount.gs
I believe I set PRIVATE_KEY, CLIENT_EMAIL and USER_EMAIL correctly from JSON file downloaded from Google Developer Console. Also I enabled Google Drive API on the project. But still I get an error in the dialog "Error: invalid_client\n no application name".
Is there any code I should add / change to run this sample script correctly?

In case you are using the correct settings (PRIVATE_KEY,CLIENT_EMAIL and a valid USER_EMAIL), the error could also be related to the permission granted to the application from the domain admin.
Since this example uses domain wide delegation of authority to impersonate the account from the USER_EMAIL, first the domain admin has to grant permissions to the application to perform this kind of operations.
To grant this permissions to the app you can do it by going to: your Admin Console -> Security -> Advanced Settings -> Manage API client access
There you will add the service account CLIENT_ID in the field "Client Name" and in the second field you will add your project scopes separated by commas. These scope should match the scopes that the application uses. In this case id Drive scope and any other you may be using.
Click the button "Authorize" and if everything goes well, then you will be able to impersonate users in your domain with that project.
Here is the related documentation. I hope this helps.

Related

Project with Google APi with self user auth

I was able to create a project to connect an app to google data, for a specific account (followed Google People API)
But now I would like that each customer log in hisself to his account and manage his data.
I can' t create project in the Google API Console for each customer, my app needs to read auth from each user who will use my app and "auto" create auth to read google contact data of the logged user.
Is possible?
Could you suggest me articles about how to do?
It sounds like you are trying to do exactly what OAuth 2.0 (see the page you linked to) gives you: authenticating users. This differs from using an API key, which is only authorizing your project and has nothing to do with a user's credentials.
OAuth 2.0 combines a Client ID (associated with your Google Developers Console project) and a user's login (specific to the user who is accessing your app/site) to give you an authorization token. This token will let your app act on behalf of that user when calling that API. Just make sure to request the necessary scopes as part of the OAuth 2.0 authorization prompt given to the user.
How to give this prompt varies by environment, but many common options are listed on that link.
Note that you always use the same Client ID, so you only need one Google Developers Console project, but you are given a unique token specific to that user's login when they authorize your app, so this lets you act as any user which grants your app access to their account.

How to prevent suspended Google account to signup

I am integrating ASP.NET application using Google Drive API. For this after authentication we re uploading Files to Google drive. I am using Google client library to Call the APIs.
Everything is working as expected I am able to authenticate user successfully and able to upload the file successfully.
In one scenario when the user Google account is suspended then I am getting refresh token from Google but my upload method is failing and it is not uploading the file to Google drive.
I want to restrict the user on Signup screen itself, when account is suspended.
What parameter do I have to pass to achieve this please suggest?
Unfortunately this info is not easily available. You have two options :
Use the Directory API to see if the user is suspended. This requires additional OAuth permissions to be provided by an admin of the domain.
At login, try and perform a Drive API call to see if you get an error or not. If you get an error (with a couple of retried) and the error message matches the one you had for suspended users, then you can deny access to the user.

Using the google drive api, how do I check if a user can share a file publicly with or without link?

See: Is it possible to share a file publicly through Google Drive API
Using the information above, If I attempt to set the necessary permission for a specific file, I receive the following:
Error calling POST https://www.googleapis.com/drive/v2/files/{somefileid} permissions: (403) Insufficient permissions for this file
This error only occurs for google accounts tied to a google apps for edu setup where the admin has unchecked the option Google Apps -> Settings for Drive -> Share Settings -> Outside this organization: "Allow users to publish files on the web or make them visible to the world as public or unlisted files"
Using the Permission feed works fine otherwise, but ideally I would like to know if there is a way to check for this setting beforehand, instead of catching the 403 exception from the drive service.
You can use the About.get() endpoint to get details about the user's Drive, including this sharing setting. The field domainSharingPolicy can have the values allowed, allowedWithWarning, incomingOnly and disallowed. The first two in that list should allow publishing outside the domain, while the second two should not.

Google Drive SDK authorization

I have been trying to follow the Quickstart: Run a Drive app in JavaScript sample in order to use Google Drive API and SDK. I went through the authentication and set up the Client ID and API key etc. I had assumed that the token can be created without the user being logged in to a Google Account, since the client has the Client ID that is connected to a Project on Google Developer Console. Am I missing something here?
Can a user use the JavaScript based Google Drive app without logging in to a Google Account?
no. From your question, it sounds like you've interpreted client ID as referring to the user. Client ID refers to the app. So separately, Google needs to confirm the user has given his permission, and that requires authentication, ie login

Impersonating users of Drive of one domain as a domain administrator

I'm looking for a way to impersonate users of a google app domain using a admin user. I could do it easily with google data document list api but I cant find a way to do it with the new Drive API.
Precisely, what I want to do is authenticate my admin user using Oauth2 (i've already done this), retrieve a list of the users of my domain and then impersonate my users, or at least be able to access files and docs from the Drive of those users.
In the administrative panel of google apps, there are Oauth consumer key and Oauth consumer secret, but these are used in Oauth1 2LO, not Oauth2.
Is there a proper way/workaround/hack to implement what I want ?
Best regards,
Jérôme
I've only been looking at the google-api-ruby-client as an example but you should be able to do this with a service account that is permitted access through the admin panel -> Advanced tools -> manage third party oauath clients. Once permitted you can follow the example for a service account here http://code.google.com/p/google-api-ruby-client/source/browse/service_account/analytics.rb?repo=samples but instead of authorizing with
client.authorization = asserter.authorize()
you can use
client.authorization = asserter.authorize("id#domain.com")
I haven't done a lot with this yet but after authenticating in this method I've been able to list all documents owned by a user on my domain.
Thanks to James Woodward, i've been able to impersonate user. I post an answer to provide Java specific details.
Create a service account in the API console. 3 important resources are created :
Client ID : used to authorize the app on the Google Apps domain
Email address : used to authorize the requests of the app
.p12 key file : used to authorize the requests of the app
Authorize the app on the Google Apps Administrative panel, providing it with Service account client ID, and all the scopes the app will need.
Create GoogleCredential this way :
GoogleCredential serviceCred = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ID)
.setServiceAccountScopes(Arrays.asList(SCOPES))
.setServiceAccountUser("impersonated.user#domain.com")
.setServiceAccountPrivateKeyFromP12File("key.p12")
.build();
Those credentials can now be used to authenticate the requests made by the app on any scope authorized.