Google Drive service account returns 403 usageLimits - java

I'm trying to write an AppEngine app that writes a Google Document to Google Drive, puts in a specific set of folders and sets access rights. I have this working with the old DocsList API but since that just got deprecated I decided to update my code (and I had some additional functions to add anyway).
Problem I'm facing is this: When I use a service account and try to impersonate a specific user I get a 403 with usageLimits even though I have not used up any of my quota.
Here is the code I'm using:
GoogleCredential credentials = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId("xxxxxxxxxxgserviceaccount.com")
.setServiceAccountScopes(DriveScopes.DRIVE)
.setServiceAccountPrivateKeyFromP12File(
new java.io.File("xxxx-privatekey.p12"))
.setServiceAccountUser("user#xxxxxx.org").build();
I than use these credentials to initiate my Drive object:
Drive d = Drive.builder(httpTransport, jsonFactory)
.setHttpRequestInitializer(credentials)
.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
#Override
public void initialize(JsonHttpRequest request) {
DriveRequest driveRequest = (DriveRequest) request;
driveRequest.setPrettyPrint(true);
}
}).setApplicationName("MYAPPNAME").build();
BTW: I've tried using new Drive(....) but that just won't work, no matter what I try. Keeps throwing errors that internal methods are not found!
Back to this issue:
When I than use 'd' to call something like .files().get("SOMEFILEID").execute() I get a 403
{ "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"
}
I can't figure out why this doesn't work. I've look online all day but can't find a suitable answer. Some help is very much appreciated.

So pinoyyid's answer did help, although it wasn't the definitive answer.
I ended up solving it like this:
I took my AppID (xxxxx.apps.googleusercontent.com) and added it to my CPanel https://www.google.com/a/cpanel/[[YOURDOMAIN]]/ManageOauthClients
with these scopes:
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
After that I had could do an authenticated request to the Drive environment. Running into a stack of different issues now but the 403 got solved.

I usually get a 403 when the API call was missing the Authorization http header. Trace the http and look at the headers. The rationale for the "quota" message is that without an Auth header, you are anonymous, and the quota for anonymous use is zero.
You might also check that your app is registered for both of the Drive APIs, as I've heard that that can cause the same problem.
On the internal method issue, that sounds like you're using incompatible library versions. What worked best for me was to delete all of the libraries I had downloaded with the sample code, then use the Google Eclipse plugin to "Google/Add Google APIs..." to download all of the latest versions.

Related

Plaid Quickstart Issues (Java)

I am trying to implement Plaid using the sample code provided on the Java Quickstart [sandbox] and am getting issues when I show the Plaid Dialog (javascript). I am able to successfully get a link_token, but I'm never able to show the dialog. It spins for a brief second, then shows me:
oauth uri does not contain a valid oauth_state_id query parameter. Request ID: DBoT92FCo8AORay
I have tried this with an empty redirectUri, as well as "http://localhost:8080/plaid_test.html", which is registered in my developer account.
I am a bit stuck and hoping someone can direct me in the right direction. I've tested with both versions 9.10.0 and the latest (11.9.0).
Curiously, I am able to get the Java Quickstart working directly, but ONLY if I leave the .env PLAID_REDIRECT_URI blank. If I put localhost in there, it fails when trying to get the link token.
Does anyone have any suggestions on how to overcome this setup issue?
Thank you!
I got this error (oauth uri does not contain a valid oauth_state_id query parameter) while creating a new test application in Plaid's Sandbox environment.
Important note: My application does not use OAuth.
The problem turned out to be, in my configuration parameters being passed to usePlaidLink, I was including a receivedRedirectUri key-value pair. Removing that key-value pair entirely resolved the issue for me.
In other words, my React component looked something like:
import { usePlaidLink } from 'react-plaid-link';
function PlaidLink(props) {
const onSuccess = React.useCallback((public_token, metadata) => {
// ...
});
const config = {
token: props.linkToken,
receivedRedirectUri: window.location.href,
onSuccess,
};
const { open, ready } = usePlaidLink(config);
// ...
}
Removing the line with the receivedRedirectUri was the solution for me, getting me past the oauth uri does not contain a valid oauth_state_id query parameter error, and getting the Plaid Link UI to appear in my app successfully.
This Plaid article, which has a number of mentions of "OAuth state ID" (as mentioned in the error message), helped point me toward this solution.
The issue may be the location you are trying to use -- unless you have manually modified the ports or other code used by the Quickstart, you should use http://localhost:3000/ as the PLAID_REDIRECT_URI (make sure to add this to your Dashboard as an allowed redirect URI). When I tried this just now on the Java quickstart (non-Docker version) it worked fine.

Transfer google drive file ownership using google java api

I have uploaded some test files to my google drive using their website and my gmail account (x#gmail.com). The files are in "My Drive" and not shared drive. I am then trying to write a google drive java api and oauth authorization code flow based program to transfer the ownership of these files to my another gmail account(y#gmail.com). i.e both the accounts belong to #gmail.com.
I am logged in to my application using x#gmail.com using authorization code workflow and my app is trying to access Google APIs with my access token. I am able to create a new permission on test files to make y#gmail.com a "writer" of the file. But when I try to make "y" an owner, I get error message. This is despite of x being the owner and being the one whose access token is used.
How do I transfer the ownership to another account?
Message changePerms(#PathVariable(name = "fileId") String fileId, #PathVariable(name = "userEmail") String newOwnerEmail) throws Exception {
Drive drive = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getOauthCredentials())
.setApplicationName("my-app").build();
Permission newOwnerPermission = new Permission();
newOwnerPermission.setEmailAddress(newOwnerEmail);
newOwnerPermission.setType("user");
newOwnerPermission.setRole("owner"); // Works if this is "writer" so my credentials and auth is working
drive.permissions().create(fileId,newOwnerPermission).setTransferOwnership(true).execute();
}
Error :
POST https://www.googleapis.com/drive/v3/files/19wvNc4TmXhODJa7Iy3Qq97UAD8fJrVg/permissions?transferOwnership=true
{
"code": 400,
"errors": [
{
"domain": "global",
"message": "Bad Request. User message: \"You can't change the owner of this item.\"",
"reason": "invalidSharingRequest"
}
],
I think you can't transfer ownership files if they have been uploaded to your Drive. There was a mention of this on the help page, but that one line was removed earlier this year (though I can't say I know why as it appears that nothing has changed).
The current version of the help page is here, but as you can see using the Wayback Machine that only one month ago the following line was still present:
You can only transfer ownership of Google files and folders.
So I would say that this is probably the reason.

Google service account authorization error

I'm trying to use Google APIs with a service account.
Originally I used a normal project account with credentials and I managed to query the APIs. To use a service account, I modified the code to skip the browser auth flow and only use the service account credentials. It seems that the same request that used to work with the normal project credentials now give an error without clarifying much in the message. It goes as follows:
directoryService = new GoogleService().buildDirectoryService();
Users result = directoryService.users().list()
.setCustomer("my_customer")
.setOrderBy("email")
.execute();
public Directory buildDirectoryService() throws GeneralSecurityException, IOException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential
.fromStream(new FileInputStream("src/main/resources/newest_service_account_creds.json"))
.createScoped(SCOPES);
return new Directory.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.setHttpRequestInitializer(credential).build();
}
Unfortunately the error message is not saying much:
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Input",
"reason" : "invalid"
} ],
"message" : "Invalid Input"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
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:1108)
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 GetDrivePermissions.getFiles(GetDrivePermissions.java:35)
at Main.main(Main.java:7)
I repeated the process two times to make sure I didn't miss anything, including creating a new project, enabling the APIs, adding a service account, adding and enabling domain-wide delegation and obtaining a credentials json file, also adding access to the app in App Access Control in the admin UI. But calling
directoryService.users().list().setCustomer("my_customer").setOrderBy("email").execute();
service still returns the above error message.
The error message refers to "Invalid input", but the request used to work before, with normal application credentials. So the problem must lay not in how I call the Directory service but with my authentication, the only difference between the working and the non-working version.
Since this worked with using the project credentials, there must be something wrong with how I use the service account, but I can't find the error even after repeating the whole process two times. Based on the guides I found about service accounts, this is supposed to work. The credential object is created and it looks proper.
What can I look into next?
Thnaks for any insight in advance.
I changed this part back to use the application's own credentials. I have another call that uses the service account credentials and that works, so this is a workaround for now.

Google Play Developer API - 400 Invalid Value - InAppPurchases

My question is similar to this one. However, I am using the API Java Client Library with a service account, making calls to the API from my server.
My code is following this guide, which is very simple. However, I can't seem to get an appropriate error for my request. This is how I build my AndroidPublisher:
val credential = GoogleCredential.fromStream(FileInputStream(
"/path/to/json"
)).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
androidPublisher = AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(packageName)
.build()
Where the JSON is generated from the Developer Console, under Service Accounts. This is how I make my request:
androidPublisher.purchases().subscriptions().get(packageName, "valid-sku", "invalid-token").execute()
My subscription ID is valid but my token is invalid. I expect an error such as "invalid token" in the response. However, what I get is:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
Is that a generic error because of the invalid token or is it an authentication issue? If it an authentication issue, how do I solve it? If it is an invalid token issue, how am I supposed to know?
Some more information:
I get the same error when trying to make that call from the API Explorer as well (this time using a Client ID and API Key instead of Service Account).
I have not delegated domain-wide access to the service account. Do I have to for some reason?
I can successfully make other calls to the API such as inappproducts.list
From my experiences, if you have HTTP 400 error with Invalid Value then that purchase or subscription is FRAUD.
You can check out Order Id part of those purchases. Probably in the format of XXXXXXXXXXXX.XXXXXXXXXXXX which is wrong and should be GPA.XXXX.XXXXX.XXXXX.XXX
I don't really count the X char number. I just added to show the logic.
In my case the problem was that I was calling:
purchases.products.get
Instead of:
purchases.subscriptions.get
So, the reason that happened was just because the purchaseToken I was using was wrong.
I did not expect that to be the reason as I thought that in the case of an invalid token, I would receive a "token invalid" error (or something similar). As it turns out, the responses given by Google are pretty inconsistent (a 404 could also be given for an invalid token).
Scratched my head for a few hours, ALL my parameters were correct, and then well.. I realized that I was barking up the wrong tree (endpoint)
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}
is not this
https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}
/purchases/subscriptions/.. vs /purchases/products/..
For all those who run into this problem, 99% of you need to publish the application for internal testers.
Follow this guide: https://support.google.com/googleplay/android-developer/answer/6062777?hl=en

Generate Access Token for Facebook

I am new to the Facebook API. What I am trying to do without success is from my laptop create a new access token for myself through the Facebook API.
Below is the URL I am using to create this new access token:
String url = "
https://graph.facebook.com/oauth/authorize?client_id=##########&client_secret=##########&redirect_uri=http%3A%2F%2Fintelligentretrieval.com"
When I use my client id and then the client_secret (I assume this is the client password) then I get an error
{
"error": {
"message": "Missing redirect_uri parameter.",
"type": "OAuthException",
"code": 191
}
}
What exactly is the problem with this and the reason for the error?
Facebook requires a redirect_uri so I decided to dot it to my company site home page.(I figure this isn't the best place to redirect it but where should I redirect this?)
I want to redirect the result (generated access token) to my laptop from where I am making this URL request.
What exactly is the problem with this?
Is this possible with a browser like Chrome?
Is this possible using java?
Also is it possible to extend the access token expiration to 60 days with this url?
Please let me know if there is any confusion with any part of this post or if the answer can be found elsewhere.

Categories

Resources