Different Scopes in Google Analytics Service Account - java

Directly from Google Developers Api for Java
GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("[[INSERT SERVICE ACCOUNT EMAIL HERE]]")
.setServiceAccountScopes(PlusScopes.PLUS_ME)
.setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
// .setServiceAccountUser("user#example.com")
.build();
// set up global Plus instance
plus = Plus.builder(HTTP_TRANSPORT, JSON_FACTORY)
.setApplicationName("Google-PlusServiceAccountSample/1.0")
.setHttpRequestInitializer(credential).build();
Now I wanted to know what are the different
ServiceAccountScopes
that we can use ??
Here, its using PlusScopes.PLUS_ME, some where it uses AnalyticsScopes.ANALYTICS_READONLY .
I really don't have any idea about these scopes.
Further, when i try to use *AnalyticsScopes.ANALYTICS_READONLY* in my analytics-cmline-sample project from here
It doesn't allow me to. Saying its accepting a List while I am providing a String.
Does anyone has any idea whats this ServiceAccountScopes is all about ?

The answer to your second question is that you should put the scope in a arraylist, like this:
GoogleAccountCredential.usingOAuth2(this,Arrays.asList(AnalyticsScopes.ANALYTICS_READONLY));

Related

How to replace AuthorizationCodeInstalledApp class?

I am trying to run sample code from Google Quickstart for Java on an Android emulator, but the code falls on this line
return new AuthorizationCodeInstalledApp(flow, receier).authorize("user");
It turned out that Android does not support AuthorizationCodeInstalledApp class, so you need to manually catch the URL address for authorization, open it in the browser and then put the result in the Credential object. I am familiar with Java superficially, so I don't really know how I can implement that.
Can you please tell how this can be done?
From this thread, Charan M uses this piece of code to get credential and service:
mCredential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES)).setBackOff(new ExponentialBackOff());
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.gmail.Gmail.Builder(
transport, jsonFactory, credential)
.setApplicationName(mContext.getResources().getString(R.string.app_name))
.build();
Do note that you can't run this code on the main thread since it involves network operations. They also provided a github project as a guide in integrating, in their case, Gmail API into their Android project.

How to instantiate GoogleIdTokenVerifier properly / what does .setAudience() do?

My Guidelines
If followed this Google documentation about verifying Google-Account-Tokens on the server side, but I am kinda confused.
My Problem
GoogleIdTokenVerifier googleIdTokenVerifier = new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new JacksonFactory())
.setAudience(Collections.singletonList(CLIENT_ID))
.build();
In this piece of code I figured out that the transport and jsonFactory arguments can be filled as new NetHttpTransport() and new JacksonFactory() here. It also describes how to get AudienceString, but I couldn't figure out what it is for. I couldn't test it, but my question is if I can use it without .setAudience() or if I need it and what it is for.
In .setAudience() you have to pass all client ID's. You can get the ID for your client from the Credentials Page. It's explained here.
Thanks to #StevenSoneff.
If you didn't get the basic concept
For every client you want your server to accept, you need to create a project in the `Developer Console`. Clients are differentiated by their `SHA-1` fingerprint. You can for example have a debug project (will take your debug fingerprint) and a release one. To make both work, you have to add both `ID`'s to your server's `GoogleIdTokenVerifier`'s `.setAudience()`.
In my case, If you're using Firebase to get the id token on Android or iOS. You should follow these instructions to verify it on your backend server.
Verify ID tokens using a third-party JWT library
For me, I'm using Google OAuth Client as the third-party library so it's easy to use.
But it's a little bit different from this document.
Verify the Google ID token on your server side
The CLIENT_ID is your firebase project ID.
The Issuer has to be set as https://securetoken.google.com/<projectId>.
You need to use GooglePublicKeysManager and call setPublicCertsEncodedUrl to set it as https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com
GooglePublicKeysManager manager = new GooglePublicKeysManager.Builder(HTTP_TRANSPORT, JSON_FACTORY)
.setPublicCertsEncodedUrl(PUBLIC_KEY_URL)
.build();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(manager)
.setAudience(Collections.singletonList(FIREBASE_PROJECT_ID))
.setIssuer(ISSUER)
.build();
If you have multiple issuers, then you have to create GoogleIdTokenVerifier for each one.

GoogleCredential Missing Access Token

I am using the service account model and Google's Java API to retrieve and modify users.
I am able to successfully create a GoogleCredential object using code similar to Google's example:
GoogleCredential googleCredential = new GoogleCredentialBuilder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountUser(SERVICE_ACCOUNT_USER)
.setServiceAccountPrivateKeyFromP12File(P12_PRIVATE_KEY_FILE)
.setServiceAccountScopes(Collections.singleton(GLOBAL_USER_AND_ALIAS_SCOPE)
.build();
I see no mention in any examples that I have to explicitly create an access token, so I have been assuming that the above code takes care of that. Is that true?
After that, I successfully create an instance of Directory, then try to retrieve a specific user:
User user = new User();
user = directory.users().get(uid).execute();
That fails, throwing a NullPointerException.
When I inspect the GoogleCredential object right before the call to get the user object, it appears that it does not contain an access token:
accessToken = null
refreshToken = null
What am I missing?
How does one get the access token using the service account model?
Thanks in advance.
Where are you getting your accessToken? Try
credential.refreshToken();
accessToken = credential.getAccessToken();
Also, you should consider running your credentials in the Oauth2 Playground. If it works in the playground, then it's likely something wrong with your implementation.
Andy is correct. The examples for the Google Java API leave out this critical step. At runtime, the Google code throws a NullPointerException with no other details that would identify where it is occurring. Stepping through the debugger in Eclipse made it clear that the token was null in GoogleCredential.

Requested scopes not allowed

I'm trying to fetch a user from Google Directory API with the following request:
Collection<String> SCOPES = Arrays.asList("https://www.googleapis.com/auth/admin.directory.user.readonly", "https://www.googleapis.com/auth/admin.directory.user");
URL url = getClass().getResource("privatekey.p12");
GoogleCredential credential = new GoogleCredential.Builder()
.setJsonFactory(request.getJsonFactory())
.setServiceAccountId("foobar.com")
.setServiceAccountScopes(SCOPES)
.setTransport(new NetHttpTransport())
.setServiceAccountUser("foo#bar.com")
.setServiceAccountPrivateKeyFromP12File(new File(url.getPath())).build();
Directory dir = new Directory.Builder(GoogleNetHttpTransport.newTrustedTransport(), request.getJsonFactory(), credential)
.setApplicationName(request.getApplicationName())
.build();
But I'm getting the following error from the API:
Caused by: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "access_denied",
"error_description" : "Requested scopes not allowed: https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/admin.directory.user.readonly"
}
I've checked the scopes are correct, anyone know what's the problem here?
Try using one scope or the other. If you only need read access, use the readonly scope. If you need read/write access to users, use the other.
Also, ensure that you've granted the service account's client_id access to these scopes in the Admin's control panel (admin.google.com) and that your ServiceAccountUser is a super admin in the domain.
Argh! I removed the old service account and created a new one. After that things started to roll. Guessing I had a wrong p12 file etc. Can finally breathe again, phew.

Android: how do I authenticate to my google account and how can I get my GMail Tasks?

I am developing an Android app to connect to my Google Tasks and show them in a ListView.
I tried to follow step by step some tutorial such as https://developers.google.com/google-apps/tasks/oauth-and-tasks-on-android but none of those works.
I tried to download the google-api-services-tasks-v1-1.1.0-beta.jar and all the jars inicated in that tutorial, and after importing all the necessary libraries it just didn't work, and when i try to get my tasks after the connection i just get nulls.
I found out that i could use Oauth2.0 for the authentication and to access to the tasks API, to get my clientID ecc., so i created an account on the Google API's Console and created my OAuth clientID.
After that I try to authenticate with this code
HttpTransport transport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
String clientId = "myID";
String clientSecret = "mySecret";
String redirectUrl = "https://localhost/oauth2callback";
Iterable<String> scope ="https://www.googleapis.com/auth/tasks";
String authorizationUrl = new GoogleAuthorizationCodeRequestUrl(clientId, redirectUrl, scope)
.build();
String code="Code";
GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory,
clientId, clientSecret, code, redirectUrl).execute();
GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(
response.getAccessToken(), transport, jsonFactory, clientId, clientSecret,
response.getRefreshToken());
Tasks service = new Tasks(transport, jsonFactory, accessProtectedResource);
AccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessToken);
Tasks service = new Tasks(transport, new JacksonFactory(), accessProtectedResource);
service.accessKey="MyKey";
service.setApplicationName("GTasks");
I don't get any error but after creating this service I tried to get my tasklists but nothing happened and i didn't get any result.
When I tried to Log the content of the List of tasklists i just got an empty list "{}".
I suspect that this could be because of the old version of the libraries that i found, but even when i tried to use the latest versions it didn't work and i got the same results.
I'm really confused.
Every tutorial I found recommends a different version of the libraries and a different strategy. I really don't know wich one should I follow.
The Tasks API is REALLY confusing.
I, like you, was trying without success to roll my own authentication. I've found it way easier to modify the sample provided by google-api-java-client. This sample simply lists the tasks from the "default" task list.
You'll need to download and install the GDT plugin for Eclipse, and then use it to install the Google APIs you want to use.
Once you have the sample working, you can do more with it by looking here for the different functions to use. For example, to request all the tasks in the "Default" task list use this line:
client.tasks().list("#default").setFields("items/title").execute().getItems();
To update a task:
client.tasks().update("#default", task.getId(), task).execute();
And so on.

Categories