cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Want to learn some quick and useful tips to make your day easier? Check out how Calvin uses Replay to get feedback from other teams at Dropbox here.

Discuss Dropbox Developer & API

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: backend Java process to read a shared folder

backend Java process to read a shared folder

novotny
Explorer | Level 4

Hi,

 

We need a java workflow to scan the contents of a shared folder on a daily basis. I have downloaded the examples and looked at AuthorizeExample which I ran with the parameters "test.app test.auth short_live_token". This code appears to requires clicking a dropbox link

 

https://www.dropbox.com/oauth2/authorize?token_access_type=offline&response_type=code&client_id=XXXX...

 

to get an authorization code which is then used to generate a token and then the token can be used to list files in a folder. How can this all be done on the backend without human intervention? Are there any examples I can look at? With AWS S3 it's easily done with an access key and a secret key, I was hoping it would be similar.

 

Thanks, Jason

14 Replies 14

novotny
Explorer | Level 4

 

Thanks to the Java TutorialExample, I am able to execute

ListFolderResult result = client.files().listFolder("");

And see the folders in my own home directory. However, my partner shared a folder with me that I wish to see the files in but I don't see it listed. That prompted me to update the team scope permissions in my dropbox app (Is that needed here?). Once I did that I went down another rabbit hole where I could no longer get my authorization code from the link provided in the AuthorizeExample as I needed admin access based on adding these extra permissions. After my partner modified me to be an admin, I was able to get an updated access token and now when I try to do the following:

ListSharedLinksResult res = client.sharing().listSharedLinks();

I get an error

com.dropbox.core.BadRequestException: Error in call to API function "sharing/list_shared_links": This API function operates on a single Dropbox account, but the OAuth 2 access token you provided is for an entire Dropbox Business team. Since your API app key has team member file access permissions, you can operate on a team member's Dropbox by providing the "Dropbox-API-Select-User" HTTP header or "select_user" URL parameter to specify the exact user

 

Am I on the right path?

 

Really, all I want to do is to be able to read the files from a shared folder. Any code snippets would be greatly appreciated.

 

Thanks, Jason

 

Здравко
Legendary | Level 20

@novotny wrote:

...

ListFolderResult result = client.files().listFolder("");

And see the folders in my own home directory. However, my partner shared a folder with me that I wish to see the files in but I don't see it listed. ...


Hi @novotny,

You have pointed your account's home only, as a member, in the account (the string "" 😉). If the shared folder appear there as a subfolder (let say named "SharedThings"), you need to put this name (properly formatted) as a parameter (i.e. "/SharedThings", not empty string). You might need to set recursive enumeration if the shared folder contains subfolder and you need to enumerate all of them in one cycle.

 


@novotny wrote:

... That prompted me to update the team scope permissions in my dropbox app (Is that needed here?). Once I did that I went down another rabbit hole where I could no longer get my authorization code from the link provided in the AuthorizeExample as I needed admin access based on adding these extra permissions. ...


"Is that needed here?" 🙂 Good question! If the shared folder is in your home (as a subfolder there), you definitely don't need to make your life complicated. Otherwise you need it. You have  to set your id as a user and the space (team folder) where your target folder reside in (aside of exact path - properly formatted).

Hope this gives direction.

novotny
Explorer | Level 4

Thanks for the information. Below is a screenshot

Screenshot 2022-09-30 at 4.55.47 PM.png

 

The existing code:

ListFolderResult result = client.files().listFolder("");
while (true) {
for (Metadata metadata : result.getEntries()) {
System.out.println(metadata.getName());
}

if (!result.getHasMore()) {
break;
}

result = client.files().listFolderContinue(result.getCursor());

will write:

 

Jason Novotny
MPS
JasonNovotnyFingage
jason.novotny@fingage.com’s files
Get Started with Dropbox.pdf

 

But I wish to get access to the folder "AffinityInvestment". Can you please help me with the steps I need to do?

 

In particular how do I "set your id as a user and the space (team folder) where your target folder reside in (aside of exact path - properly formatted)." do this in Java?

 

Thanks, Jason

 

Здравко
Legendary | Level 20

Bad "news" - your folder is out of your home. 😕 You need to use team features.

First make sure you have selected yourself in the client object using asMember. Next select proper root (your team folder) using withPathRoot. Next you can list it using empty string (the folder appears to be the root, not a subfloder there). For more basic info take a look here.

Good luck.

Greg-DB
Dropbox Staff

@novotny Regarding your initial authorization question, it is not possible to fully automate the OAuth process where the user chooses to authorize the app and the app then receives the resulting access token and optional refresh token. This needs to be done manually by the user at least once. If your app needs to maintain long-term access without the user manually re-authorizing it repeatedly, the app should request "offline" access so that it gets a refresh token. The refresh token doesn't expire and can be stored and used repeatedly to get new short-lived access tokens whenever needed, without the user manually reauthorizing the app.

 

The Java SDK can actually handle the refresh process for you automatically, as long as you supply the necessary credentials, e.g., as shown retrieved in this example (meant for server-side Java apps), or this example (meant for client-side Java apps), and then used as shown in this example. (For Android, see this example instead.)

 

And as Здравко noted, to access that "AffinityInvestment" folder, which is in your "team space", you should use withPathRoot, to set the "Dropbox-API-Path-Root" header as covered in the Team Files Guide. Note that you don't actually need any team scopes (be an admin) and use asMember to do that. Using listFolder/listFolderContinue, whether using withPathRoot or not, just requires the "files.metadata.read" scope.

novotny
Explorer | Level 4

Thanks, I am getting a little farther.

 

Regarding authorization, let me describe what I am doing:

1. I executed the Authorize example you pointed me to with the parameters "test.app test.auth short_live_token" such that my test.app contains my appKey and secretKey. It then produces the following:

 

1. Go to https://www.dropbox.com/oauth2/authorize?token_access_type=offline&response_type=code&client_id=XYZ
2. Click "Allow" (you might have to log in first).
3. Copy the authorization code.
Enter the authorization code here:

 

After step 1, I get my code and enter it. It now displays:

 

Authorization complete.
- User ID:
- Account ID: null
- Access Token: <ACCESS_TOKEN>
- Expires At: 1664569280436
- Refresh Token: <REFRESH_TOKEN>
- Scope: account_info.read contacts.read file_requests.read files.metadata.read members.read sharing.read team_data.content.read team_data.content.write team_data.governance.read team_data.governance.write team_data.member team_data.team_space team_info.read
Saved authorization information to "/Users/novotny/IdeaProjects/dropbox-sdk-java/test.auth"

 

2. In my own code I hardcode the values I received from the example and create a credential object which allows me to create a client

 

DbxCredential dbxCredential = new DbxCredential(ACCESS_TOKEN, EXPIRES_AT, REFRESH_TOKEN, APP_KEY, APP_SECRET);
DbxTeamClientV2 teamClientV2 = new DbxTeamClientV2(config, dbxCredential);

But now what? I see there is a refreshAccessToken API available, is this something that my backend process should execute once per day?

try {
DbxRefreshResult result = client.refreshAccessToken();
System.err.println(result);
} catch (DbxException e) {
throw new RuntimeException(e);
}

Thanks, Jason

 

 

 

 

Greg-DB
Dropbox Staff

@novotny You can call refreshAccessToken if you want, but that is actually not necessary. The client will automatically handle this procedure for you whenever needed. (That is, it will automatically perform the refresh to get and use a new short-lived access token when the current one is expired, without you having to call any other methods yourself.)

novotny
Explorer | Level 4

Ok thanks, so the code I have should work fine? However what happens when the app restarts and the original hardcoded credentials have expired already? (Since the EXPIRES_AT has been hardcoded) Will that still work?

Здравко
Legendary | Level 20

It's related to access token only! Refresh token doesn't expire. 😉

Need more support?