diff --git a/build.gradle b/build.gradle index cfd8162..977d908 100644 --- a/build.gradle +++ b/build.gradle @@ -111,6 +111,7 @@ dependencies { compile 'org.xerial:sqlite-jdbc:3.20.0' testCompile 'junit:junit:4.12' + testCompile 'com.github.tomakehurst:wiremock:2.8.0' } springBoot { diff --git a/docs/backends/rest.md b/docs/backends/rest.md index e3c0eec..9ff9c05 100644 --- a/docs/backends/rest.md +++ b/docs/backends/rest.md @@ -101,8 +101,8 @@ If a match was found: "medium": "email", "address": "john.doe@example.org", "id": { - "type": "mxisd", - "value": "@jane:example.org" + "type": "mxid", + "value": "@john:example.org" } } } @@ -153,7 +153,7 @@ For all entries where a match was found: "medium": "msisdn", "address": "123456789", "id": { - "type": "mxisd", + "type": "mxid", "value": "@jane:example.org" } } diff --git a/src/main/groovy/io/kamax/mxisd/backend/rest/RestThreePidProvider.java b/src/main/groovy/io/kamax/mxisd/backend/rest/RestThreePidProvider.java index 88bcdbe..0434396 100644 --- a/src/main/groovy/io/kamax/mxisd/backend/rest/RestThreePidProvider.java +++ b/src/main/groovy/io/kamax/mxisd/backend/rest/RestThreePidProvider.java @@ -33,6 +33,8 @@ import io.kamax.mxisd.lookup.provider.IThreePidProvider; import io.kamax.mxisd.util.RestClientUtils; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -45,6 +47,8 @@ import java.util.stream.Collectors; @Component public class RestThreePidProvider extends RestProvider implements IThreePidProvider { + private Logger log = LoggerFactory.getLogger(RestThreePidProvider.class); + private MatrixConfig mxCfg; // FIXME should be done in the lookup manager @Autowired @@ -56,9 +60,9 @@ public class RestThreePidProvider extends RestProvider implements IThreePidProvi // TODO refactor in lookup manager with above FIXME private _MatrixID getMxId(UserID id) { if (UserIdType.Localpart.is(id.getType())) { - return new MatrixID(id.getValue()); - } else { return new MatrixID(id.getValue(), mxCfg.getDomain()); + } else { + return new MatrixID(id.getValue()); } } @@ -80,13 +84,14 @@ public class RestThreePidProvider extends RestProvider implements IThreePidProvi // TODO refactor common code @Override public Optional find(SingleLookupRequest request) { - HttpUriRequest req = RestClientUtils.post( - cfg.getEndpoints().getIdentity().getSingle(), gson, "lookup", + String endpoint = cfg.getEndpoints().getIdentity().getSingle(); + HttpUriRequest req = RestClientUtils.post(endpoint, gson, "lookup", new LookupSingleRequestJson(request.getType(), request.getThreePid())); try (CloseableHttpResponse res = client.execute(req)) { int status = res.getStatusLine().getStatusCode(); if (status < 200 || status >= 300) { + log.warn("REST endpoint {} answered with status {}, no binding found", endpoint, status); return Optional.empty(); } diff --git a/src/test/java/io/kamax/mxisd/backend/rest/RestThreePidProviderTest.java b/src/test/java/io/kamax/mxisd/backend/rest/RestThreePidProviderTest.java new file mode 100644 index 0000000..0289b12 --- /dev/null +++ b/src/test/java/io/kamax/mxisd/backend/rest/RestThreePidProviderTest.java @@ -0,0 +1,147 @@ +package io.kamax.mxisd.backend.rest; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import io.kamax.matrix.ThreePidMedium; +import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.rest.RestBackendConfig; +import io.kamax.mxisd.lookup.SingleLookupReply; +import io.kamax.mxisd.lookup.SingleLookupRequest; +import io.kamax.mxisd.lookup.ThreePidMapping; +import org.apache.commons.lang.StringUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class RestThreePidProviderTest { + + @Rule + public WireMockRule wireMockRule = new WireMockRule(65000); + + private RestThreePidProvider p; + + private String lookupSinglePath = "/lookup/single"; + private SingleLookupRequest lookupSingleRequest; + private String lookupSingleRequestBody = "{\"lookup\":{\"medium\":\"email\",\"address\":\"john.doe@example.org\"}}"; + private String lookupSingleFoundBody = "{\"lookup\":{\"medium\":\"email\",\"address\":\"john.doe@example.org\"" + + ",\"id\":{\"type\":\"mxid\",\"value\":\"@john:example.org\"}}}"; + private String lookupSingleNotFoundBody = "{}"; + + private String lookupBulkPath = "/lookup/bulk"; + private List lookupBulkList; + private String lookupBulkRequestBody = "{\"lookup\":[{\"medium\":\"email\",\"address\":\"john.doe@example.org\"}," + + "{\"medium\":\"msisdn\",\"address\":\"123456789\"}]}"; + private String lookupBulkFoundBody = "{\"lookup\":[{\"medium\":\"email\",\"address\":\"john.doe@example.org\"," + + "\"id\":{\"type\":\"localpart\",\"value\":\"john\"}},{\"medium\":\"msisdn\",\"address\":\"123456789\"," + + "\"id\":{\"type\":\"mxid\",\"value\":\"@jane:example.org\"}}]}"; + private String lookupBulkNotFoundBody = "{\"lookup\":[]}"; + + @Before + public void before() { + MatrixConfig mxCfg = new MatrixConfig(); + mxCfg.setDomain("example.org"); + mxCfg.build(); + + RestBackendConfig cfg = new RestBackendConfig(); + cfg.setEnabled(true); + cfg.setHost("http://localhost:65000"); + cfg.getEndpoints().getIdentity().setSingle(lookupSinglePath); + cfg.getEndpoints().getIdentity().setBulk("/lookup/bulk"); + cfg.build(); + + p = new RestThreePidProvider(cfg, mxCfg); + + lookupSingleRequest = new SingleLookupRequest(); + lookupSingleRequest.setType(ThreePidMedium.Email.getId()); + lookupSingleRequest.setThreePid("john.doe@example.org"); + + ThreePidMapping m1 = new ThreePidMapping(); + m1.setMedium(ThreePidMedium.Email.getId()); + m1.setValue("john.doe@example.org"); + + ThreePidMapping m2 = new ThreePidMapping(); + m1.setMedium(ThreePidMedium.PhoneNumber.getId()); + m1.setValue("123456789"); + lookupBulkList = new ArrayList<>(); + lookupBulkList.add(m1); + lookupBulkList.add(m2); + } + + @Test + public void lookupSingleFound() { + stubFor(post(urlEqualTo(lookupSinglePath)) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(lookupSingleFoundBody) + ) + ); + + Optional rep = p.find(lookupSingleRequest); + assertTrue(rep.isPresent()); + rep.ifPresent(data -> { + assertNotNull(data.getMxid()); + assertTrue(data.getMxid().getId(), StringUtils.equals(data.getMxid().getId(), "@john:example.org")); + }); + + verify(postRequestedFor(urlMatching("/lookup/single")) + .withHeader("Content-Type", containing("application/json")) + .withRequestBody(equalTo(lookupSingleRequestBody)) + ); + } + + @Test + public void lookupSingleNotFound() { + stubFor(post(urlEqualTo(lookupSinglePath)) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(lookupSingleNotFoundBody) + ) + ); + + Optional rep = p.find(lookupSingleRequest); + assertTrue(!rep.isPresent()); + + verify(postRequestedFor(urlMatching("/lookup/single")) + .withHeader("Content-Type", containing("application/json")) + .withRequestBody(equalTo(lookupSingleRequestBody)) + ); + } + + @Test + public void lookupBulkFound() { + stubFor(post(urlEqualTo(lookupBulkPath)) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(lookupBulkFoundBody) + ) + ); + + List mappings = p.populate(lookupBulkList); + assertNotNull(mappings); + assertTrue(mappings.size() == 2); + assertTrue(StringUtils.equals(mappings.get(0).getMxid(), "@john:example.org")); + assertTrue(StringUtils.equals(mappings.get(1).getMxid(), "@jane:example.org")); + } + + @Test + public void lookupBulkNotFound() { + stubFor(post(urlEqualTo(lookupBulkPath)) + .willReturn(aResponse() + .withHeader("Content-Type", "application/json") + .withBody(lookupBulkNotFoundBody) + ) + ); + + List mappings = p.populate(lookupBulkList); + assertNotNull(mappings); + assertTrue(mappings.size() == 0); + } + +}