From bc0f9a984c2d194ff64084252e4df38751c14790 Mon Sep 17 00:00:00 2001 From: Daniel Lublin Date: Tue, 17 May 2022 14:47:52 +0200 Subject: [PATCH] Add method for fetching api versions that the mailbox supports --- .../bramble/mailbox/MailboxApi.java | 3 + .../bramble/mailbox/MailboxApiImpl.java | 60 +++++++++---- .../bramble/mailbox/MailboxApiTest.java | 89 +++++++++++++++++++ 3 files changed, 133 insertions(+), 19 deletions(-) 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 37b6ca042..8f373d334 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 @@ -31,6 +31,9 @@ interface MailboxApi { List CLIENT_SUPPORTS = singletonList( new MailboxVersion(1, 0)); + List getServerSupports(MailboxProperties properties) + throws IOException, ApiException; + /** * Sets up the mailbox with the setup token. * 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 944bc2fcb..e96015f9c 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 @@ -56,6 +56,23 @@ class MailboxApiImpl implements MailboxApi { this.httpClientProvider = httpClientProvider; } + @Override + public List getServerSupports(MailboxProperties properties) + throws IOException, ApiException { + if (!properties.isOwner()) throw new IllegalArgumentException(); + Response response = sendGetRequest(properties, "/versions"); + if (response.code() != 200) throw new ApiException(); + + ResponseBody body = response.body(); + if (body == null) throw new ApiException(); + try { + JsonNode node = mapper.readTree(body.string()); + return parseServerSupports(node); + } catch (JacksonException e) { + throw new ApiException(); + } + } + @Override public MailboxProperties setup(MailboxProperties properties) throws IOException, ApiException { @@ -76,32 +93,37 @@ class MailboxApiImpl implements MailboxApi { if (tokenNode == null) { throw new ApiException(); } - List serverSupports = new ArrayList<>(); - ArrayNode serverSupportsNode = getArray(node, "serverSupports"); - for (JsonNode versionNode : serverSupportsNode) { - if (!versionNode.isObject()) throw new ApiException(); - ObjectNode objectNode = (ObjectNode) versionNode; - JsonNode majorNode = objectNode.get("major"); - JsonNode minorNode = objectNode.get("minor"); - if (majorNode == null || !majorNode.isNumber()) { - throw new ApiException(); - } - if (minorNode == null || !minorNode.isNumber()) { - throw new ApiException(); - } - int major = majorNode.asInt(); - int minor = minorNode.asInt(); - if (major < 0 || minor < 0) throw new ApiException(); - serverSupports.add(new MailboxVersion(major, minor)); - } return new MailboxProperties(properties.getBaseUrl(), MailboxAuthToken.fromString(tokenNode.textValue()), - true, serverSupports); + true, parseServerSupports(node)); } catch (JacksonException | InvalidMailboxIdException e) { throw new ApiException(); } } + private List parseServerSupports(JsonNode node) + throws ApiException { + List serverSupports = new ArrayList<>(); + ArrayNode serverSupportsNode = getArray(node, "serverSupports"); + for (JsonNode versionNode : serverSupportsNode) { + if (!versionNode.isObject()) throw new ApiException(); + ObjectNode objectNode = (ObjectNode) versionNode; + JsonNode majorNode = objectNode.get("major"); + JsonNode minorNode = objectNode.get("minor"); + if (majorNode == null || !majorNode.isNumber()) { + throw new ApiException(); + } + if (minorNode == null || !minorNode.isNumber()) { + throw new ApiException(); + } + int major = majorNode.asInt(); + int minor = minorNode.asInt(); + if (major < 0 || minor < 0) throw new ApiException(); + serverSupports.add(new MailboxVersion(major, minor)); + } + return serverSupports; + } + @Override public boolean checkStatus(MailboxProperties properties) throws IOException, ApiException { 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 d39bedddf..de5075c0b 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 @@ -9,6 +9,7 @@ import org.briarproject.bramble.api.mailbox.MailboxFileId; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxId; import org.briarproject.bramble.api.mailbox.MailboxProperties; +import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.mailbox.MailboxApi.ApiException; import org.briarproject.bramble.mailbox.MailboxApi.MailboxContact; import org.briarproject.bramble.mailbox.MailboxApi.MailboxFile; @@ -79,6 +80,94 @@ public class MailboxApiTest extends BrambleTestCase { private final MailboxContact mailboxContact = new MailboxContact( contactId, contactToken, contactInboxId, contactOutboxId); + @Test + public void testGetServerSupports() throws Exception { + String validVersions = "[ {\"major\":1,\"minor\":0} ]"; + String validResponse = makeVersionsResponse(validVersions); + String invalidResponse = "{\"foo\":\"bar\"}"; + String invalidVersionsResponse = makeVersionsResponse("42"); + String invalidVersionsResponse2 = makeVersionsResponse("[ 1,0 ]"); + String invalidVersionsResponse3 = + makeVersionsResponse("[ {\"major\":1, \"minor\":-1} ]"); + + MockWebServer server = new MockWebServer(); + server.enqueue(new MockResponse().setBody(validResponse)); + server.enqueue(new MockResponse().setBody(invalidResponse)); + server.enqueue(new MockResponse().setResponseCode(401)); + server.enqueue(new MockResponse().setResponseCode(500)); + server.enqueue(new MockResponse().setBody(invalidVersionsResponse)); + server.enqueue(new MockResponse().setBody(invalidVersionsResponse2)); + server.enqueue(new MockResponse().setBody(invalidVersionsResponse3)); + server.start(); + String baseUrl = getBaseUrl(server); + List versions = singletonList(new MailboxVersion(1, 0)); + MailboxProperties properties = + new MailboxProperties(baseUrl, token, true, new ArrayList<>()); + MailboxProperties properties2 = + new MailboxProperties(baseUrl, token2, true, new ArrayList<>()); + + RecordedRequest request; + + // valid response with valid token + assertEquals(versions, api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + + // invalid response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + + // 401 response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties2)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token2); + + // 500 response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + + // invalid non-array serverSupports response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + + // invalid non-object in serverSupports array response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + + // invalid negative minor version in serverSupports response + assertThrows(ApiException.class, + () -> api.getServerSupports(properties)); + request = server.takeRequest(); + assertEquals("/versions", request.getPath()); + assertEquals("GET", request.getMethod()); + assertToken(request, token); + } + + private String makeVersionsResponse(String versions) { + return "{\"serverSupports\":" + versions + "}"; + } + @Test public void testSetup() throws Exception { String validVersions = "[ {\"major\":1,\"minor\":0} ]";