How can I give full permissions to Google Drive REST API? - java

I'm trying to create an app that copies and deletes existing spreadsheets. I've set up the DriveQuickstart from https://developers.google.com/drive/v2/web/quickstart/java
The error that I'm getting now is saying that I do not have sufficient permissions to access that, even after I click the "Allow" button that comes up on my browser after I run the sample.
My code is exactly the same as on the quickstart link.
I'm getting this stacktrace:
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at DriveQuickstart.main(DriveQuickstart.java:110)

To build on adjuremods response, this is what worked for me:
1) Change this line:
private static final List<String> SCOPES =
Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
to:
private static final java.util.Collection<String> SCOPES =
DriveScopes.all();
2) Delete your existing stored credentials so that it will fetch them again, and reexecute your program:
rm ~/.credentials/drive-java-quickstart/StoredCredential
Note: you want an OAuth Client ID called client_secret.json file, not the client_id.json file (I think - that's what worked for me anyway).

Since you're using the exact code form the QuickStart, it may have something to do with the scope set, its currently set as DriveScopes.DRIVE_METADATA_READONLY, which if you check out its meaning in the Choose Auth Scopes page, it states
Allows read-only access to file metadata, but does not allow any access to read or download file content
You can look at the cited page to know what scope it is you'll exactly use. Its most likely going to be https://www.googleapis.com/auth/drive, so check out the DriveScopes class for the constant of the same nature.

Related

Search for messages in Google Chat Space through Google Vault API

I'm trying to create a Google Vault Export containing all messages in a Chat Space by querying for a specific Chat Space ID. Unfortunately, creating an export for the following query:
newQuery
.setDataScope("ALL_DATA")
.setCorpus("HANGOUTS_CHAT")
.setStartTime(startDate)
.setEndTime(endDate)
.setSearchMethod("ROOM")
.setHangoutsChatOptions(new HangoutsChatOptions().setIncludeRooms(false))
.setHangoutsChatInfo(new HangoutsChatInfo().setRoomId(spaceId));
produces the following error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
POST https://vault.googleapis.com/v1/matters/<matterID>/exports
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Search method ROOM is not supported for corpus type HANGOUTS_CHAT.",
"reason" : "badRequest"
} ],
"message" : "Search method ROOM is not supported for corpus type HANGOUTS_CHAT.",
"status" : "INVALID_ARGUMENT"
}
CorpusType needs to be set to "HANGOUTS_CHAT" in order to search in the Google Chat Service. The API also mentions that a HangoutsChatInfo() object needs to be passed when the search method is "ROOM" (https://developers.google.com/vault/reference/rest/v1/Query#SearchMethod).
Am I missing something or is this a bug? Does anyone know a workaround for this issue, if what I want to accomplish is not possible?
It seems that is intended behavior as per current design of the API since you will need to provide the corresponding RoomId and it's not possible at the moment.
Someone had a similar problem before and it ended up in a feature request, you can check it here: https://issuetracker.google.com/189250955

Missing a valid API key about Google Translation API Client issue?

I follow the https://cloud.google.com/translate/docs/reference/libraries#client-libraries-usage-java to get started java client demo.
I have already set authentication json file to the environment variable GOOGLE_APPLICATION_CREDENTIALS. However, I got the translateException when I run java sample code.
Exception in thread "main" com.google.cloud.translate.TranslateException: The request is missing a valid API key.
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:61)
at com.google.cloud.translate.spi.v2.HttpTranslateRpc.translate(HttpTranslateRpc.java:144)
at com.google.cloud.translate.TranslateImpl$4.call(TranslateImpl.java:113)
at com.google.cloud.translate.TranslateImpl$4.call(TranslateImpl.java:110)
Caused by:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403
Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "The request is missing a valid API key.",
"reason" : "forbidden"
} ],
"message" : "The request is missing a valid API key.",
"status" : "PERMISSION_DENIED"
}
The doc shows that this JSON file contains key infomation.
The sample code is shown
// Instantiates a client
Translate translate = TranslateOptions.getDefaultInstance().getService();
// The text to translate
String text = "Hello, world!";
// Translates some text into Russian
Translation translation =
translate.translate(
text,
TranslateOption.sourceLanguage("en"),
TranslateOption.targetLanguage("ru"));
System.out.printf("Text: %s%n", text);
System.out.printf("Translation: %s%n", translation.getTranslatedText());
I have no idea how to set api-key.
It still doesn't work after I set environment variable for key and credentials.
you can try to authenticating by your service acount json file like below
its pretty simple in node
// Instantiates a client
const translate = new Translate(
{
projectId: 'your project id', //eg my-project-0o0o0o0o'
keyFilename: 'path of your service acount json file' //eg my-project-0fwewexyz.json
}
);
you can take the reference https://cloud.google.com/bigquery/docs/authentication/service-account-file for java
To make authenticated requests to Google Translation, you must create a service object with credentials or use an API key. The simplest way to authenticate is to use Application Default Credentials. These credentials are automatically inferred from your environment, so you only need the following code to create your service object:
Translate translate = TranslateOptions.getDefaultInstance().getService();
I have personally never gotten that to work.
This code can be also used with an API key. By default, an API key is looked for in the GOOGLE_API_KEY environment variable. Once the API key is set, you can make API calls by invoking methods on the Translation service created via TranslateOptions.getDefaultInstance().getService().
Sample project here
I was able to get google translate to work by running
"gcloud auth application-default login"
on the command prompt. This regenerated the credentials to the default location after asking you to authorize with your google account. See https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-translate for more details.
Add
System.setProperty("GOOGLE_API_KEY", "your key here");
before
Translate translate = TranslateOptions.getDefaultInstance().getService();
Cheers :)
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Requests from this Android client application <empty> are blocked.",
"reason" : "forbidden"
} ],
"message" : "Requests from this Android client application <empty> are blocked.",
"status" : "PERMISSION_DENIED"
}
Following Approach I follow in android to resolve it. I tried with Private key but did not work for me. so I use public key for this
System.setProperty("GOOGLE_API_KEY", "Public key");
val translate = TranslateOptions.getDefaultInstance().service
translate?.let {
val translation = it.translate("Hola Mundo!",
Translate.TranslateOption.sourceLanguage("es"),
Translate.TranslateOption.targetLanguage("en"),
Translate.TranslateOption.model("nmt"));
val check = translation.translatedText
Log.e("inf",""+check)
}

Able to access bucket in gcloud and Python API but not Java API

I'm working on a project that is includes a process to store files into Google Cloud Storage.
The initial prototype was in Python and works fine, however when porting the codebase over to Java I am unable to access the bucket.
The Java project is built with Gradle and development is through NetBeans. The ServiceAccount is a keyfile with restricted access, only allowing for read/write behavior from this particular bucket.
// The Java code, which should be enough to grab the bucket.
Storage storage = StorageOptions.getDefaultInstance().getService();
Bucket bucket = storage.get(BUCKET_NAME);
// For comparison, the Python setup.
storage_client = storage.Client()
self.bucket = storage_client.bucket(bucket_name)
When manually running the project from Gradle the result is,
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403
Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "xxx#xxx.iam.gserviceaccount.com does not have storage.buckets.get access to xxx.",
"reason" : "forbidden"
} ],
"message" : "xxx#xxx.iam.gserviceaccount.com does not have storage.buckets.get access to xxx."
}
Slightly different when running from within NetBeans itself:
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 401
Unauthorized
{
"code" : 401,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "Anonymous users does not have storage.buckets.get access to a1s-submissions.",
"reason" : "required"
} ],
"message" : "Anonymous users does not have storage.buckets.get access to a1s-submissions."
}
All of these methods are returning the expected results
So I know at least the file is being read.
StorageOptions.getAppEngineAppId());
StorageOptions.getDefaultProjectId());
StorageOptions.CREDENTIAL_ENV_NAME);GOOGLE_APPLICATION_CREDENTIALS
StorageOptions.getDefaultInstance().getApplicationName());
StorageOptions.getDefaultInstance().getProjectId());
StorageOptions.getDefaultInstance().getCredentials()
.getAuthenticationType());
StorageOptions.getLibraryName());
So given that I can access the bucket via gcloud and python, I know the account has authorization, however I cannot seem to uncover the cause for this error.
Oddly, the solution here was in fact to relax the permissions on the service account. I didn't have access to this at the time but was finally able to check this today.
For whatever reason still unknown to me, Python was able to carry out the same operations with the original service account authorization settings while Java required additional rights granted.

Write to GoogleSheet via API with Java

I am trying to write a value to a cell with Google Sheet API with Java.
For reading I used guide from Java Quickstart which worked fine for me.
For writing to Google Sheet I use:
service.spreadsheets().values().update(spreadsheetId, "Sheet1!A4:H", response).execute();
This function outputs the following error while run:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Request had insufficient authentication scopes.",
"reason" : "forbidden"
} ],
"message" : "Request had insufficient authentication scopes.",
"status" : "PERMISSION_DENIED"
}
As a Authentication Scope I am using
private static final List<String> SCOPES = Arrays.asList(SheetsScopes.SPREADSHEETS);
Apparently there were several issues together:
Delete credentials that were stored at /Users/XXX/.credentials.
Change Scopes to SheetsScopes.SPREADSHEETS.
Google Sheet Share and Edit options at on Sheet itself.
Now it works!
Thank you guys for help
I was having the same issue. I resolved the problem that was in the scope.
I just changed
SheetsScopes.SPREADSHEETS.READONLY
To
SheetsScopes.SPREADSHEETS
And it works very well.
The Java API must be used in an interactive way, if you're running this on a server that can't pop up a web-browser (which will let you approve an OAuth dialog), then the authentication flow doesn't get proper credentials and won't work.
While running this, do you see a browser pop up to approve an OAuth dialog? If not, you're likely running in a headless session and will need some other means to get the user's credentials.
Try replacing "Sheet1!A4:H" with A4:H

Get the Post Of User On Google Plus

I got a problem on getting the post of user on google plus. I only have the access token and refresh token of this user ( not the ID !), how could i get the post from google plus of this user ?, i do searching a lot, but none of them meets my circumstance. When the user provide his google plus Id on the front end side, the access token and refresh token were generated and stored in database, i, on the backend side, will use these tokens to retrieve the post of this user.
p/s: I use this library https://code.google.com/p/google-plus-java-api/ because it looks so simple, i don't want to use so complicated library just for getting the post, thanks you guy a lot
here is my code
import com.googlecode.googleplus.GooglePlusFactory;
import com.googlecode.googleplus.Plus;
import com.googlecode.googleplus.model.activity.ActivityCollection;
import com.googlecode.googleplus.model.activity.ActivityFeed;
public void getInfo(String accessToken, String refreshToken) {
GooglePlusFactory factory = new GooglePlusFactory(clientId, clientSecret);
Plus plus = factory.getApi(accessToken, refreshToken,null);
if (plus != null) {
ActivityFeed af = plus.getActivityOperations().list("me",ActivityCollection.PUBLIC);
String firstpost = af.getItems().get(0).getObject().getContent();
}
, i got 403 error when call this method, the error output was :
403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "usageLimits",
"message" : "Daily Limit Exceeded. Please sign up",
"reason" : "dailyLimitExceededUnreg",
"extendedHelp" : "https://code.google.com/apis/console"
} ],
"message" : "Daily Limit Exceeded. Please sign up"
}
Actually, i think the reason is not because daily limit exceeded, because i got that message at the first time i run, i also turn the google+ api, google+ domain api on google api console. I suppose the error come from using the "me" in the "list" method to retrieve the post. I still dont' have any idea how to fix this problem
Updated #1#:
I have change my code a lot, so here is exactly what i stuck at, i already get a new accessToken, and (when it is still not expired) , i run this code below:
GoogleCredential credential = new GoogleCredential.Builder()
.setJsonFactory(JSON_FACTORY)
.setTransport(TRANSPORT)
.setClientSecrets(CLIENT_ID, CLIENT_SECRET).build().setAccessToken(newAccessToken);
// Create a new authorized API client.
Plus service = new Plus.Builder(TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
// Get a list of people that this user has shared with this app.
ActivityFeed feed = service.activities().list("me", "public").execute()
then i got this error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Insufficient Permission",
"reason" : "insufficientPermissions"
} ],
"message" : "Insufficient Permission"
}
Using "me" as the ID for the list call should work correctly, and your code generally appears correct.
The error message suggests that your client is unregistered. I would check to make sure of the following:
Make sure you have created a Client ID and Secret (and don't post them here!) for your project and you're passing them to the GooglePlusFactory correctly.
Make sure this project has the Google+ API turned on.
Make sure that the access token you're providing for the user corresponds to them authenticating to this same project
I solved this problem, everything is fine except 1 thing, that's is the access token and refresh token was created by some scopes but not the scopes Plus.me, that why's i can't request a new access token by using this refresh token, and then i got the insufficient permission error 403. So when i get the new access and refresh token by using the approriated scope, i can query with keyword "me". Hope you guy don't stuck like me, it takes me nearly 2 days to figure it out

Categories