diff --git a/doc/shared-items.md b/doc/shared-items.md index 8f6631d49..33c580ac9 100644 --- a/doc/shared-items.md +++ b/doc/shared-items.md @@ -28,17 +28,5 @@ String password = "foo"; BoxItem.Info itemInfo = BoxItem.getSharedItem(api, sharedLink, password); ``` -If you already know the type and ID of the item you want to access, you can -manually construct a [`SharedLinkAPIConnection`][shared-link-api] and make -API calls on the item directly. - -```java -String sharedLink = "https://app.box.com/s/abcdefghijklmnopqrstuvwxyz123456"; -SharedLinkAPIConnection sharedLinkAPI = new SharedLinkAPIConnection(api, sharedLink); - -BoxFile sharedFile = new BoxFile(sharedLinkAPI, "file_id"); -BoxFile.Info sharedFileInfo = sharedFile.getInfo(); -``` - [get-shared-item]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxItem.html#getSharedItem-com.box.sdk.BoxAPIConnection-java.lang.String- [get-shared-item-password]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxItem.html#getSharedItem-com.box.sdk.BoxAPIConnection-java.lang.String-java.lang.String- diff --git a/src/main/java/com/box/sdk/BoxAPIRequest.java b/src/main/java/com/box/sdk/BoxAPIRequest.java index 924572d7c..a23e794ba 100644 --- a/src/main/java/com/box/sdk/BoxAPIRequest.java +++ b/src/main/java/com/box/sdk/BoxAPIRequest.java @@ -600,12 +600,10 @@ private BoxAPIResponse trySend(ProgressListener listener) { if (this.api instanceof SharedLinkAPIConnection) { SharedLinkAPIConnection sharedItemAPI = (SharedLinkAPIConnection) this.api; - String sharedLink = sharedItemAPI.getSharedLink(); - String boxAPIValue = "shared_link=" + sharedLink; - String sharedLinkPassword = sharedItemAPI.getSharedLinkPassword(); - if (sharedLinkPassword != null) { - boxAPIValue += "&shared_link_password=" + sharedLinkPassword; - } + String boxAPIValue = BoxSharedLink.getSharedLinkHeaderValue( + sharedItemAPI.getSharedLink(), + sharedItemAPI.getSharedLinkPassword() + ); requestBuilder.addHeader("BoxApi", boxAPIValue); } diff --git a/src/main/java/com/box/sdk/BoxItem.java b/src/main/java/com/box/sdk/BoxItem.java index f9e8d397c..b867eab29 100644 --- a/src/main/java/com/box/sdk/BoxItem.java +++ b/src/main/java/com/box/sdk/BoxItem.java @@ -64,12 +64,14 @@ public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink * @return info about the shared item. */ public static BoxItem.Info getSharedItem(BoxAPIConnection api, String sharedLink, String password) { - BoxAPIConnection newAPI = new SharedLinkAPIConnection(api, sharedLink, password); - URL url = SHARED_ITEM_URL_TEMPLATE.build(newAPI.getBaseURL()); - BoxJSONRequest request = new BoxJSONRequest(newAPI, url, "GET"); + URL url = SHARED_ITEM_URL_TEMPLATE.build(api.getBaseURL()); + BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); + + request.addHeader("BoxApi", BoxSharedLink.getSharedLinkHeaderValue(sharedLink, password)); + try (BoxJSONResponse response = request.send()) { JsonObject json = Json.parse(response.getJSON()).asObject(); - return (BoxItem.Info) BoxResource.parseInfo(newAPI, json); + return (BoxItem.Info) BoxResource.parseInfo(api, json); } } diff --git a/src/main/java/com/box/sdk/BoxSharedLink.java b/src/main/java/com/box/sdk/BoxSharedLink.java index a85f91fa9..9b0bb8fa9 100644 --- a/src/main/java/com/box/sdk/BoxSharedLink.java +++ b/src/main/java/com/box/sdk/BoxSharedLink.java @@ -269,6 +269,14 @@ void parseJSONMember(JsonObject.Member member) { } } + public static String getSharedLinkHeaderValue(String sharedLink, String password) { + String boxAPIValue = "shared_link=" + sharedLink; + if (password != null) { + boxAPIValue += "&shared_link_password=" + password; + } + return boxAPIValue; + } + /** * Enumerates the possible access levels that can be set on a shared link. */ diff --git a/src/main/java/com/box/sdk/SharedLinkAPIConnection.java b/src/main/java/com/box/sdk/SharedLinkAPIConnection.java index 22e29ef01..fbdd48f78 100644 --- a/src/main/java/com/box/sdk/SharedLinkAPIConnection.java +++ b/src/main/java/com/box/sdk/SharedLinkAPIConnection.java @@ -3,6 +3,7 @@ /** * This API connection uses a shared link (along with an optional password) to authenticate with the Box API. It wraps a * preexisting BoxAPIConnection in order to provide additional access to items that are accessible with a shared link. + * @deprecated Use {@link BoxItem#getSharedItem(BoxAPIConnection, String, String)} instead */ public class SharedLinkAPIConnection extends BoxAPIConnection { private final BoxAPIConnection wrappedConnection; diff --git a/src/test/Fixtures/BoxItem/GetSharedItemFile200.json b/src/test/Fixtures/BoxItem/GetSharedItemFile200.json new file mode 100644 index 000000000..2164306af --- /dev/null +++ b/src/test/Fixtures/BoxItem/GetSharedItemFile200.json @@ -0,0 +1,185 @@ +{ + "id": "12345", + "type": "file", + "allowed_invitee_roles": [ + "editor" + ], + "classification": { + "color": "#FF0000", + "definition": "Content that should not be shared outside the company.", + "name": "Top Secret" + }, + "comment_count": 10, + "content_created_at": "2012-12-12T10:53:43-08:00", + "content_modified_at": "2012-12-12T10:53:43-08:00", + "created_at": "2012-12-12T10:53:43-08:00", + "created_by": { + "id": "11446498", + "type": "user", + "login": "ceo@example.com", + "name": "Aaron Levie" + }, + "description": "Contract for Q1 renewal", + "disposition_at": "2012-12-12T10:53:43-08:00", + "etag": "1", + "expires_at": "2012-12-12T10:53:43-08:00", + "expiring_embed_link": { + "access_token": "c3FIOG9vSGV4VHo4QzAyg5T1JvNnJoZ3ExaVNyQWw6WjRsanRKZG5lQk9qUE1BVQ", + "expires_in": 3600, + "restricted_to": [ + { + "scope": "item_download", + "object": { + "id": "12345", + "etag": "1", + "type": "folder", + "sequence_id": "3", + "name": "Contracts" + } + } + ], + "token_type": "bearer", + "url": "https://cloud.app.box.com/preview/expiring_embed/..." + }, + "extension": "pdf", + "file_version": { + "id": "12345", + "type": "file_version", + "sha1": "134b65991ed521fcfe4724b7d814ab8ded5185dc" + }, + "has_collaborations": true, + "is_accessible_via_shared_link": true, + "is_externally_owned": true, + "is_package": true, + "item_status": "active", + "lock": { + "id": "11446498", + "type": "lock", + "app_type": "office_wopiplus", + "created_at": "2012-12-12T10:53:43-08:00", + "created_by": { + "id": "11446498", + "type": "user", + "login": "ceo@example.com", + "name": "Aaron Levie" + }, + "expired_at": "2012-12-12T10:53:43-08:00", + "is_download_prevented": true + }, + "metadata": { + "enterprise_27335": { + "marketingCollateral": { + "$canEdit": true, + "$id": "01234500-12f1-1234-aa12-b1d234cb567e", + "$parent": "folder_59449484661", + "$scope": "enterprise_27335", + "$template": "marketingCollateral", + "$type": "properties-6bcba49f-ca6d-4d2a-a758-57fe6edf44d0", + "$typeVersion": 2, + "$version": 1 + } + } + }, + "modified_at": "2012-12-12T10:53:43-08:00", + "modified_by": { + "id": "11446498", + "type": "user", + "login": "ceo@example.com", + "name": "Aaron Levie" + }, + "name": "Contract.pdf", + "owned_by": { + "id": "11446498", + "type": "user", + "login": "ceo@example.com", + "name": "Aaron Levie" + }, + "parent": { + "id": "12345", + "type": "folder", + "etag": "1", + "name": "Contracts", + "sequence_id": "3" + }, + "path_collection": { + "entries": [ + { + "id": "12345", + "etag": "1", + "type": "folder", + "sequence_id": "3", + "name": "Contracts" + } + ], + "total_count": 1 + }, + "permissions": { + "can_annotate": true, + "can_comment": true, + "can_delete": true, + "can_download": true, + "can_invite_collaborator": true, + "can_preview": true, + "can_rename": true, + "can_set_share_access": true, + "can_share": true, + "can_upload": true, + "can_view_annotations_all": true, + "can_view_annotations_self": true + }, + "purged_at": "2012-12-12T10:53:43-08:00", + "representations": { + "entries": [ + { + "content": { + "url_template": "https://dl.boxcloud.com/api/2.0/internal_files/123/versions/345/representations/png_paged_2048x2048/content/{+asset_path}?watermark_content=4567" + }, + "info": { + "url": "https://api.box.com/2.0/internal_files/123/versions/345/representations/png_paged_2048x2048" + }, + "properties": { + "dimensions": "2048x2048", + "paged": true, + "thumb": true + }, + "representation": "png", + "status": { + "state": "success" + } + } + ] + }, + "sequence_id": "3", + "sha1": "85136C79CBF9FE36BB9D05D0639C70C265C18D37", + "shared_link": { + "access": "open", + "download_count": 3, + "download_url": "https://www.box.com/shared/static/rh935iit6ewrmw0unyul.jpeg", + "effective_access": "company", + "effective_permission": "can_download", + "is_password_enabled": true, + "permissions": { + "can_download": true, + "can_edit": false, + "can_preview": true + }, + "preview_count": 3, + "unshared_at": "2018-04-13T13:53:23-07:00", + "url": "https://www.box.com/s/vspke7y05sb214wjokpk", + "vanity_name": "my_url", + "vanity_url": "https://acme.app.box.com/v/my_url/" + }, + "shared_link_permission_options": [ + "can_preview" + ], + "size": 629644, + "tags": [ + "approved" + ], + "trashed_at": "2012-12-12T10:53:43-08:00", + "uploader_display_name": "Ellis Wiggins", + "version_number": "1", + "watermark_info": { + "is_watermarked": true + } +} \ No newline at end of file diff --git a/src/test/java/com/box/sdk/BoxItemTest.java b/src/test/java/com/box/sdk/BoxItemTest.java index 01cc7f061..d54e71f84 100644 --- a/src/test/java/com/box/sdk/BoxItemTest.java +++ b/src/test/java/com/box/sdk/BoxItemTest.java @@ -1,13 +1,35 @@ package com.box.sdk; import com.eclipsesource.json.JsonObject; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import java.util.Collections; +import static com.box.sdk.http.ContentType.APPLICATION_JSON; +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static java.lang.String.format; +import static org.junit.Assert.assertEquals; + public class BoxItemTest { + + @Rule + public WireMockRule wireMockRule = new WireMockRule(wireMockConfig().dynamicHttpsPort().httpDisabled(true)); + private final BoxAPIConnection api = TestUtils.getAPIConnection(); + + @Before + public void setUpBaseUrl() { + api.setMaxRetryAttempts(1); + api.setBaseURL(format("https://localhost:%d", wireMockRule.httpsPort())); + api.setBaseUploadURL(format("https://localhost:%d", wireMockRule.httpsPort())); + } + @Test public void shouldUseRequestInterceptor() { String itemType = "file"; @@ -33,4 +55,47 @@ public void shouldUseRequestInterceptor() { MatcherAssert.assertThat(item.getType(), CoreMatchers.is(itemType)); MatcherAssert.assertThat(item.getID(), CoreMatchers.is(itemId)); } + + @Test + public void shouldgetSharedItemWithoutPasswordAndUseBaseClient() { + final String sharedLink = "https://app.box.com/s/kwio6b4ovt1264rnfbyqo1"; + final String expectedSharedLinkHeaderValue = "shared_link=" + sharedLink; + final String sharedItemsURL = "/2.0/shared_items"; + + String result = TestUtils.getFixture("BoxItem/GetSharedItemFile200"); + + wireMockRule.stubFor(WireMock.get(WireMock.urlPathEqualTo(sharedItemsURL)) + .willReturn(WireMock.aResponse() + .withHeader("Content-Type", APPLICATION_JSON) + .withBody(result))); + + BoxItem.Info itemInfo = BoxItem.getSharedItem(api, sharedLink); + + assertEquals("file", itemInfo.getType()); + + verify(1, getRequestedFor( + urlEqualTo("/2.0/shared_items")).withHeader("BoxApi", equalTo(expectedSharedLinkHeaderValue))); + } + + @Test + public void shouldgetSharedItemWithPasswordAndUseBaseClient() { + final String sharedLink = "https://app.box.com/s/kwio6b4ovt1264rnfbyqo1"; + final String password = "letmein"; + final String expectedSharedLinkHeaderValue = "shared_link=" + sharedLink + "&shared_link_password=" + password; + final String sharedItemsURL = "/2.0/shared_items"; + + String result = TestUtils.getFixture("BoxItem/GetSharedItemFile200"); + + wireMockRule.stubFor(WireMock.get(WireMock.urlPathEqualTo(sharedItemsURL)) + .willReturn(WireMock.aResponse() + .withHeader("Content-Type", APPLICATION_JSON) + .withBody(result))); + + BoxItem.Info itemInfo = BoxItem.getSharedItem(api, sharedLink, password); + + assertEquals("file", itemInfo.getType()); + + verify(1, getRequestedFor( + urlEqualTo("/2.0/shared_items")).withHeader("BoxApi", equalTo(expectedSharedLinkHeaderValue))); + } }