From a58dd004e519fb08045bdbfd3cd6dba25ae22017 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Fri, 19 May 2017 14:04:11 +0300 Subject: [PATCH 1/7] Added allow-all CORS filter refers #2163 --- .../src/main/webapp/WEB-INF/web.xml | 11 +++-- .../connect/http/cors/CorsFilter.java | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java diff --git a/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml b/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml index 4cde237650..4295947db9 100644 --- a/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml +++ b/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml @@ -8,13 +8,18 @@ Jersey com.sun.jersey.spi.container.servlet.ServletContainer + + + com.sun.jersey.spi.container.ContainerResponseFilters + org.restcomm.connect.http.cors.CorsFilter + resteasy.scan false - + resteasy.scan.providers false @@ -24,12 +29,12 @@ resteasy.scan.resources false - + Jersey /2012-04-24/* - + index.html diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java new file mode 100644 index 0000000000..48023fdd20 --- /dev/null +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java @@ -0,0 +1,44 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + */ + +package org.restcomm.connect.http.cors; + +import com.sun.jersey.spi.container.ContainerRequest; +import com.sun.jersey.spi.container.ContainerResponse; +import com.sun.jersey.spi.container.ContainerResponseFilter; + +import javax.ws.rs.ext.Provider; + +/** + * @author otsakir@gmail.com - Orestis Tsakiridis + */ +@Provider +public class CorsFilter implements ContainerResponseFilter { + + @Override + public ContainerResponse filter(ContainerRequest cres, ContainerResponse response) { + response.getHttpHeaders().add("Access-Control-Allow-Origin", "*"); + response.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); + response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true"); + response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); + response.getHttpHeaders().add("Access-Control-Max-Age", "1209600"); + return response; + } +} From 2805a23e1e326b87b615ba3b39ec4144457a6a50 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Thu, 15 Jun 2017 14:18:02 +0300 Subject: [PATCH 2/7] Reviewed restcomm.xml 'rcmlserver-api' section, configuration classes and RcmlserverApi class - renamed rcmlserver-api to rcmlserver - added api-path property Refers #2230 --- .../src/main/webapp/WEB-INF/conf/restcomm.xml | 9 ++++---- .../sets/RcmlserverConfigurationSet.java | 1 + .../impl/RcmlserverConfigurationSetImpl.java | 23 +++++++++++++++---- .../http/client/rcmlserver/RcmlserverApi.java | 13 +++++++++-- .../resources/restcomm-accountRemoval.xml | 3 ++- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml b/restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml index 4a67870fcf..d89cf0c3e4 100644 --- a/restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml +++ b/restcomm/restcomm.application/src/main/webapp/WEB-INF/conf/restcomm.xml @@ -383,17 +383,18 @@ - - /restcomm-rvd/services + + /restcomm-rvd/services true 5000 500 - + - http://localhost:8089/restcomm-rvd/services + http://localhost:8089 + /restcomm-rvd/services true From 3feaa8f0c4105f2d65fb6568578cae40b3e23f84 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Thu, 15 Jun 2017 15:14:39 +0300 Subject: [PATCH 3/7] Fixed broken AccountsEndpointClosingTest This relates to 'rcmlserver' configuration section since it used it Refers #2230 --- .../resources/restcomm-accountRemoval.xml | 353 +++++++++++++----- 1 file changed, 260 insertions(+), 93 deletions(-) diff --git a/restcomm/restcomm.testsuite/src/test/resources/restcomm-accountRemoval.xml b/restcomm/restcomm.testsuite/src/test/resources/restcomm-accountRemoval.xml index 048feb9f09..a5f4c154eb 100644 --- a/restcomm/restcomm.testsuite/src/test/resources/restcomm-accountRemoval.xml +++ b/restcomm/restcomm.testsuite/src/test/resources/restcomm-accountRemoval.xml @@ -1,24 +1,4 @@ - - /restcomm/audio + + beep.wav + alert.wav + ${restcomm:home}/cache /restcomm/cache + + false + file://${restcomm:home}/recordings /restcomm/recordings @@ -72,16 +62,28 @@ from those users --> true + + + false + + + 5060 + WebRTCGW__1@ + WebRTCGW/1.0 + + + 60 - true - + false + true true + + false + + + + false + + + + false + + + false + + + + false + @@ -104,14 +130,15 @@ proxy when --> - true + + false true - true + false 20 @@ -119,21 +146,30 @@ true + false restcomm restcomm restcomm_instance_id + site_id http://127.0.0.1:2080 - 127.0.0.1:5090 + + + + http://GMLC-IP:port/restcomm/gmlc/rest?msisdn= + + + + @@ -155,6 +191,9 @@ RestComm:Read:SmsMessages RestComm:Read:Transcriptions RestComm:*:OutboundProxies + RestComm:*:EmailMessages + RestComm:*:Usage + RestComm:*:Geolocation RestComm:Read:Accounts @@ -163,19 +202,75 @@ - + + + + + + + - - - - + + + + + + + + + https://backoffice.voipinnovations.com/api2.pl + + + + + + + https://api.inetwork.com/v1.0 + - randomkey - randomsecret - http://127.0.0.1:8089/nexmo + + + https://rest.nexmo.com/ + + + + + https://api.voxbone.com/ws-voxbone/services/rest + @@ -189,8 +284,7 @@ - - + @@ -203,8 +297,27 @@ false - 7 + 10 true + us-east-1 + + secure + false + http://127.0.0.1:8090/s3 + abandoning the request. This does NOT apply to RQNT/NOTIFY request/response. + This indicates rtp timeout, in seconds. + This is used to indicate when the RTP/RTCP timeout + timer starts. It can have one of the following values: + * "im" for immediate i.e., the timer starts as soon as the + request is received. This is the default. + * "ra" to indicate that the timer should start only after an + RTCP packet has been received from the other end (i.e., the + timer will be initiated when the first RTCP packet is + received after the request is made). Note that in the case + where the other end does not support RTCP, the timer will + never be initiated.--> - + 127.0.0.1 2727 127.0.0.1 2427 - 1500 - + 500 + + 60 + im + + - - + - 5000 + 6000 @@ -260,21 +386,30 @@ - - + + http://localhost:8089 /restcomm-rvd/services true - + 5000 + 500 + - 127.0.0.1:5090 + 127.0.0.1:5070 + @@ -334,34 +469,45 @@ - + http://vaas.acapela-group.com/Services/Synthesizer - - justine8k - marcia8k - rachel8k graham8k - louise8k - eliska8k mette8k - rasmus8k heather8k ryan8k - sanna8k - claire8k bruno8k sarah8k - klaus8k dimitris8k - chiara8k vittorio8k - jasmijn8k daan8k - kari8k olav8k - ania8k celia8k - alyona8k - salma8k mehdi8k - laia8k - maria8k antonio8k - elin8k emil8k - ipek8k --> - - + + + + + justine8k + marcia8k + rachel8k graham8k + louise8k + eliska8k + mette8krasmus8k + laura8k ryan8k + sanna8k + claire8k bruno8k + sarah8k klaus8k + dimitris8k + chiara8k vittorio8k + jasmijn8k daan8k + kari8k olav8k + ania8k + celia8k + alyona8k + salma8k mehdi8k + laia8k + maria8k antonio8k + elin8k emil8k + ipek8k + lulu8k + sakura8k + + + + http://api.voicerss.org - 16824850f3634b9eb8a464350c0b133d + ca-es zh-cn @@ -381,18 +527,7 @@ it-it ja-jp ko-kr - nb-no - - - strict - - true - - - + nb-no pl-pl pt-br pt-pt @@ -401,10 +536,42 @@ es-es sv-se - + + + + + + + + + Mizuki + Filiz + TatyanaMaxim + CarmenMaxim + InesCristiano + VitoriaRicardo + MajaJan + LotteRuben + Liv + CarlaGiorgio + DoraKarl + CelineMathieu + Chantal + PenelopeMiguel + ConchitaEnrique + Geraint + Gwyneth + JoannaJoey + Raveena + EmmaBrian + NicoleRussell + MarleneHans + NajaMads + + - - + \ No newline at end of file From ca24d22533b91774e4c7b3f8fcdcaf576081fb44 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Fri, 16 Jun 2017 00:39:00 +0300 Subject: [PATCH 4/7] Load restcomm.xml and initialize CorsFilter accordingly Refers #2230 --- .../connect/http/cors/CorsFilter.java | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java index 48023fdd20..47cc32adfa 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java @@ -23,8 +23,16 @@ import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerResponse; import com.sun.jersey.spi.container.ContainerResponseFilter; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.XMLConfiguration; +import org.restcomm.connect.commons.configuration.sets.RcmlserverConfigurationSet; +import org.restcomm.connect.commons.configuration.sets.impl.RcmlserverConfigurationSetImpl; +import org.restcomm.connect.commons.configuration.sources.ApacheConfigurationSource; +import org.restcomm.connect.commons.configuration.sources.ConfigurationSource; import javax.ws.rs.ext.Provider; +import java.io.File; +import java.net.URL; /** * @author otsakir@gmail.com - Orestis Tsakiridis @@ -32,13 +40,50 @@ @Provider public class CorsFilter implements ContainerResponseFilter { + String allowedOrigin; + + public CorsFilter() { + // Determine absolute path to restcomm.xml + URL url = CorsFilter.class.getResource("."); + String path = url.getFile(); + String webInfPath = path.substring(0, path.indexOf("/WEB-INF/")); + String restcommXmlPath = webInfPath + "/WEB-INF/conf/restcomm.xml"; + File restcommXmlFile = new File(restcommXmlPath); + // Create apache configuration + XMLConfiguration apacheConf = new XMLConfiguration(); + apacheConf.setDelimiterParsingDisabled(true); + apacheConf.setAttributeSplittingDisabled(true); + try { + apacheConf.load(restcommXmlPath); + } catch (ConfigurationException e) { + e.printStackTrace(); + } + // Create high-level configuration + ConfigurationSource source = new ApacheConfigurationSource(apacheConf); + RcmlserverConfigurationSet rcmlserverConfig = new RcmlserverConfigurationSetImpl(source); + + // initialize allowedOrigin + String baseUrl = rcmlserverConfig.getBaseUrl(); + if ( baseUrl != null && (! baseUrl.trim().equals(""))) { + // baseUrl is set. We need to return CORS allow headers + allowedOrigin = baseUrl; + } + } + + // We return Access-* headers only in case allowedOrigin is present and equals to the 'Origin' header. @Override public ContainerResponse filter(ContainerRequest cres, ContainerResponse response) { - response.getHttpHeaders().add("Access-Control-Allow-Origin", "*"); - response.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); - response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true"); - response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); - response.getHttpHeaders().add("Access-Control-Max-Age", "1209600"); + String requestOrigin = cres.getHeaderValue("Origin"); + if (requestOrigin != null) { // is this is a cors request (ajax request that targets a different domain than the one the page was loaded from) + if (allowedOrigin != null && allowedOrigin.startsWith(requestOrigin)) { // no cors allowances make are applied if allowedOrigins == null + // only return the origin the client informed + response.getHttpHeaders().add("Access-Control-Allow-Origin", requestOrigin); + response.getHttpHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization"); + response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true"); + response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); + response.getHttpHeaders().add("Access-Control-Max-Age", "1209600"); + } + } return response; } } From ef1d591e75edf57c44d03605073c0550a225db56 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Mon, 22 May 2017 02:18:52 +0300 Subject: [PATCH 5/7] Added OPTIONS method to AccountsEndpoint and refined security checks for endpoint's methods Refers #2230 --- .../java/org/restcomm/connect/http/AccountsEndpoint.java | 5 ++++- .../org/restcomm/connect/http/AccountsJsonEndpoint.java | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsEndpoint.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsEndpoint.java index 796de673c7..4ced8a1fda 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsEndpoint.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsEndpoint.java @@ -108,7 +108,6 @@ void init() { xstream.registerConverter(new AccountListConverter(runtimeConfiguration)); xstream.registerConverter(new RestCommResponseConverter(runtimeConfiguration)); // Make sure there is an authenticated account present when this endpoint is used - checkAuthenticatedAccount(); } private Account createFrom(final Sid accountSid, final MultivaluedMap data) throws PasswordTooWeak { @@ -142,6 +141,7 @@ private Account createFrom(final Sid accountSid, final MultivaluedMap data, final MediaType responseType) { + checkAuthenticatedAccount(); //First check if the account has the required permissions in general, this way we can fail fast and avoid expensive DAO operations checkPermission("RestComm:Create:Accounts"); // check account level depth. If we're already at third level no sub-accounts are allowed to be created @@ -476,6 +478,7 @@ private Account prepareAccountForUpdate(final Account account, final Multivalued protected Response updateAccount(final String identifier, final MultivaluedMap data, final MediaType responseType) { + checkAuthenticatedAccount(); // First check if the account has the required permissions in general, this way we can fail fast and avoid expensive DAO // operations checkPermission("RestComm:Modify:Accounts"); diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsJsonEndpoint.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsJsonEndpoint.java index 18d4f0b2c4..34273f2508 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsJsonEndpoint.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/AccountsJsonEndpoint.java @@ -23,6 +23,7 @@ import javax.ws.rs.Consumes; import javax.ws.rs.GET; +import javax.ws.rs.OPTIONS; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -49,6 +50,13 @@ public Response getAccountAsJson(@PathParam("accountSid") final String accountSi return getAccount(accountSid, APPLICATION_JSON_TYPE); } + @Path("/{accountSid}") + @OPTIONS + public Response optionsAccount(@PathParam("accountSid") final String accountSid) { + // no authentication here since this is a pre-flight request + return Response.ok().build(); + } + @GET public Response getAccounts() { return getAccounts(APPLICATION_JSON_TYPE); From eb071676e7e7705391f99e5e08d65659730e19d1 Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Fri, 16 Jun 2017 12:38:55 +0300 Subject: [PATCH 6/7] Reviewed CorsFilter initialization and added automated test Refers #2230 --- .../src/main/webapp/WEB-INF/web.xml | 2 +- .../connect/http/cors/CorsFilter.java | 73 ++- .../connect/testsuite/http/CorsRelaxTest.java | 103 +++ .../src/test/resources/restcomm-corsRelax.xml | 600 ++++++++++++++++++ 4 files changed, 749 insertions(+), 29 deletions(-) create mode 100644 restcomm/restcomm.testsuite/src/test/java/org/restcomm/connect/testsuite/http/CorsRelaxTest.java create mode 100644 restcomm/restcomm.testsuite/src/test/resources/restcomm-corsRelax.xml diff --git a/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml b/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml index 4295947db9..01b2f813b9 100644 --- a/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml +++ b/restcomm/restcomm.application/src/main/webapp/WEB-INF/web.xml @@ -8,7 +8,7 @@ Jersey com.sun.jersey.spi.container.servlet.ServletContainer - + com.sun.jersey.spi.container.ContainerResponseFilters org.restcomm.connect.http.cors.CorsFilter diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java index 47cc32adfa..ec9266a2c8 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java @@ -25,54 +25,39 @@ import com.sun.jersey.spi.container.ContainerResponseFilter; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; import org.restcomm.connect.commons.configuration.sets.RcmlserverConfigurationSet; import org.restcomm.connect.commons.configuration.sets.impl.RcmlserverConfigurationSetImpl; import org.restcomm.connect.commons.configuration.sources.ApacheConfigurationSource; import org.restcomm.connect.commons.configuration.sources.ConfigurationSource; +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; import java.io.File; -import java.net.URL; /** * @author otsakir@gmail.com - Orestis Tsakiridis */ @Provider public class CorsFilter implements ContainerResponseFilter { + private final Logger logger = Logger.getLogger(CorsFilter.class); - String allowedOrigin; + @Context + private HttpServletRequest servletRequest; - public CorsFilter() { - // Determine absolute path to restcomm.xml - URL url = CorsFilter.class.getResource("."); - String path = url.getFile(); - String webInfPath = path.substring(0, path.indexOf("/WEB-INF/")); - String restcommXmlPath = webInfPath + "/WEB-INF/conf/restcomm.xml"; - File restcommXmlFile = new File(restcommXmlPath); - // Create apache configuration - XMLConfiguration apacheConf = new XMLConfiguration(); - apacheConf.setDelimiterParsingDisabled(true); - apacheConf.setAttributeSplittingDisabled(true); - try { - apacheConf.load(restcommXmlPath); - } catch (ConfigurationException e) { - e.printStackTrace(); - } - // Create high-level configuration - ConfigurationSource source = new ApacheConfigurationSource(apacheConf); - RcmlserverConfigurationSet rcmlserverConfig = new RcmlserverConfigurationSetImpl(source); + // we initialize this lazily upon first request since it can't be injected through the @Context annotation (it didn't work) + private ServletContext lazyServletContext; - // initialize allowedOrigin - String baseUrl = rcmlserverConfig.getBaseUrl(); - if ( baseUrl != null && (! baseUrl.trim().equals(""))) { - // baseUrl is set. We need to return CORS allow headers - allowedOrigin = baseUrl; - } - } + String allowedOrigin; // We return Access-* headers only in case allowedOrigin is present and equals to the 'Origin' header. @Override public ContainerResponse filter(ContainerRequest cres, ContainerResponse response) { + initLazily(servletRequest); String requestOrigin = cres.getHeaderValue("Origin"); if (requestOrigin != null) { // is this is a cors request (ajax request that targets a different domain than the one the page was loaded from) if (allowedOrigin != null && allowedOrigin.startsWith(requestOrigin)) { // no cors allowances make are applied if allowedOrigins == null @@ -86,4 +71,36 @@ public ContainerResponse filter(ContainerRequest cres, ContainerResponse respons } return response; } + + private void initLazily(ServletRequest request) { + if (lazyServletContext == null) { + ServletContext context = request.getServletContext(); + String rootPath = context.getRealPath("/"); + rootPath = StringUtils.stripEnd(rootPath,"/"); // remove trailing "/" character + String restcommXmlPath = rootPath + "/WEB-INF/conf/restcomm.xml"; + + // ok, found restcomm.xml. Now let's get rcmlserver/base-url configuration setting + File restcommXmlFile = new File(restcommXmlPath); + // Create apache configuration + XMLConfiguration apacheConf = new XMLConfiguration(); + apacheConf.setDelimiterParsingDisabled(true); + apacheConf.setAttributeSplittingDisabled(true); + try { + apacheConf.load(restcommXmlPath); + } catch (ConfigurationException e) { + e.printStackTrace(); + } + // Create high-level configuration + ConfigurationSource source = new ApacheConfigurationSource(apacheConf); + RcmlserverConfigurationSet rcmlserverConfig = new RcmlserverConfigurationSetImpl(source); + // initialize allowedOrigin + String baseUrl = rcmlserverConfig.getBaseUrl(); + if ( baseUrl != null && (! baseUrl.trim().equals(""))) { + // baseUrl is set. We need to return CORS allow headers + allowedOrigin = baseUrl; + } + + lazyServletContext = context; + } + } } diff --git a/restcomm/restcomm.testsuite/src/test/java/org/restcomm/connect/testsuite/http/CorsRelaxTest.java b/restcomm/restcomm.testsuite/src/test/java/org/restcomm/connect/testsuite/http/CorsRelaxTest.java new file mode 100644 index 0000000000..045562688f --- /dev/null +++ b/restcomm/restcomm.testsuite/src/test/java/org/restcomm/connect/testsuite/http/CorsRelaxTest.java @@ -0,0 +1,103 @@ +/* + * TeleStax, Open Source Cloud Communications + * Copyright 2011-2014, Telestax Inc and individual contributors + * by the @authors tag. + * + * This program is free software: you can redistribute it and/or modify + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + */ + +package org.restcomm.connect.testsuite.http; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import junit.framework.Assert; +import org.apache.log4j.Logger; +import org.jboss.arquillian.container.test.api.Deployer; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.resolver.api.maven.archive.ShrinkWrapMaven; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.restcomm.connect.commons.Version; + +import javax.ws.rs.core.MultivaluedMap; +import java.net.URL; + +/** + * Tests whether CORS restrictions are relaxed when configuration contains an absolute baseurl. + * Currently it only tests Accounts endpoint where CORS-relax logic has been applied + * + * @author otsakir@gmail.com - Orestis Tsakiridis + */ +@RunWith(Arquillian.class) +public class CorsRelaxTest extends EndpointTest { + private final static Logger logger = Logger.getLogger(CorsRelaxTest.class.getName()); + + private static final String version = Version.getVersion(); + + @ArquillianResource + private Deployer deployer; + @ArquillianResource + URL deploymentUrl; + + String accountSid = "ACae6e420f425248d6a26948c17a9e2acf"; + String accountToken = "77f8c12cc7b8f8423e5c38b035249166"; + + // Tests cors headers existence when retrieving an account + @Test + public void corsHeadersAreReturnedForAccount() { + // Bypass jersey restriction for "Origin" header. By default it can't be added to a WebResource object. + System.setProperty("sun.net.http.allowRestrictedHeaders", "true"); + + Client jersey = Client.create(); + // make a preflight OPTIONS request using an origin present in restcomm.xml/rcmlserver i.e. http://testing.restcomm.com + WebResource resource = jersey.resource(getResourceUrl("/2012-04-24/Accounts.json/ACae6e420f425248d6a26948c17a9e2acf")); + ClientResponse response = resource.header("Origin", "http://testing.restcomm.com").options(ClientResponse.class); + Assert.assertEquals(200, response.getStatus()); + MultivaluedMap headers = response.getHeaders(); + String originHeader = headers.getFirst("Access-Control-Allow-Origin"); + Assert.assertEquals("http://testing.restcomm.com",originHeader); + // make a preflight OPTIONS request using an origin NOT present in restcomm.xml/rcmlserver i.e. http://otherhost.restcomm.com + WebResource resource2 = jersey.resource(getResourceUrl("/restcomm/2012-04-24/Accounts.json/ACae6e420f425248d6a26948c17a9e2acf")); + ClientResponse response2 = resource2.header("Origin", "http://otherhost.restcomm.com").options(ClientResponse.class); + originHeader = response2.getHeaders().getFirst("Access-Control-Allow-Origin"); + Assert.assertEquals(200, response2.getStatus()); + Assert.assertNull(originHeader); + + } + + @Deployment(name = "CorsRelaxTest", managed = true, testable = false) + public static WebArchive createWebArchiveNoGw() { + logger.info("Packaging Test App"); + logger.info("version"); + WebArchive archive = ShrinkWrap.create(WebArchive.class, "restcomm.war"); + final WebArchive restcommArchive = ShrinkWrapMaven.resolver() + .resolve("org.restcomm:restcomm-connect.application:war:" + version).withoutTransitivity() + .asSingle(WebArchive.class); + archive = archive.merge(restcommArchive); + archive.delete("/WEB-INF/sip.xml"); + archive.delete("/WEB-INF/conf/restcomm.xml"); + archive.delete("/WEB-INF/data/hsql/restcomm.script"); + archive.addAsWebInfResource("sip.xml"); + archive.addAsWebInfResource("restcomm-corsRelax.xml", "conf/restcomm.xml"); + archive.addAsWebInfResource("restcomm.script", "data/hsql/restcomm.script"); + logger.info("Packaged Test App"); + return archive; + } +} diff --git a/restcomm/restcomm.testsuite/src/test/resources/restcomm-corsRelax.xml b/restcomm/restcomm.testsuite/src/test/resources/restcomm-corsRelax.xml new file mode 100644 index 0000000000..58ed3ba08d --- /dev/null +++ b/restcomm/restcomm.testsuite/src/test/resources/restcomm-corsRelax.xml @@ -0,0 +1,600 @@ + + + + + + + + 2012-04-24 + + + false + + + /restcomm/audio + + + beep.wav + alert.wav + + + ${restcomm:home}/cache + /restcomm/cache + + + false + + + file://${restcomm:home}/recordings + /restcomm/recordings + + + /restcomm/errors + + + + + + true + + + false + + + true + + + + false + + + 5060 + WebRTCGW__1@ + WebRTCGW/1.0 + + + + + 60 + + + false + + true + + + + true + + + false + + + + false + + + + false + + + false + + + + false + + + + + + 127.0.0.1:5070 + + + + + 127.0.0.1:5090 + + + + + false + + + true + + + false + + 20 + + true + + + + + false + restcomm + restcomm + restcomm_instance_id + site_id + http://127.0.0.1:2080 + + + + + + + + + + + + http://GMLC-IP:port/restcomm/gmlc/rest?msisdn= + + + + + + + + RestComm:*:Accounts + RestComm:*:Applications + RestComm:*:Announcements + RestComm:Read:AvailablePhoneNumbers + RestComm:*:Calls + RestComm:*:Clients + RestComm:*:Conferences + RestComm:Create,Delete,Read:Faxes + RestComm:*:IncomingPhoneNumbers + RestComm:Read:Notifications + RestComm:*:OutgoingCallerIds + RestComm:Delete,Read:Recordings + RestComm:Read,Modify:SandBoxes + RestComm:*:ShortCodes + RestComm:Read:SmsMessages + RestComm:Read:Transcriptions + RestComm:*:OutboundProxies + RestComm:*:EmailMessages + RestComm:*:Usage + RestComm:*:Geolocation + + + + + + + + + + + + + + + + + + + + + + https://backoffice.voipinnovations.com/api2.pl + + + + + + + https://api.inetwork.com/v1.0 + + + + + https://rest.nexmo.com/ + + + + + + https://api.voxbone.com/ws-voxbone/services/rest + + + + + + + + + + + + + + + + + + + + + false + restcomm-recordings + + + + false + 10 + true + us-east-1 + + secure + false + http://127.0.0.1:8090/s3 + + + + + rms + +
127.0.0.1
+ 5060 + udp + 5 +
+
+ + + + + 127.0.0.1 + 2727 + 127.0.0.1 + 2427 + 500 + + 60 + im + + + + + + + 6000 + + strict + + true + + + + + + + http://testing.restcomm.com + /restcomm-rvd/services + true + 5000 + 500 + + + + + + 127.0.0.1:5070 + + + + + + + + + + test + test + 127.0.0.1 + 2776 + TRANSCEIVER + + test + sms + + 0x34 + -1 + -1 + + + 1 + + 60000 + + 10000 + + 30000 + + 15000 + true + true + + 30000 + + + + + + + + + + + + + + + + + + + + http://vaas.acapela-group.com/Services/Synthesizer + + + + + justine8k + marcia8k + rachel8k graham8k + louise8k + eliska8k + mette8krasmus8k + laura8k ryan8k + sanna8k + claire8k bruno8k + sarah8k klaus8k + dimitris8k + chiara8k vittorio8k + jasmijn8k daan8k + kari8k olav8k + ania8k + celia8k + alyona8k + salma8k mehdi8k + laia8k + maria8k antonio8k + elin8k emil8k + ipek8k + lulu8k + sakura8k + + + + + http://api.voicerss.org + + + ca-es + zh-cn + zh-hk + zh-tw + da-dk + nl-nl + en-au + en-ca + en-gb + en-in + en-us + fi-fi + fr-ca + fr-fr + de-de + it-it + ja-jp + ko-kr + nb-no + pl-pl + pt-br + pt-pt + ru-ru + es-mx + es-es + sv-se + + + + + + + + + + Mizuki + Filiz + TatyanaMaxim + CarmenMaxim + InesCristiano + VitoriaRicardo + MajaJan + LotteRuben + Liv + CarlaGiorgio + DoraKarl + CelineMathieu + Chantal + PenelopeMiguel + ConchitaEnrique + Geraint + Gwyneth + JoannaJoey + Raveena + EmmaBrian + NicoleRussell + MarleneHans + NajaMads + + + + + +
From 66864c8a282ba798325d20c091388681c84b2b7e Mon Sep 17 00:00:00 2001 From: Orestis Tsakiridis Date: Tue, 20 Jun 2017 10:56:25 +0300 Subject: [PATCH 7/7] Added log message upon initialization of CORS filter Refers #2230 --- .../main/java/org/restcomm/connect/http/cors/CorsFilter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java index ec9266a2c8..9dcb847f88 100644 --- a/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java +++ b/restcomm/restcomm.http/src/main/java/org/restcomm/connect/http/cors/CorsFilter.java @@ -101,6 +101,8 @@ private void initLazily(ServletRequest request) { } lazyServletContext = context; + + logger.info("Initialized (lazily) CORS servlet response filter. allowedOrigin: " + allowedOrigin); } } }