From 3a191908c02a517419b8255628f7edc994805188 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Fri, 21 Jan 2022 13:58:39 -0300 Subject: [PATCH] Add method for listing folders with files available for download (owner only) --- .../bramble/mailbox/MailboxApi.java | 11 ++ .../bramble/mailbox/MailboxApiImpl.java | 33 ++++++ .../bramble/mailbox/MailboxApiTest.java | 101 ++++++++++++++++++ 3 files changed, 145 insertions(+) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java index 6a5b946f9..29f94e55f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java @@ -96,6 +96,17 @@ interface MailboxApi { void deleteFile(MailboxProperties properties, String folderId, String fileId) throws IOException, ApiException; + /** + * Lists all contact outboxes that have files available + * for the owner to download. + * + * @return a list of folder names + * to be used with {@link #getFiles(MailboxProperties, String)}. + * @throws IllegalArgumentException if used by non-owner. + */ + List getFolders(MailboxProperties properties) + throws IOException, ApiException; + @Immutable @JsonSerialize class MailboxContact { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiImpl.java index a027f41eb..60ee4858f 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApiImpl.java @@ -234,6 +234,39 @@ class MailboxApiImpl implements MailboxApi { if (response.code() != 200) throw new ApiException(); } + @Override + public List getFolders(MailboxProperties properties) + throws IOException, ApiException { + if (!properties.isOwner()) throw new IllegalArgumentException(); + Response response = sendGetRequest(properties, "/folders"); + if (response.code() != 200) throw new ApiException(); + + ResponseBody body = response.body(); + if (body == null) throw new ApiException(); + try { + JsonNode node = mapper.readTree(body.string()); + JsonNode filesNode = node.get("folders"); + if (filesNode == null || !filesNode.isArray()) { + throw new ApiException(); + } + List list = new ArrayList<>(); + for (JsonNode fileNode : filesNode) { + if (!fileNode.isObject()) throw new ApiException(); + ObjectNode objectNode = (ObjectNode) fileNode; + JsonNode idNode = objectNode.get("id"); + if (idNode == null || !idNode.isTextual()) { + throw new ApiException(); + } + String id = idNode.asText(); + if (!isValidToken(id)) throw new ApiException(); + list.add(id); + } + return list; + } catch (JacksonException e) { + throw new ApiException(); + } + } + /* Helper Functions */ private Response sendGetRequest(MailboxProperties properties, String path) diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java index 082a81df1..2e90525af 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java @@ -16,6 +16,7 @@ import org.junit.rules.TemporaryFolder; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.annotation.Nonnull; @@ -622,6 +623,106 @@ public class MailboxApiTest extends BrambleTestCase { assertToken(request3, token); } + @Test + public void testGetFolders() throws Exception { + String id1 = getMailboxSecret(); + String id2 = getMailboxSecret(); + String validResponse1 = "{\"folders\": [ {\"id\": \"" + id1 + "\"} ] }"; + String validResponse2 = "{\"folders\": [ {\"id\": \"" + id1 + "\"}, " + + "{ \"id\": \"" + id2 + "\"} ] }"; + String invalidResponse1 = "{\"folders\":\"bar\"}"; + String invalidResponse2 = "{\"folders\":{\"foo\":\"bar\"}}"; + String invalidResponse3 = + "{\"folders\": [ {\"id\": \"" + id1 + "\", 1] }"; + String invalidResponse4 = "{\"files\": [ 1, 2 ] }"; + + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody(validResponse1)); + server.enqueue(new MockResponse().setBody(validResponse2)); + server.enqueue(new MockResponse()); + server.enqueue(new MockResponse().setBody(invalidResponse1)); + server.enqueue(new MockResponse().setBody(invalidResponse2)); + server.enqueue(new MockResponse().setBody(invalidResponse3)); + server.enqueue(new MockResponse().setBody(invalidResponse4)); + server.enqueue(new MockResponse().setResponseCode(401)); + server.enqueue(new MockResponse().setResponseCode(500)); + server.start(); + String baseUrl = getBaseUrl(server); + MailboxProperties properties = + new MailboxProperties(baseUrl, token, true); + + // valid response with one folders + assertEquals(singletonList(id1), api.getFolders(properties)); + RecordedRequest request1 = server.takeRequest(); + assertEquals("/folders", request1.getPath()); + assertEquals("GET", request1.getMethod()); + assertToken(request1, token); + + // valid response with two folders + assertEquals(Arrays.asList(id1, id2), api.getFolders(properties)); + RecordedRequest request2 = server.takeRequest(); + assertEquals("/folders", request1.getPath()); + assertEquals("GET", request2.getMethod()); + assertToken(request2, token); + + // empty body + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request3 = server.takeRequest(); + assertEquals("/folders", request3.getPath()); + assertEquals("GET", request3.getMethod()); + assertToken(request3, token); + + // invalid response: string instead of list + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request4 = server.takeRequest(); + assertEquals("/folders", request4.getPath()); + assertEquals("GET", request4.getMethod()); + assertToken(request4, token); + + // invalid response: object instead of list + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request5 = server.takeRequest(); + assertEquals("/folders", request5.getPath()); + assertEquals("GET", request5.getMethod()); + assertToken(request5, token); + + // invalid response: list with non-objects + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request6 = server.takeRequest(); + assertEquals("/folders", request6.getPath()); + assertEquals("GET", request6.getMethod()); + assertToken(request6, token); + + // no folders key in root object + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request7 = server.takeRequest(); + assertEquals("/folders", request7.getPath()); + assertEquals("GET", request7.getMethod()); + assertToken(request7, token); + + // 401 not authorized + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request8 = server.takeRequest(); + assertEquals("/folders", request8.getPath()); + assertEquals("GET", request8.getMethod()); + assertToken(request8, token); + + // 500 internal server error + assertThrows(ApiException.class, () -> api.getFolders(properties)); + RecordedRequest request9 = server.takeRequest(); + assertEquals("/folders", request9.getPath()); + assertEquals("GET", request9.getMethod()); + assertToken(request9, token); + } + + @Test + public void testGetFoldersOnlyForOwner() { + MailboxProperties properties = + new MailboxProperties("", token, false); + assertThrows(IllegalArgumentException.class, () -> + api.getFolders(properties)); + } + private String getBaseUrl(MockWebServer server) { String baseUrl = server.url("").toString(); return baseUrl.substring(0, baseUrl.length() - 1);