From 30ab82b0c12927799fbd0c369aaa5f3793477b7a Mon Sep 17 00:00:00 2001 From: Frederik Williams Date: Mon, 2 Mar 2020 15:21:24 +0100 Subject: [PATCH] release 3.6.0 --- .gitignore | 2 + SDK/.classpath | 55 + SDK/.project | 23 + .../org.eclipse.core.resources.prefs | 6 + SDK/.settings/org.eclipse.jdt.apt.core.prefs | 2 + SDK/.settings/org.eclipse.jdt.core.prefs | 17 + SDK/.settings/org.eclipse.m2e.core.prefs | 4 + SDK/nbproject/build-impl.xml | 1042 ------ SDK/nbproject/genfiles.properties | 8 - SDK/nbproject/project.properties | 74 - SDK/nbproject/project.xml | 15 - SDK/pom.xml | 51 + SDK/{ => src}/build.xml | 0 .../resources}/hamcrest-core-1.3.jar | Bin .../resources}/javax.servlet-api.jar | Bin .../knownuserv3/sdk/CancelEventConfig.java | 12 +- .../queueit/knownuserv3/sdk/Constants.java | 0 .../queueit/knownuserv3/sdk/KnownUser.java | 233 +- .../knownuserv3/sdk/QueueEventConfig.java | 12 +- .../knownuserv3/sdk/QueueITHelpers.java | 315 ++ .../sdk/RequestValidationResult.java | 15 +- .../knownuserv3/sdk/UserInQueueService.java | 144 +- .../sdk/UserInQueueStateCookieRepository.java | 5 +- .../sdk/integrationconfig/Constants.java | 3 - .../CustomerIntegration.java | 0 .../IntegrationConfigModel.java | 2 +- .../IntegrationEvaluator.java | 63 +- .../sdk/integrationconfig/TriggerModel.java | 0 .../sdk/integrationconfig/TriggerPart.java | 0 SDK/src/main/resources/hamcrest-core-1.3.jar | Bin 0 -> 45024 bytes SDK/src/main/resources/javax.servlet-api.jar | Bin 0 -> 86333 bytes .../knownuserv3/sdk/QueueITHelpers.java | 215 -- .../resources/hamcrest-core-1.3.jar | Bin 0 -> 45024 bytes .../resources/javax.servlet-api.jar | Bin 0 -> 86333 bytes .../knownuserv3/sdk/HashHelperTest.java | 22 + .../knownuserv3/sdk/KnownUserTest.java | 2891 +++++++++++++++++ .../sdk/UrlParameterProviderTest.java | 27 +- .../sdk/UserInQueueServiceTest.java | 377 ++- .../UserInQueueStateCookieRepositoryTest.java | 37 +- .../ComparisonOperatorHelperTest.java | 24 - .../CookieValidatorHelperTest.java | 0 .../HttpHeaderHelperTest.java | 0 .../IntegrationEvaluatorTest.java | 0 .../UrlValidatorHelperTest.java | 0 .../UserAgentValidatorHelperTest.java | 0 .../sdk/resources/hamcrest-core-1.3.jar | Bin 0 -> 45024 bytes .../sdk/resources/javax.servlet-api.jar | Bin 0 -> 86333 bytes SDK/src/test/resources/hamcrest-core-1.3.jar | Bin 0 -> 45024 bytes SDK/src/test/resources/javax.servlet-api.jar | Bin 0 -> 86333 bytes .../knownuserv3/sdk/HashHelperTest.java | 15 - .../knownuserv3/sdk/KnownUserTest.java | 1795 ---------- 51 files changed, 3932 insertions(+), 3574 deletions(-) create mode 100644 SDK/.classpath create mode 100644 SDK/.project create mode 100644 SDK/.settings/org.eclipse.core.resources.prefs create mode 100644 SDK/.settings/org.eclipse.jdt.apt.core.prefs create mode 100644 SDK/.settings/org.eclipse.jdt.core.prefs create mode 100644 SDK/.settings/org.eclipse.m2e.core.prefs delete mode 100644 SDK/nbproject/build-impl.xml delete mode 100644 SDK/nbproject/genfiles.properties delete mode 100644 SDK/nbproject/project.properties delete mode 100644 SDK/nbproject/project.xml create mode 100644 SDK/pom.xml rename SDK/{ => src}/build.xml (100%) rename SDK/{libs => src/main/java/queueit/knownuserv3/resources}/hamcrest-core-1.3.jar (100%) rename SDK/{libs => src/main/java/queueit/knownuserv3/resources}/javax.servlet-api.jar (100%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/CancelEventConfig.java (77%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/Constants.java (100%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/KnownUser.java (62%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/QueueEventConfig.java (87%) create mode 100644 SDK/src/main/java/queueit/knownuserv3/sdk/QueueITHelpers.java rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/RequestValidationResult.java (76%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/UserInQueueService.java (52%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java (98%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/Constants.java (84%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/CustomerIntegration.java (100%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java (91%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java (79%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/TriggerModel.java (100%) rename SDK/src/{ => main/java}/queueit/knownuserv3/sdk/integrationconfig/TriggerPart.java (100%) create mode 100644 SDK/src/main/resources/hamcrest-core-1.3.jar create mode 100644 SDK/src/main/resources/javax.servlet-api.jar delete mode 100644 SDK/src/queueit/knownuserv3/sdk/QueueITHelpers.java create mode 100644 SDK/src/test/java/queueit/knownuserv3/resources/hamcrest-core-1.3.jar create mode 100644 SDK/src/test/java/queueit/knownuserv3/resources/javax.servlet-api.jar create mode 100644 SDK/src/test/java/queueit/knownuserv3/sdk/HashHelperTest.java create mode 100644 SDK/src/test/java/queueit/knownuserv3/sdk/KnownUserTest.java rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/UrlParameterProviderTest.java (53%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/UserInQueueServiceTest.java (65%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java (94%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java (67%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/CookieValidatorHelperTest.java (100%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/HttpHeaderHelperTest.java (100%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluatorTest.java (100%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/UrlValidatorHelperTest.java (100%) rename SDK/{test => src/test/java}/queueit/knownuserv3/sdk/integrationconfig/UserAgentValidatorHelperTest.java (100%) create mode 100644 SDK/src/test/java/queueit/knownuserv3/sdk/resources/hamcrest-core-1.3.jar create mode 100644 SDK/src/test/java/queueit/knownuserv3/sdk/resources/javax.servlet-api.jar create mode 100644 SDK/src/test/resources/hamcrest-core-1.3.jar create mode 100644 SDK/src/test/resources/javax.servlet-api.jar delete mode 100644 SDK/test/queueit/knownuserv3/sdk/HashHelperTest.java delete mode 100644 SDK/test/queueit/knownuserv3/sdk/KnownUserTest.java diff --git a/.gitignore b/.gitignore index 7b00f01..817c2c3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ /SDK/nbproject/private /SDK/build /SDK/dist +/.vs +/SDK/target diff --git a/SDK/.classpath b/SDK/.classpath new file mode 100644 index 0000000..0ca1374 --- /dev/null +++ b/SDK/.classpath @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SDK/.project b/SDK/.project new file mode 100644 index 0000000..eb1a254 --- /dev/null +++ b/SDK/.project @@ -0,0 +1,23 @@ + + + y + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SDK/.settings/org.eclipse.core.resources.prefs b/SDK/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/SDK/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/SDK/.settings/org.eclipse.jdt.apt.core.prefs b/SDK/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..d4313d4 --- /dev/null +++ b/SDK/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/SDK/.settings/org.eclipse.jdt.core.prefs b/SDK/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b5e07ce --- /dev/null +++ b/SDK/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,17 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.processAnnotations=disabled +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SDK/.settings/org.eclipse.m2e.core.prefs b/SDK/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/SDK/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SDK/nbproject/build-impl.xml b/SDK/nbproject/build-impl.xml deleted file mode 100644 index a14899c..0000000 --- a/SDK/nbproject/build-impl.xml +++ /dev/null @@ -1,1042 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - - - - - - java -cp "${run.classpath.with.dist.jar}" ${main.class} - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - - - - - - - - Must select one file in the IDE or set profile.class - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SDK/nbproject/genfiles.properties b/SDK/nbproject/genfiles.properties deleted file mode 100644 index efac672..0000000 --- a/SDK/nbproject/genfiles.properties +++ /dev/null @@ -1,8 +0,0 @@ -build.xml.data.CRC32=4f4bbae4 -build.xml.script.CRC32=edafd639 -build.xml.stylesheet.CRC32=28e38971@1.44.1.45 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=4f4bbae4 -nbproject/build-impl.xml.script.CRC32=6eb04d1d -nbproject/build-impl.xml.stylesheet.CRC32=0ae3a408@1.44.1.45 diff --git a/SDK/nbproject/project.properties b/SDK/nbproject/project.properties deleted file mode 100644 index f7f5cf8..0000000 --- a/SDK/nbproject/project.properties +++ /dev/null @@ -1,74 +0,0 @@ -annotation.processing.enabled=true -annotation.processing.enabled.in.editor=false -annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output -application.title=SDK -application.vendor=queueit -build.classes.dir=${build.dir}/classes -build.classes.excludes=**/*.java,**/*.form -# This directory is removed when the project is cleaned: -build.dir=build -build.generated.dir=${build.dir}/generated -build.generated.sources.dir=${build.dir}/generated-sources -# Only compile against the classpath explicitly listed here: -build.sysclasspath=ignore -build.test.classes.dir=${build.dir}/test/classes -build.test.results.dir=${build.dir}/test/results -# Uncomment to specify the preferred debugger connection transport: -#debug.transport=dt_socket -debug.classpath=\ - ${run.classpath} -debug.test.classpath=\ - ${run.test.classpath} -# This directory is removed when the project is cleaned: -dist.dir=dist -dist.jar=${dist.dir}/SDK.jar -dist.javadoc.dir=${dist.dir}/javadoc -endorsed.classpath= -excludes= -file.reference.javax.servlet-api.jar=libs/javax.servlet-api.jar -includes=** -jar.compress=false -javac.classpath=\ - ${file.reference.javax.servlet-api.jar} -# Space-separated list of extra javac options -javac.compilerargs= -javac.deprecation=false -javac.processorpath=\ - ${javac.classpath} -javac.source=1.6 -javac.target=1.6 -javac.test.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir}:\ - ${libs.junit_4.classpath}:\ - ${libs.hamcrest.classpath} -javac.test.processorpath=\ - ${javac.test.classpath} -javadoc.additionalparam= -javadoc.author=false -javadoc.encoding=${source.encoding} -javadoc.noindex=false -javadoc.nonavbar=false -javadoc.notree=false -javadoc.private=false -javadoc.splitindex=true -javadoc.use=true -javadoc.version=false -javadoc.windowtitle= -meta.inf.dir=${src.dir}/META-INF -mkdist.disabled=true -platform.active=default_platform -run.classpath=\ - ${javac.classpath}:\ - ${build.classes.dir} -# Space-separated list of JVM arguments used when running the project -# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value -# or test-sys-prop.name=value to set system properties for unit tests): -run.jvmargs= -run.test.classpath=\ - ${javac.test.classpath}:\ - ${build.test.classes.dir} -source.encoding=UTF-8 -src.dir=src -test.src.dir=test diff --git a/SDK/nbproject/project.xml b/SDK/nbproject/project.xml deleted file mode 100644 index c79c34b..0000000 --- a/SDK/nbproject/project.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - org.netbeans.modules.java.j2seproject - - - SDK - - - - - - - - - diff --git a/SDK/pom.xml b/SDK/pom.xml new file mode 100644 index 0000000..380df67 --- /dev/null +++ b/SDK/pom.xml @@ -0,0 +1,51 @@ + + + + UTF-8 + + 4.0.0 + + x + y + 1.0 + + + + junit + junit + 4.12 + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.8 + 1.8 + + + + maven-surefire-plugin + 3.0.0-M3 + + 1.8 + 1.8 + + + + + + + \ No newline at end of file diff --git a/SDK/build.xml b/SDK/src/build.xml similarity index 100% rename from SDK/build.xml rename to SDK/src/build.xml diff --git a/SDK/libs/hamcrest-core-1.3.jar b/SDK/src/main/java/queueit/knownuserv3/resources/hamcrest-core-1.3.jar similarity index 100% rename from SDK/libs/hamcrest-core-1.3.jar rename to SDK/src/main/java/queueit/knownuserv3/resources/hamcrest-core-1.3.jar diff --git a/SDK/libs/javax.servlet-api.jar b/SDK/src/main/java/queueit/knownuserv3/resources/javax.servlet-api.jar similarity index 100% rename from SDK/libs/javax.servlet-api.jar rename to SDK/src/main/java/queueit/knownuserv3/resources/javax.servlet-api.jar diff --git a/SDK/src/queueit/knownuserv3/sdk/CancelEventConfig.java b/SDK/src/main/java/queueit/knownuserv3/sdk/CancelEventConfig.java similarity index 77% rename from SDK/src/queueit/knownuserv3/sdk/CancelEventConfig.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/CancelEventConfig.java index fe800e2..fe228c5 100644 --- a/SDK/src/queueit/knownuserv3/sdk/CancelEventConfig.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/CancelEventConfig.java @@ -6,6 +6,7 @@ public class CancelEventConfig { private String queueDomain; private String cookieDomain; private int version; + private String actionName = "unspecified"; public String getEventId() { return eventId; @@ -15,6 +16,10 @@ public void setEventId(String eventId) { this.eventId = eventId; } + public void setActionName(String actionName) { + this.actionName = actionName; + } + public String getQueueDomain() { return queueDomain; } @@ -42,12 +47,17 @@ public void setVersion(int version) { public CancelEventConfig() { this.version = -1; } + + public String getActionName() { + return actionName; + } @Override public String toString() { return "EventId:" + eventId + "&Version:" + version + "&QueueDomain:" + queueDomain - + "&CookieDomain:" + cookieDomain; + + "&CookieDomain:" + cookieDomain + + "&ActionName:" + actionName; } } diff --git a/SDK/src/queueit/knownuserv3/sdk/Constants.java b/SDK/src/main/java/queueit/knownuserv3/sdk/Constants.java similarity index 100% rename from SDK/src/queueit/knownuserv3/sdk/Constants.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/Constants.java diff --git a/SDK/src/queueit/knownuserv3/sdk/KnownUser.java b/SDK/src/main/java/queueit/knownuserv3/sdk/KnownUser.java similarity index 62% rename from SDK/src/queueit/knownuserv3/sdk/KnownUser.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/KnownUser.java index 3ced801..9c6e13a 100644 --- a/SDK/src/queueit/knownuserv3/sdk/KnownUser.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/KnownUser.java @@ -22,10 +22,10 @@ public class KnownUser { private static IUserInQueueService _userInQueueService; private static IUserInQueueService getUserInQueueService(HttpServletRequest request, HttpServletResponse response) { + if (_userInQueueService == null) { return new UserInQueueService(new UserInQueueStateCookieRepository(new CookieManager(request, response))); } - return _userInQueueService; } @@ -37,85 +37,118 @@ static void setUserInQueueService(IUserInQueueService mockUserInQueueService) { } public static RequestValidationResult validateRequestByIntegrationConfig(String currentUrlWithoutQueueITToken, - String queueitToken, CustomerIntegration customerIntegrationInfo, - String customerId, HttpServletRequest request, - HttpServletResponse response, String secretKey) throws Exception { + String queueitToken, CustomerIntegration customerIntegrationInfo, String customerId, + HttpServletRequest request, HttpServletResponse response, String secretKey) throws Exception { + + Map debugEntries = new HashMap(); - Map debugEntries = new HashMap(); + ConnectorDiagnostics connectorDiagnostics = ConnectorDiagnostics.Verify(customerId, secretKey, queueitToken); + + if (connectorDiagnostics.hasError) { + return connectorDiagnostics.validationResult; + } try { - boolean isDebug = getIsDebug(queueitToken, secretKey); - if (isDebug) { - debugEntries.put("ConfigVersion", Integer.toString(customerIntegrationInfo.Version)); + if (connectorDiagnostics.isEnabled) { + debugEntries.put("SdkVersion", UserInQueueService.SDK_VERSION); + debugEntries.put("Runtime", GetRuntime()); + String conVer = (customerIntegrationInfo != null) ? Integer.toString(customerIntegrationInfo.Version) : "NULL"; + debugEntries.put("ConfigVersion", conVer); debugEntries.put("PureUrl", currentUrlWithoutQueueITToken); debugEntries.put("QueueitToken", queueitToken); debugEntries.put("OriginalUrl", getOriginalUrl(request)); + logMoreRequestDetails(debugEntries, request); } if (Utils.isNullOrWhiteSpace(currentUrlWithoutQueueITToken)) { throw new Exception("currentUrlWithoutQueueITToken can not be null or empty."); } + if (customerIntegrationInfo == null) { throw new KnowUserException("customerIntegrationInfo can not be null."); } - Cookie[] cookies = request != null ? request.getCookies() : new Cookie[0]; - IntegrationEvaluator configEvaluater = new IntegrationEvaluator(); - IntegrationConfigModel matchedConfig = configEvaluater.getMatchedIntegrationConfig( - customerIntegrationInfo, currentUrlWithoutQueueITToken, request); + IntegrationConfigModel matchedConfig = configEvaluater.getMatchedIntegrationConfig(customerIntegrationInfo, + currentUrlWithoutQueueITToken, request); - if (isDebug) { - String matchedConfigName = (matchedConfig != null) ? matchedConfig.Name : "NULL"; - debugEntries.put("MatchedConfig", matchedConfigName); + if (connectorDiagnostics.isEnabled) { + String matchedConf = (matchedConfig != null) ? matchedConfig.Name : "NULL"; + debugEntries.put("MatchedConfig", matchedConf); } if (matchedConfig == null) { - return new RequestValidationResult(null, null, null, null, null); + return new RequestValidationResult(null, null, null, null, null, null); } // unspecified or 'Queue' specified - if (Utils.isNullOrWhiteSpace(matchedConfig.ActionType) || ActionType.QUEUE_ACTION.equals(matchedConfig.ActionType)) { - return handleQueueAction(matchedConfig, currentUrlWithoutQueueITToken, customerIntegrationInfo, queueitToken, customerId, request, response, secretKey, debugEntries); + if (Utils.isNullOrWhiteSpace(matchedConfig.ActionType) + || ActionType.QUEUE_ACTION.equals(matchedConfig.ActionType)) { + return handleQueueAction(matchedConfig, currentUrlWithoutQueueITToken, customerIntegrationInfo, + queueitToken, customerId, request, response, secretKey, debugEntries, connectorDiagnostics.isEnabled); + } else if (ActionType.CANCEL_ACTION.equals(matchedConfig.ActionType)) { - return handleCancelAction(matchedConfig, customerIntegrationInfo, currentUrlWithoutQueueITToken, queueitToken, customerId, request, response, secretKey, debugEntries); - } // for all unknown types default to 'Ignore' + return handleCancelAction(matchedConfig, customerIntegrationInfo, currentUrlWithoutQueueITToken, + queueitToken, customerId, request, response, secretKey, debugEntries, connectorDiagnostics.isEnabled); + } + + // for all unknown types default to 'Ignore' else { - return handleIgnoreAction(request, response); + return handleIgnoreAction(request, response, matchedConfig.Name); } - } finally { + } + catch (Exception e) { + if (connectorDiagnostics.isEnabled) { + debugEntries.put("Exception", e.getMessage()); + } + throw e; + } + finally { setDebugCookie(debugEntries, request, response); } } - public static RequestValidationResult cancelRequestByLocalConfig( - String targetUrl, String queueitToken, CancelEventConfig cancelConfig, - String customerId, HttpServletRequest request, - HttpServletResponse response, String secretKey) throws Exception { + public static RequestValidationResult cancelRequestByLocalConfig(String targetUrl, String queueitToken, + CancelEventConfig cancelConfig, String customerId, HttpServletRequest request, HttpServletResponse response, + String secretKey) throws Exception { + + Map debugEntries = new HashMap(); - Map debugEntries = new HashMap(); + ConnectorDiagnostics connectorDiagnostics = ConnectorDiagnostics.Verify(customerId, secretKey, queueitToken); + + if (connectorDiagnostics.hasError) { + return connectorDiagnostics.validationResult; + } try { - targetUrl = generateTargetUrl(targetUrl, request); - return cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, request, response, secretKey, debugEntries); - } finally { + return cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, request, response, + secretKey, debugEntries, connectorDiagnostics.isEnabled); + } + catch (Exception e) { + if(connectorDiagnostics.isEnabled) { + debugEntries.put("Exception", e.getMessage()); + } + throw e; + } + finally { setDebugCookie(debugEntries, request, response); } } - private static RequestValidationResult cancelRequestByLocalConfig( - String targetUrl, String queueitToken, CancelEventConfig cancelConfig, - String customerId, HttpServletRequest request, - HttpServletResponse response, String secretKey, - Map debugEntries) throws Exception { + private static RequestValidationResult cancelRequestByLocalConfig(String targetUrl, String queueitToken, + CancelEventConfig cancelConfig, String customerId, HttpServletRequest request, HttpServletResponse response, + String secretKey, Map debugEntries, boolean isDebug) throws Exception { + + targetUrl = generateTargetUrl(targetUrl, request); - boolean isDebug = getIsDebug(queueitToken, secretKey); if (isDebug) { + debugEntries.put("SdkVersion", UserInQueueService.SDK_VERSION); + debugEntries.put("Runtime", GetRuntime()); debugEntries.put("TargetUrl", targetUrl); debugEntries.put("QueueitToken", queueitToken); - debugEntries.put("CancelConfig", cancelConfig != null ? cancelConfig.toString() : "NULL"); + debugEntries.put("CancelConfig", (cancelConfig != null) ? cancelConfig.toString() : "NULL"); debugEntries.put("OriginalUrl", getOriginalUrl(request)); logMoreRequestDetails(debugEntries, request); } @@ -140,39 +173,55 @@ private static RequestValidationResult cancelRequestByLocalConfig( } IUserInQueueService userInQueueService = getUserInQueueService(request, response); - RequestValidationResult result = userInQueueService.validateCancelRequest(targetUrl, cancelConfig, customerId, secretKey); + RequestValidationResult result = userInQueueService.validateCancelRequest(targetUrl, cancelConfig, customerId, + secretKey); result.isAjaxResult = isQueueAjaxCall(request); return result; } public static RequestValidationResult resolveQueueRequestByLocalConfig( - String targetUrl, String queueitToken, QueueEventConfig queueConfig, - String customerId, HttpServletRequest request, - HttpServletResponse response, String secretKey) throws Exception { + String targetUrl, String queueitToken, + QueueEventConfig queueConfig, String customerId, HttpServletRequest request, HttpServletResponse response, + String secretKey) throws Exception { + + ConnectorDiagnostics connectorDiagnostics = ConnectorDiagnostics.Verify(customerId, secretKey, queueitToken); + + if (connectorDiagnostics.hasError) { + return connectorDiagnostics.validationResult; + } - Map debugEntries = new HashMap(); + Map debugEntries = new HashMap(); try { targetUrl = generateTargetUrl(targetUrl, request); - return resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, request, response, secretKey, debugEntries); - } finally { + + return resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, request, response, + secretKey, debugEntries, connectorDiagnostics.isEnabled); + } + catch (Exception e) { + if(connectorDiagnostics.isEnabled) { + debugEntries.put("Exception", e.getMessage()); + } + throw e; + } + finally { setDebugCookie(debugEntries, request, response); } } - private static RequestValidationResult resolveQueueRequestByLocalConfig( - String targetUrl, String queueitToken, QueueEventConfig queueConfig, - String customerId, HttpServletRequest request, - HttpServletResponse response, String secretKey, - Map debugEntries) throws Exception { + private static RequestValidationResult resolveQueueRequestByLocalConfig(String targetUrl, String queueitToken, + QueueEventConfig queueConfig, String customerId, HttpServletRequest request, HttpServletResponse response, + String secretKey, Map debugEntries, boolean isDebug) throws Exception { - boolean isDebug = getIsDebug(queueitToken, secretKey); if (isDebug) { + debugEntries.put("SdkVersion", UserInQueueService.SDK_VERSION); + debugEntries.put("Runtime", GetRuntime()); debugEntries.put("TargetUrl", targetUrl); debugEntries.put("QueueitToken", queueitToken); - debugEntries.put("QueueConfig", queueConfig != null ? queueConfig.toString() : "NULL"); + debugEntries.put("QueueConfig", (queueConfig != null) ? queueConfig.toString() : "NULL"); debugEntries.put("OriginalUrl", getOriginalUrl(request)); + logMoreRequestDetails(debugEntries, request); } @@ -199,18 +248,15 @@ private static RequestValidationResult resolveQueueRequestByLocalConfig( } IUserInQueueService userInQueueService = getUserInQueueService(request, response); - RequestValidationResult result = userInQueueService.validateQueueRequest(targetUrl, queueitToken, queueConfig, customerId, secretKey); + RequestValidationResult result = userInQueueService.validateQueueRequest(targetUrl, queueitToken, queueConfig, + customerId, secretKey); result.isAjaxResult = isQueueAjaxCall(request); return result; } - public static void extendQueueCookie(String eventId, - int cookieValidityMinute, - String cookieDomain, - HttpServletRequest request, - HttpServletResponse response, - String secretKey) throws Exception { + public static void extendQueueCookie(String eventId, int cookieValidityMinute, String cookieDomain, + HttpServletRequest request, HttpServletResponse response, String secretKey) throws Exception { if (Utils.isNullOrWhiteSpace(eventId)) { throw new Exception("eventId can not be null or empty."); @@ -226,7 +272,9 @@ public static void extendQueueCookie(String eventId, userInQueueService.extendQueueCookie(eventId, cookieValidityMinute, cookieDomain, secretKey); } - private static void setDebugCookie(Map debugEntries, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException { + private static void setDebugCookie(Map debugEntries, HttpServletRequest request, + HttpServletResponse response) throws UnsupportedEncodingException { + if (debugEntries.isEmpty()) { return; } @@ -243,36 +291,35 @@ private static void setDebugCookie(Map debugEntries, HttpServlet } private static void logMoreRequestDetails(Map debugEntries, HttpServletRequest request) { + TimeZone tz = TimeZone.getTimeZone("UTC"); - DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); // Quoted "Z" to indicate UTC, no timezone offset + // Quoted "Z" to indicate UTC, no timezone offset + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); df.setTimeZone(tz); String nowAsISO = df.format(new Date()); debugEntries.put("ServerUtcTime", nowAsISO); debugEntries.put("RequestIP", request.getRemoteAddr()); debugEntries.put("RequestHttpHeader_Via", request.getHeader("via") != null ? request.getHeader("via") : ""); - debugEntries.put("RequestHttpHeader_Forwarded", request.getHeader("forwarded") != null ? request.getHeader("forwarded") : ""); - debugEntries.put("RequestHttpHeader_XForwardedFor", request.getHeader("x-forwarded-for") != null ? request.getHeader("x-forwarded-for") : ""); - debugEntries.put("RequestHttpHeader_XForwardedHost", request.getHeader("x-forwarded-host") != null ? request.getHeader("x-forwarded-host") : ""); - debugEntries.put("RequestHttpHeader_XForwardedProto", request.getHeader("x-forwarded-proto") != null ? request.getHeader("x-forwarded-proto") : ""); - } - - private static boolean getIsDebug(String queueitToken, String secretKey) throws Exception { - QueueUrlParams qParams = QueueParameterHelper.extractQueueParams(queueitToken); - if (qParams != null && qParams.getRedirectType() != null && "debug".equals(qParams.getRedirectType().toLowerCase())) { - String hash = HashHelper.generateSHA256Hash(secretKey, qParams.getQueueITTokenWithoutHash()); - return qParams.getHashCode().equals(hash); - } - return false; + debugEntries.put("RequestHttpHeader_Forwarded", + request.getHeader("forwarded") != null ? request.getHeader("forwarded") : ""); + debugEntries.put("RequestHttpHeader_XForwardedFor", + request.getHeader("x-forwarded-for") != null ? request.getHeader("x-forwarded-for") : ""); + debugEntries.put("RequestHttpHeader_XForwardedHost", + request.getHeader("x-forwarded-host") != null ? request.getHeader("x-forwarded-host") : ""); + debugEntries.put("RequestHttpHeader_XForwardedProto", + request.getHeader("x-forwarded-proto") != null ? request.getHeader("x-forwarded-proto") : ""); } private static String getOriginalUrl(HttpServletRequest request) { - return (request.getQueryString() != null) - ? request.getRequestURL().toString() + "?" + request.getQueryString() + return (request.getQueryString() != null) ? request.getRequestURL().toString() + "?" + request.getQueryString() : request.getRequestURL().toString(); } - private static RequestValidationResult handleQueueAction(IntegrationConfigModel matchedConfig, String currentUrlWithoutQueueITToken, CustomerIntegration customerIntegrationInfo, String queueitToken, String customerId, HttpServletRequest request, HttpServletResponse response, String secretKey, Map debugEntries) throws Exception { + private static RequestValidationResult handleQueueAction(IntegrationConfigModel matchedConfig, + String currentUrlWithoutQueueITToken, CustomerIntegration customerIntegrationInfo, String queueitToken, + String customerId, HttpServletRequest request, HttpServletResponse response, String secretKey, + Map debugEntries, boolean isDebug) throws Exception { String targetUrl; if ("ForecedTargetUrl".equals(matchedConfig.RedirectLogic) || // support for typo @@ -293,32 +340,42 @@ private static RequestValidationResult handleQueueAction(IntegrationConfigModel queueConfig.setCookieValidityMinute(matchedConfig.CookieValidityMinute); queueConfig.setCookieDomain(matchedConfig.CookieDomain); queueConfig.setVersion(customerIntegrationInfo.Version); + queueConfig.setActionName(matchedConfig.Name); - return resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, request, response, secretKey, debugEntries); + return resolveQueueRequestByLocalConfig(targetUrl, queueitToken, queueConfig, customerId, request, response, + secretKey, debugEntries, isDebug); } - private static RequestValidationResult handleCancelAction(IntegrationConfigModel matchedConfig, CustomerIntegration customerIntegrationInfo, String currentUrlWithoutQueueITToken, String queueitToken, String customerId, HttpServletRequest request, HttpServletResponse response, String secretKey, Map debugEntries) throws Exception { + private static RequestValidationResult handleCancelAction(IntegrationConfigModel matchedConfig, + CustomerIntegration customerIntegrationInfo, String currentUrlWithoutQueueITToken, String queueitToken, + String customerId, HttpServletRequest request, HttpServletResponse response, String secretKey, + Map debugEntries, boolean isDebug) throws Exception { + CancelEventConfig cancelConfig = new CancelEventConfig(); cancelConfig.setQueueDomain(matchedConfig.QueueDomain); cancelConfig.setEventId(matchedConfig.EventId); cancelConfig.setCookieDomain(matchedConfig.CookieDomain); cancelConfig.setVersion(customerIntegrationInfo.Version); + cancelConfig.setActionName(matchedConfig.Name); String targetUrl = generateTargetUrl(currentUrlWithoutQueueITToken, request); - return cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, request, response, secretKey, debugEntries); + + return cancelRequestByLocalConfig(targetUrl, queueitToken, cancelConfig, customerId, request, response, + secretKey, debugEntries, isDebug); } - private static RequestValidationResult handleIgnoreAction(HttpServletRequest request, HttpServletResponse response) { + private static RequestValidationResult handleIgnoreAction(HttpServletRequest request, HttpServletResponse response, + String actionName) { + IUserInQueueService userInQueueService = getUserInQueueService(request, response); - RequestValidationResult result = userInQueueService.getIgnoreActionResult(); + RequestValidationResult result = userInQueueService.getIgnoreActionResult(actionName); result.isAjaxResult = isQueueAjaxCall(request); return result; } private static String generateTargetUrl(String originalTargetUrl, HttpServletRequest request) { try { - return !isQueueAjaxCall(request) - ? originalTargetUrl + return !isQueueAjaxCall(request) ? originalTargetUrl : URLDecoder.decode(request.getHeader(QueueITAjaxHeaderKey), "UTF-8"); } catch (UnsupportedEncodingException e) { } @@ -328,6 +385,14 @@ private static String generateTargetUrl(String originalTargetUrl, HttpServletReq private static boolean isQueueAjaxCall(HttpServletRequest request) { return !Utils.isNullOrWhiteSpace(request.getHeader(QueueITAjaxHeaderKey)); } + + public static String GetRuntime() { + try { + return System.getProperty("java.runtime.version"); + } catch (Exception ex) { + return "unknown"; + } + } } interface ICookieManager { @@ -387,7 +452,7 @@ public String getCookie(String cookieName) { if (cookie.getName().equals(cookieName)) { try { return URLDecoder.decode(cookie.getValue(), "UTF-8"); - } catch (UnsupportedEncodingException ex) { + } catch (Exception ex) { } } } diff --git a/SDK/src/queueit/knownuserv3/sdk/QueueEventConfig.java b/SDK/src/main/java/queueit/knownuserv3/sdk/QueueEventConfig.java similarity index 87% rename from SDK/src/queueit/knownuserv3/sdk/QueueEventConfig.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/QueueEventConfig.java index c970173..b06935d 100644 --- a/SDK/src/queueit/knownuserv3/sdk/QueueEventConfig.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/QueueEventConfig.java @@ -10,6 +10,7 @@ public class QueueEventConfig { private int cookieValidityMinute; private String cookieDomain; private int version; + private String actionName = "unspecified"; public String getEventId() { return eventId; @@ -19,6 +20,10 @@ public void setEventId(String eventId) { this.eventId = eventId; } + public void setActionName(String actionName) { + this.actionName = actionName; + } + public String getLayoutName() { return layoutName; } @@ -78,6 +83,10 @@ public void setVersion(int version) { public QueueEventConfig() { this.version = -1; } + + public String getActionName() { + return actionName; + } @Override public String toString() { @@ -88,6 +97,7 @@ public String toString() { + "&ExtendCookieValidity:" + extendCookieValidity + "&CookieValidityMinute:" + cookieValidityMinute + "&LayoutName:" + layoutName - + "&Culture:" + culture; + + "&Culture:" + culture + + "&ActionName:" + actionName; } } diff --git a/SDK/src/main/java/queueit/knownuserv3/sdk/QueueITHelpers.java b/SDK/src/main/java/queueit/knownuserv3/sdk/QueueITHelpers.java new file mode 100644 index 0000000..e8d7dc6 --- /dev/null +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/QueueITHelpers.java @@ -0,0 +1,315 @@ +package queueit.knownuserv3.sdk; + +import java.util.AbstractCollection; +import java.util.Iterator; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.lang.Exception; +import java.net.URLEncoder; + +class Utils { + + public static boolean isNullOrWhiteSpace(String str) { + return str == null || str.trim().length() == 0; + } + + public static boolean isInteger(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static boolean isLong(String value) { + try { + Long.parseLong(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + public static String join(String delimiter, AbstractCollection s) { + if (s == null || s.isEmpty()) { + return ""; + } + Iterator iter = s.iterator(); + StringBuilder builder = new StringBuilder(iter.next()); + while (iter.hasNext()) { + builder.append(delimiter).append(iter.next()); + } + return builder.toString(); + } + + public static String encodeUrl(String arg) { + try { + String value = URLEncoder.encode(arg, "UTF-8").replaceAll("\\+", "%20").replaceAll("&", "\\%26") + .replaceAll("!", "\\%21").replaceAll("'", "\\%27").replaceAll("\\(", "\\%28") + .replaceAll("~", "\\%7E").replaceAll("\\|", "\\%7C").replaceAll("\\)", "\\%29") + .replaceAll("\\*", "\\%2A"); + return value; + } catch (Exception e) { + return arg; + } + } +} + +class ConnectorDiagnostics { + public boolean isEnabled; + public boolean hasError; + public RequestValidationResult validationResult; + + public boolean getIsEnabled() { + return this.isEnabled; + } + + public void setIsEnabled(boolean isEnabled) { + this.isEnabled = isEnabled; + } + + public boolean getHasError() { + return this.hasError; + } + + public void setHasError(boolean hasError) { + this.hasError = hasError; + } + + public RequestValidationResult getValidationResult() { + return this.validationResult; + } + + public void setValidationResult(RequestValidationResult validationResult) { + this.validationResult = validationResult; + } + + private void SetStateWithTokenError(String customerId, String errorCode) { + hasError = true; + String redirectUrl = "https://" + customerId + ".api2.queue-it.net/" + customerId + + "/diagnostics/connector/error/?code=" + errorCode; + + validationResult = new RequestValidationResult("ConnectorDiagnosticsRedirect", null, null, redirectUrl, null, + null); + } + + private void SetStateWithSetupError() { + hasError = true; + validationResult = new RequestValidationResult("ConnectorDiagnosticsRedirect", null, null, + "https://api2.queue-it.net/diagnostics/connector/error/?code=setup", null, null); + } + + public static ConnectorDiagnostics Verify(String customerId, String secretKey, String queueitToken){ + + ConnectorDiagnostics diagnostics = new ConnectorDiagnostics(); + + QueueUrlParams qParams = QueueParameterHelper.extractQueueParams(queueitToken); + + if (qParams == null) { + return diagnostics; + } + + if (qParams.getRedirectType() == null) { + return diagnostics; + } + + if (!"debug".equals(qParams.getRedirectType())) { + return diagnostics; + } + + if (Utils.isNullOrWhiteSpace(customerId) || Utils.isNullOrWhiteSpace(secretKey)) { + diagnostics.SetStateWithSetupError(); + return diagnostics; + } + + String calculatedHash = HashHelper.generateSHA256Hash(secretKey, qParams.getQueueITTokenWithoutHash()); + + if (!calculatedHash.toUpperCase().equals(qParams.getHashCode().toUpperCase())) { + diagnostics.SetStateWithTokenError(customerId, "hash"); + return diagnostics; + } + + if (qParams.getTimeStamp() < System.currentTimeMillis() / 1000L) { + diagnostics.SetStateWithTokenError(customerId, "timestamp"); + return diagnostics; + } + + diagnostics.isEnabled = true; + + return diagnostics; + } +} + +class QueueParameterHelper { + + public static final String TimeStampKey = "ts"; + public static final String ExtendableCookieKey = "ce"; + public static final String CookieValidityMinutesKey = "cv"; + public static final String HashKey = "h"; + public static final String QueueIdKey = "q"; + public static final String RedirectTypeKey = "rt"; + public static final String EventIdKey = "e"; + public static final String KeyValueSeparatorChar = "_"; + public static final String KeyValueSeparatorGroupChar = "~"; + + public static QueueUrlParams extractQueueParams(String queueitToken) { + + if (Utils.isNullOrWhiteSpace(queueitToken)) { + return null; + } + QueueUrlParams result = new QueueUrlParams(); + result.setQueueITToken(queueitToken); + + String[] paramList = queueitToken.split(KeyValueSeparatorGroupChar); + for (String paramKeyValue : paramList) { + String[] keyValueArr = paramKeyValue.split(KeyValueSeparatorChar); + + if (keyValueArr.length != 2) + continue; + + if (HashKey.equals(keyValueArr[0])) { + result.setHashCode(keyValueArr[1]); + } else if (TimeStampKey.equals(keyValueArr[0])) { + if (Utils.isLong(keyValueArr[1])) { + result.setTimeStamp(Long.parseLong(keyValueArr[1])); + } + } else if (CookieValidityMinutesKey.equals(keyValueArr[0])) { + if (Utils.isInteger(keyValueArr[1])) { + result.setCookieValidityMinutes(Integer.parseInt(keyValueArr[1])); + } + } else if (EventIdKey.equals(keyValueArr[0])) { + result.setEventId(keyValueArr[1]); + } else if (QueueIdKey.equals(keyValueArr[0])) { + result.setQueueId(keyValueArr[1]); + } else if (ExtendableCookieKey.equals(keyValueArr[0])) { + result.setExtendableCookie(Boolean.parseBoolean(keyValueArr[1])); + } else if (RedirectTypeKey.equals(keyValueArr[0])) { + result.setRedirectType(keyValueArr[1]); + } + } + String queueITTokenWithoutHash = result.getQueueITToken() + .replace(KeyValueSeparatorGroupChar + HashKey + KeyValueSeparatorChar + result.getHashCode(), ""); + result.setQueueITTokenWithoutHash(queueITTokenWithoutHash); + return result; + } +} + +class HashHelper { + + public static String generateSHA256Hash(String secretKey, String stringToHash) { + try { + byte[] secretKeyBytes = secretKey.getBytes("UTF-8"); + SecretKeySpec signingKey = new SecretKeySpec(secretKeyBytes, "HmacSHA256"); + Mac mac = Mac.getInstance("HmacSHA256"); + mac.init(signingKey); + byte[] bytes = stringToHash.getBytes("UTF-8"); + byte[] rawHmac = mac.doFinal(bytes); + StringBuilder sb = new StringBuilder(); + for (byte b : rawHmac) { + sb.append(String.format("%1$02x", b)); + } + + return sb.toString(); + } + catch (Exception e) { + return ""; + } + } +} + +class QueueUrlParams { + + private String eventId; + private String hashCode; + private boolean extendableCookie; + private String queueITToken; + private String queueITTokenWithoutHash; + private Integer cookieValidityMinutes; + private long timeStamp; + private String queueId; + private String redirectType; + + public QueueUrlParams() { + this.eventId = ""; + this.hashCode = ""; + this.extendableCookie = false; + this.queueITToken = ""; + this.queueITTokenWithoutHash = ""; + this.cookieValidityMinutes = null; + this.timeStamp = 0; + this.queueId = ""; + } + + public String getEventId() { + return this.eventId; + } + + public void setEventId(String eventId) { + this.eventId = eventId; + } + + public String getHashCode() { + return this.hashCode; + } + + public void setHashCode(String hashCode) { + this.hashCode = hashCode; + } + + public boolean getExtendableCookie() { + return this.extendableCookie; + } + + public void setExtendableCookie(boolean extendableCookie) { + this.extendableCookie = extendableCookie; + } + + public Integer getCookieValidityMinutes() { + return this.cookieValidityMinutes; + } + + public void setCookieValidityMinutes(Integer cookieValidityMinute) { + this.cookieValidityMinutes = cookieValidityMinute; + } + + public String getQueueITToken() { + return this.queueITToken; + } + + public void setQueueITToken(String queueITToken) { + this.queueITToken = queueITToken; + } + + public String getQueueITTokenWithoutHash() { + return this.queueITTokenWithoutHash; + } + + public void setQueueITTokenWithoutHash(String queueITTokenWithoutHash) { + this.queueITTokenWithoutHash = queueITTokenWithoutHash; + } + + public long getTimeStamp() { + return this.timeStamp; + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + public void setQueueId(String queueId) { + this.queueId = queueId; + } + + public String getQueueId() { + return this.queueId; + } + + public void setRedirectType(String redirectType) { + this.redirectType = redirectType; + } + + public String getRedirectType() { + return this.redirectType; + } +} diff --git a/SDK/src/queueit/knownuserv3/sdk/RequestValidationResult.java b/SDK/src/main/java/queueit/knownuserv3/sdk/RequestValidationResult.java similarity index 76% rename from SDK/src/queueit/knownuserv3/sdk/RequestValidationResult.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/RequestValidationResult.java index 4fdba52..cf306ca 100644 --- a/SDK/src/queueit/knownuserv3/sdk/RequestValidationResult.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/RequestValidationResult.java @@ -10,14 +10,16 @@ public class RequestValidationResult { private String redirectUrl; private String queueId; private String redirectType; - public boolean isAjaxResult; + private String actionName; + public boolean isAjaxResult; - public RequestValidationResult(String actionType, String eventId, String queueId, String redirectUrl, String redirectType) { + public RequestValidationResult(String actionType, String eventId, String queueId, String redirectUrl, String redirectType, String actionName) { this.actionType = actionType; this.eventId = eventId; this.queueId = queueId; this.redirectUrl = redirectUrl; this.redirectType = redirectType; + this.actionName = actionName; } public String getActionType() { @@ -57,11 +59,18 @@ public String getAjaxRedirectUrl() { } return ""; } + public String getActionName() { + return this.actionName; + } } class KnowUserException extends Exception { + /** + * The serializable class KnowUserException does not declare a static final serialVersionUID field of type long + */ + private static final long serialVersionUID = 1L; - public KnowUserException(String message) { + public KnowUserException(String message) { super(message); } diff --git a/SDK/src/queueit/knownuserv3/sdk/UserInQueueService.java b/SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueService.java similarity index 52% rename from SDK/src/queueit/knownuserv3/sdk/UserInQueueService.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueService.java index 8609bfc..6fc1d82 100644 --- a/SDK/src/queueit/knownuserv3/sdk/UserInQueueService.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueService.java @@ -1,6 +1,4 @@ package queueit.knownuserv3.sdk; - -import java.net.URLEncoder; import java.util.ArrayList; interface IUserInQueueService { @@ -24,13 +22,13 @@ void extendQueueCookie( String cookieDomain, String secretKey); - RequestValidationResult getIgnoreActionResult(); + RequestValidationResult getIgnoreActionResult(String actionName); } class UserInQueueService implements IUserInQueueService { - public static final String SDK_VERSION = "3.5.2"; - private final IUserInQueueStateRepository _userInQueueStateRepository; + public static final String SDK_VERSION = "v3-java-" + "3.6.0"; + public final IUserInQueueStateRepository _userInQueueStateRepository; public UserInQueueService(IUserInQueueStateRepository queueStateRepository) { this._userInQueueStateRepository = queueStateRepository; @@ -43,7 +41,8 @@ public RequestValidationResult validateQueueRequest( QueueEventConfig config, String customerId, String secretKey) throws Exception { - StateInfo stateInfo = this._userInQueueStateRepository.getState(config.getEventId(), config.getCookieValidityMinute(), secretKey, true); + StateInfo stateInfo = this._userInQueueStateRepository.getState(config.getEventId(), config.getCookieValidityMinute(), secretKey, true); + if (stateInfo.isValid()) { if (stateInfo.isStateExtendable() && config.getExtendCookieValidity()) { this._userInQueueStateRepository.store( @@ -54,36 +53,35 @@ public RequestValidationResult validateQueueRequest( stateInfo.getRedirectType(), secretKey); } - return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), stateInfo.getQueueId(), null, stateInfo.getRedirectType()); - } - + return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), stateInfo.getQueueId(), null, stateInfo.getRedirectType(), config.getActionName()); + } QueueUrlParams queueParmas = QueueParameterHelper.extractQueueParams(queueitToken); if (queueParmas != null) { - return getQueueITTokenValidationResult(targetUrl, config.getEventId(), config, queueParmas, customerId, secretKey); + return getQueueITTokenValidationResult(targetUrl, config, queueParmas, customerId, secretKey); } else { - return getInQueueRedirectResult(targetUrl, config, customerId); + return cancelQueueCookieReturnQueueResult(targetUrl, config, customerId); } } private RequestValidationResult getQueueITTokenValidationResult( - String targetUrl, - String eventId, + String targetUrl, QueueEventConfig config, QueueUrlParams queueParams, String customerId, String secretKey) throws Exception { + String calculatedHash = HashHelper.generateSHA256Hash(secretKey, queueParams.getQueueITTokenWithoutHash()); if (!calculatedHash.toUpperCase().equals(queueParams.getHashCode().toUpperCase())) { - return getVaidationErrorResult(customerId, targetUrl, config, queueParams, "hash"); + return cancelQueueCookieReturnErrorResult(customerId, targetUrl, config, queueParams, "hash"); } - if (!eventId.toUpperCase().equals(queueParams.getEventId().toUpperCase())) { - return getVaidationErrorResult(customerId, targetUrl, config, queueParams, "eventid"); + if (!config.getEventId().toUpperCase().equals(queueParams.getEventId().toUpperCase())) { + return cancelQueueCookieReturnErrorResult(customerId, targetUrl, config, queueParams, "eventid"); } if (queueParams.getTimeStamp() < System.currentTimeMillis() / 1000L) { - return getVaidationErrorResult(customerId, targetUrl, config, queueParams, "timestamp"); + return cancelQueueCookieReturnErrorResult(customerId, targetUrl, config, queueParams, "timestamp"); } this._userInQueueStateRepository.store( @@ -94,67 +92,80 @@ private RequestValidationResult getQueueITTokenValidationResult( queueParams.getRedirectType(), secretKey); - return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), queueParams.getQueueId(), null, queueParams.getRedirectType()); + return new RequestValidationResult( + ActionType.QUEUE_ACTION, + config.getEventId(), + queueParams.getQueueId(), + null, + queueParams.getRedirectType(), + config.getActionName()); } - private RequestValidationResult getVaidationErrorResult( + private RequestValidationResult cancelQueueCookieReturnErrorResult( String customerId, String targetUrl, QueueEventConfig config, QueueUrlParams qParams, - String errorCode) throws Exception { + String errorCode) throws Exception { + + this._userInQueueStateRepository.cancelQueueCookie(config.getEventId(), config.getCookieDomain()); - String query = getQueryString(customerId, config.getEventId(), config.getVersion(), config.getCulture(), config.getLayoutName()) - + "&queueittoken=" + qParams.getQueueITToken() - + "&ts=" + System.currentTimeMillis() / 1000L; + String query = getQueryString(customerId, config.getEventId(), config.getVersion(), config.getActionName(), config.getCulture(), config.getLayoutName()) + + "&queueittoken=" + qParams.getQueueITToken() + "&ts=" + System.currentTimeMillis() / 1000L; + if (!Utils.isNullOrWhiteSpace(targetUrl)) { - query += "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); - } - String domainAlias = config.getQueueDomain(); - if (!domainAlias.endsWith("/")) { - domainAlias = domainAlias + "/"; + query += "&t=" + Utils.encodeUrl(targetUrl); } - String redirectUrl = "https://" + domainAlias + "error/" + errorCode + "/?" + query; - return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), null, redirectUrl, null); + + String redirectUrl = generateRedirectUrl(config.getQueueDomain(), "error/" + errorCode + "/", query); + + return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), null, redirectUrl, null, config.getActionName()); } - private RequestValidationResult getInQueueRedirectResult( + private RequestValidationResult cancelQueueCookieReturnQueueResult( String targetUrl, QueueEventConfig config, String customerId) throws Exception { - - String redirectUrl = "https://" + config.getQueueDomain() + "?" - + getQueryString(customerId, config.getEventId(), config.getVersion(), config.getCulture(), config.getLayoutName()); + + this._userInQueueStateRepository.cancelQueueCookie(config.getEventId(), config.getCookieDomain()); + String query = getQueryString(customerId, config.getEventId(), config.getVersion(), config.getActionName(), config.getCulture(), config.getLayoutName()); + if (!Utils.isNullOrWhiteSpace(targetUrl)) { - redirectUrl += "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); - } + query += "&t=" + Utils.encodeUrl(targetUrl); - return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), null, redirectUrl, null); + } + String redirectUrl = generateRedirectUrl(config.getQueueDomain(), "", query); + + return new RequestValidationResult(ActionType.QUEUE_ACTION, config.getEventId(), null, redirectUrl, null, config.getActionName()); } - - private String getQueryString( - String customerId, - String eventId, - int configVersion, - String culture, - String layoutName) throws Exception { - ArrayList queryStringList = new ArrayList(); - queryStringList.add("c=" + URLEncoder.encode(customerId, "UTF-8")); - queryStringList.add("e=" + URLEncoder.encode(eventId, "UTF-8")); - queryStringList.add("ver=v3-java-" + URLEncoder.encode(SDK_VERSION, "UTF-8")); - queryStringList.add("cver=" + URLEncoder.encode(String.valueOf(configVersion), "UTF-8")); + + private String getQueryString(String customerId, String eventId, int configVersion, String actionName, String culture, String layoutName) throws Exception { + + ArrayList queryStringList = new ArrayList(); + queryStringList.add("c=" + Utils.encodeUrl(customerId)); + queryStringList.add("e=" + Utils.encodeUrl(eventId)); + queryStringList.add("ver=" + Utils.encodeUrl(SDK_VERSION)); + queryStringList.add("cver=" + Utils.encodeUrl(String.valueOf(configVersion))); + queryStringList.add("man=" + Utils.encodeUrl(actionName)); if (!Utils.isNullOrWhiteSpace(culture)) { - queryStringList.add("cid=" + URLEncoder.encode(culture, "UTF-8")); + queryStringList.add("cid=" + Utils.encodeUrl(culture)); } if (!Utils.isNullOrWhiteSpace(layoutName)) { - queryStringList.add("l=" + URLEncoder.encode(layoutName, "UTF-8")); + queryStringList.add("l=" + Utils.encodeUrl(layoutName)); } return Utils.join("&", queryStringList); } + private String generateRedirectUrl(String queueDomain, String uriPath, String query) throws Exception{ + if (!queueDomain.endsWith("/")) { + queueDomain = queueDomain + "/"; + } + return "https://" + queueDomain + uriPath + "?" + query; + } + @Override public void extendQueueCookie( String eventId, @@ -175,28 +186,23 @@ public RequestValidationResult validateCancelRequest( if (state.isValid()) { this._userInQueueStateRepository.cancelQueueCookie(config.getEventId(), config.getCookieDomain()); - - String query = getQueryString(customerId, config.getEventId(), config.getVersion(), null, null); - - if (targetUrl != null) { - query += "&r=" + URLEncoder.encode(targetUrl, "UTF-8"); + String uriPath = "cancel/"+ customerId + "/" + config.getEventId() + "/"; + + String query = getQueryString(customerId, config.getEventId(), config.getVersion(), config.getActionName(), null, null); + + if (!Utils.isNullOrWhiteSpace(targetUrl)) { + query += "&r=" + Utils.encodeUrl(targetUrl); } - - String domainAlias = config.getQueueDomain(); - if (!domainAlias.endsWith("/")) { - domainAlias = domainAlias + "/"; - } - - String redirectUrl = "https://" + domainAlias + "cancel/" + customerId + "/" + config.getEventId() + "/?" + query; - - return new RequestValidationResult(ActionType.CANCEL_ACTION, config.getEventId(), state.getQueueId(), redirectUrl, state.getRedirectType()); + String redirectUrl = generateRedirectUrl(config.getQueueDomain(), uriPath, query); + + return new RequestValidationResult(ActionType.CANCEL_ACTION, config.getEventId(), state.getQueueId(), redirectUrl, state.getRedirectType(), config.getActionName()); } else { - return new RequestValidationResult(ActionType.CANCEL_ACTION, config.getEventId(), null, null, null); + return new RequestValidationResult(ActionType.CANCEL_ACTION, config.getEventId(), null, null, null, config.getActionName()); } } @Override - public RequestValidationResult getIgnoreActionResult() { - return new RequestValidationResult(ActionType.IGNORE_ACTION, null, null, null, null); + public RequestValidationResult getIgnoreActionResult(String actionName) { + return new RequestValidationResult(ActionType.IGNORE_ACTION, null, null, null, null, actionName); } -} +} \ No newline at end of file diff --git a/SDK/src/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java b/SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java similarity index 98% rename from SDK/src/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java index 759b513..8848e47 100644 --- a/SDK/src/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepository.java @@ -139,7 +139,7 @@ private Boolean isCookieValid( } public static HashMap getCookieNameValueMap(String cookieValue) { - HashMap result = new HashMap(); + HashMap result = new HashMap(); String[] cookieNameValues = cookieValue.split("&"); for (int i = 0; i < cookieNameValues.length; ++i) { @@ -196,13 +196,10 @@ public void reissueQueueCookie( if (!isCookieValid(secretKey, cookieNameValueMap, eventId, cookieValidityMinutes, true)) { return; } - - String issueTime = Long.toString(System.currentTimeMillis() / 1000L); Integer fixedCookieValidityMinutes = null; if (cookieNameValueMap.containsKey(FIXED_COOKIE_VALIDITY_MINUTES_KEY)) { fixedCookieValidityMinutes = Integer.valueOf(cookieNameValueMap.get(FIXED_COOKIE_VALIDITY_MINUTES_KEY)); } - String cookieValue = createCookieValue(eventId, cookieNameValueMap.get(QUEUE_ID_KEY), fixedCookieValidityMinutes, cookieNameValueMap.get(REDIRECT_TYPE_KEY), secretKey); this.cookieManager.setCookie(cookieKey, cookieValue, 24 * 60 * 60, cookieDomain); diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/Constants.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/Constants.java similarity index 84% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/Constants.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/Constants.java index d9a5b89..f9b0afe 100644 --- a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/Constants.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/Constants.java @@ -19,9 +19,6 @@ final class ComparisonOperatorType { public static final String EQUALS = "Equals"; public static final String CONTAINS = "Contains"; - public static final String STARTS_WITH = "StartsWith"; - public static final String ENDS_WITH = "EndsWith"; - public static final String MATCHES_WITH = "MatchesWith"; public static final String EQUALS_ANY = "EqualsAny"; public static final String CONTAINS_ANY = "ContainsAny"; } diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/CustomerIntegration.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/CustomerIntegration.java similarity index 100% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/CustomerIntegration.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/CustomerIntegration.java diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java similarity index 91% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java index 4cf7390..0ae74ed 100644 --- a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationConfigModel.java @@ -13,5 +13,5 @@ public class IntegrationConfigModel { public String RedirectLogic; public String ForcedTargetUrl; public String ActionType; - public TriggerModel[] Triggers; + public TriggerModel[] Triggers; } diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java similarity index 79% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java index 93c0509..555aefa 100644 --- a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java +++ b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluator.java @@ -1,9 +1,9 @@ package queueit.knownuserv3.sdk.integrationconfig; + import java.net.MalformedURLException; import java.net.URL; import javax.servlet.http.Cookie; -import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; interface IIntegrationEvaluator { @@ -172,13 +172,8 @@ public static boolean evaluate( return equals(value, valueToCompare, isNegative, isIgnoreCase); } else if (ComparisonOperatorType.CONTAINS.equals(opt)) { return contains(value, valueToCompare, isNegative, isIgnoreCase); - } else if (ComparisonOperatorType.STARTS_WITH.equals(opt)) { - return startsWith(value, valueToCompare, isNegative, isIgnoreCase); - } else if (ComparisonOperatorType.ENDS_WITH.equals(opt)) { - return endsWith(value, valueToCompare, isNegative, isIgnoreCase); - } else if (ComparisonOperatorType.MATCHES_WITH.equals(opt)) { - return matchesWith(value, valueToCompare, isNegative, isIgnoreCase); - } else if (ComparisonOperatorType.EQUALS_ANY.equals(opt)) { + } + else if (ComparisonOperatorType.EQUALS_ANY.equals(opt)) { return equalsAny(value, valuesToCompare, isNegative, isIgnoreCase); } else if (ComparisonOperatorType.CONTAINS_ANY.equals(opt)) { return containsAny(value, valuesToCompare, isNegative, isIgnoreCase); @@ -188,12 +183,12 @@ public static boolean evaluate( } private static boolean contains(String value, String valueToCompare, boolean isNegative, boolean ignoreCase) { - if (valueToCompare.equals("*")) { + if (valueToCompare.equals("*") && value != null && !value.isEmpty()) { return true; } boolean evaluation; if (ignoreCase) { - evaluation = value.toUpperCase().contains(valueToCompare.toUpperCase()); + evaluation = value.toUpperCase().contains(valueToCompare.toUpperCase()); } else { evaluation = value.contains(valueToCompare); } @@ -220,54 +215,6 @@ private static boolean equals(String value, String valueToCompare, boolean isNeg } } - private static boolean endsWith(String value, String valueToCompare, boolean isNegative, boolean ignoreCase) { - boolean evaluation; - - if (ignoreCase) { - evaluation = value.toUpperCase().endsWith(valueToCompare.toUpperCase()); - } else { - evaluation = value.endsWith(valueToCompare); - } - - if (isNegative) { - return !evaluation; - } else { - return evaluation; - } - } - - private static boolean startsWith(String value, String valueToCompare, boolean isNegative, boolean ignoreCase) { - boolean evaluation; - - if (ignoreCase) { - evaluation = value.toUpperCase().startsWith(valueToCompare.toUpperCase()); - } else { - evaluation = value.startsWith(valueToCompare); - } - - if (isNegative) { - return !evaluation; - } else { - return evaluation; - } - } - - private static boolean matchesWith(String value, String valueToCompare, boolean isNegative, boolean isIgnoreCase) { - Pattern pattern; - if (isIgnoreCase) { - pattern = Pattern.compile(valueToCompare, Pattern.CASE_INSENSITIVE); - } else { - pattern = Pattern.compile(valueToCompare); - } - - boolean evaluation = pattern.matcher(value).matches(); - if (isNegative) { - return !evaluation; - } else { - return evaluation; - } - } - private static boolean equalsAny(String value, String[] valuesToCompare, boolean isNegative, boolean isIgnoreCase) { for (String valueToCompare : valuesToCompare) { if (equals(value, valueToCompare, false, isIgnoreCase)) { diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/TriggerModel.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/TriggerModel.java similarity index 100% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/TriggerModel.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/TriggerModel.java diff --git a/SDK/src/queueit/knownuserv3/sdk/integrationconfig/TriggerPart.java b/SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/TriggerPart.java similarity index 100% rename from SDK/src/queueit/knownuserv3/sdk/integrationconfig/TriggerPart.java rename to SDK/src/main/java/queueit/knownuserv3/sdk/integrationconfig/TriggerPart.java diff --git a/SDK/src/main/resources/hamcrest-core-1.3.jar b/SDK/src/main/resources/hamcrest-core-1.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9d5fe16e3dd37ebe79a36f61f5d0e1a69a653a8a GIT binary patch literal 45024 zcmaI81C*p&lQmqnZQHhOn_aeT+qTtZ+wQVmUAC*b%)j2bGxN>8@64Yo^W@64;>nfg zWbD|nBO+5l8W;o$00062fW7oo0N{VzAOS!CWJOg3X(i>v=s(8+02Kby6as+l+w|#c zNwVhK91suy0OkAnzfENYJ+q&~~XcVMg@)Q>u853k!`i`Ur45 zyu5Cd37@2HgH)`Wy1`l;*oM6)AovI`MZ*5P^GAe-{5dEZG0FFgLIHB7%e7m@~IKQ2JFQMZ<9=GfFm*%A&yCZ2FhNHwGWyrhp(buKg?hqDS+*3t9 zd{fJ?i!iu3WWuibV>u(s!C7Y9Ec@WNo2&8wt$(Q78NE9faKyXMFZx?z#3g=W!ggoW zxBju_^2Gk#d1;@npM{AJMlo8%y|Ejj#qPY!E?ZE}{zt!8D)Sevt(Mlx?wUpBu7Pd- z+&=5f)$cT0MHpK#AxKNtLgIJ;1o0;w;U`Im=XE0^FJ`(EW^RqEi|ti|O73QiforP# zZ4`hWX!GNBWxLS!_Nha8kt+qvaywJz^&^fC8TLt%rr#0pz;rRNvOOFu-M3nI=avGe zGeQvShWz>WK)WN5I{5e2?{Wf-#LUiZA$BZ*U2cs9(rD%v`A}Y>;3#xQ{>62Eo>{k^kl!@X(KI9@K zP|&oX8WJ<-Sx`mN@Uw|3vJ}OpTfpgEQ$i8C2HuxCnNO7>v;M|S?XW0&?ONp#Xsq{bsj*Uh;RjX%HgjZ zDcD81yIB87fQn~>(|C4lNp49A0PPu*kkf1B#@2_ChL&1Ygu98+J^LoG$hkZK#b=S&+3y>I$q^Pesl7%RmMS5C%3|Beac-R%1#O@FxO1 zgA!Vxayv;1V*Dj>CYT#C3woj>nT!jiIa1715Fwi6L6eK+)cMN&Tz(BxQ|^%LTr5K$ zk^Rrc^G%HwiAcP{>{ZKiZ<@NrpM`v~-eSWZ$sa8#XjdrgO{MX{fuTSLc!5`kTVoSg zkx^J3fwyDpx4}j+V|NjI`)N0O`^5TV&nOHkC@tDhIZTCD*PJKU(a}w;ry|kT2x(5AaXMUN2y6CRpK%|^ z8zX`PGgBCxWr6}~wM(DmZ$S+2^~1@X-|@^qkVAw$29(R2s*U(<$*W+veIM?&1gJPA z&jf1a4fTmkn53m2AI{uCYb&0EV)^%2xmcvmVyAR)RO^<|r`!`65={#m>2uhQQ>R6q zQx_b-V^1_t0Pgy{x}^j^q|~2G_ahv3mo>AId%ES4yqvQ~v8lEeZ_z%B_ieJ3Z)0QK zZgcByNKyTkZ_(dX1=S6VKZE0a81awaxMFw1BjKIjVQWvH5&YC=RY*#lFGPD|<8DG@ z{dV$TrV`K?NrvOmfP+?bE+P)Njmu~#HT>#nOqe*YgBh(ThQp)|_Fic28i__O?DHtS z4;ay#B`2=r(=q4#h+nQDB{wf80Mq1S%nkyiP{Y(WV@p~AV#*upqgtb+h`}c<5-t-0 z?NT2Dulu5m0bZIZnVAoH)2|uZ>`B`M>^)^ew$8l6#^Z829~mNHxDT_>If7E zVJZSK$$4y{Q9kc!rXpDH(YAKf%!_SKQSzA)*@R@N`V{}zz}8bbEn+T??gM;5gCjXS zh^u~U93JSUN$b*BTt2fqUm4q*p~FT5wH z!9xXmu2r!m{0{U$Lh-o1|EI;6AhI)SSfnTj?f_6Oq3|J3W^^WA{|^!L0%)^ARi%AM zTXpnxxUoy&%^J!kUFz0O%vO6imp|qV16Bi8gXhylzQHo*=yUewfamJtOZSm8hre*d ziAQ4~ejr!WVOrINRH8K*Qu{UN4F_$FD6}$BZDvR5@KAp7-qtVQv@q30h)M!0D_ZYx-={x%~$*|j6x@uqG^rA#UV;D`c4 zTxv57a%R2oCZ}LDmAB1J<%hx#^|gV~FUIvWsNA47P^?iz-xx=i;F4>KOiX_Y-Rr^+ z-Ec`ePh78D_TT?~PewAJJ(R@>8vF}Jfs=4?hmcmqX^vdX=V_UfBu)yMBwuy+6m_mU>2c@>7 z+PLl1WXwrH4SkNh503CP;up1p17UO14ZUS>Z7QorCE`_Llo+vhjLss~uGOIsbEfxC zZiTU1!R5K6stovuuLs0S%G|r6Dv7xIE}m&@_e}CPkj9ttE-0>xU3}9nGvn(H@iW;k z{J*Cf<)rvf+CTsR0^dnH-v5?r$Qn2snVUHNm1e{!>pIN~pzuOBH35dqYgtr(+#s(* zsg0udPcOQ97rKaHcu&%dL2VF1Ceir5Q~S)n?!e!Ob8dNafEZRz+FzSKC{L~X!S)s49! zrBz7HE9nzwy`iWhIr`{rbNtR*3*Y{`R-R$8-5hGh-b6lIYUa)Z^DIT<_I#_ILB;45 zj2zJPz=<7*z62@tS_fz}o|$|Y5_n$(2726rT7BIoG)0P44DCv3*iie?re=h$-E;GT zN1l!6J?#TXwKvX9uUCfH6cCj_=^5m%*j z*M`v>9qnGo2C_W^cXFXsYM~UKT{r`$G`*;dcs%-U^GdyrzDa^u-hpp*(LTnIkEYKB zg#x|IHI;(CKqTeV{|fZuqY-4uF*=g;r-n!~%vUQ?fh`DmWgDgiYXXtnz-5{ex zTYwCd9eFoP1;7%z0^F-j*n=X!pX!L#Y<;-PX5m>xs9|xy9Jed??lk+PPj37Ch+lis zfGI+&M0B2;FYw>p@~*f3Pu{mXPJTcB%`JuPY>h4cmHUz~{^gc7(SlF|3<#oM=FM7B zuB3FjZEW{2qWvLlHz16#Hc~PK5qQ%f;5Q0}kvrr3llXj-Z?#YRkoh9HM6wBp4UOHL z-=bc6psS%&O;EG(@;L_?jhndXVVp%AQ%k!n9Z_wWwdzoPw;28+%vuTv;-w$slxnIw zEmz@QRK{tcZlNTJ2qE?B#Sr%tum@{IPzF-$mJCBYZ)9o@{-HeG`+w9e{w2lVS9d7Y zzh$!icY;syPsIJdt^I{NLJ1x-cd-Vd!YZ`t43vOvY2cYc8*rOas!eU35ff?E+&utXsq1i=YQ~QH z`jBQl`iKSswH6dn1Z>6zvKKW)bvsYpVpMIz&PLm6ZM%#*Y&u+JmtI5rFm158(XavZ zT0vr>3aT^_Yt$a)()hc@JpBSp+nP&NTPWumB>vpoZR@G}_onh!IBh)%vAQhQ=-RdNgZX%P)bJhv*h+`h5gTcCyRi;}2fE#DftKNa`hpF3@| z_Xkhxe39monl3yD{(X0Tu+AuV*_n~6oto{FV~2ME=*=tIJ5uF1uB{T&zFtY^Q#P%J zv}=yJVL*RKGblm~qJJG4Km|#Z#EXfIDnZ5FXpA~S$=|Sqpq@5HvIZ!3>jRUsYz7do z7JUL4DYhONi?mGB?8h*bhS!wq_^^j7YJYn{kik|204wDxeJocCCmEy16 z`4~C{;F~hUYKn7PBLmW=1DI;mAEZ!7%O`W1P&*N$`@-Fu;H#qqHGQT7OrOqt)}7PL zhz?wE$UvP(3DC`w7dQvdH#t1;#WmU-^`I*|!zi)1LVpFfSCrEvy9NJy%ppIz9M<@z z!e8H1NdA8VQ_jx$Z`ce`7W@|{ex{OuAV8~Cr)b%rQY&cx|}58su?>Ovh}x6JCTwlwa@ExnX2Z!wu*8gI=GjaS*S<{M<^?YW>ku9$(>j@`FcagxfEDjg zZuWp51dLUJ4|>BqZRfGQ-=3lut(Lk17OmW_oVs|5>F>L0#KDQxi104O*s*ctn>mSC zGao{b!R114pRmPD@;ht%bMo4nU%uOXja)r*8Wgt;{Bl;hrY?&Z0)|F&k1)4}$ofBP z5cCJ@^x2D4MjF7MQZ3q%YmK_=hnaOUOWi;f&?HX`DNRpTJp1cBE~!h7QFVo{&H9@# z)b{1XkaDPRLX<9k7m4|Gf!&r%KwPq{pnO-w=He5o>YPY?<4-b50F*b2O}20dx(*#fP@NxL@Mi2p!t4ntJ~>96Kf@mF_z`8dSCpQR$y;ikE_<%q<|X!DJspGuPKqN$p~7fKRmGK|@cI|M&+X(mttr?tVLE z#do!v@c(vBWoHxnzbGR|j?s2N03jRH$Os%lHM0q&xL*oen}vWxT7qs8obKoVhso^x zDm=NiWCzegWeBra!oSj*nY*!*`R&h}56DeqeHb`Au~6KS%ZsRn>BW{Qku9psT#!Qe7i z>@WSBpS@RcS)15S7d z8PLX;<4J@V*T8J*o;X{r=JI2djTF}Z%#^=n~+#DbvD%^-qP`c zc+l9!X2Z@V2~4!CV^XAB;(%2u)`R>-ax1sG-&WV}jsrA#tu(z0XJVO7xJ>+&=gxmP zQPhbRHS~(hnBjhDKk}^%sFJJMT8|Q~TFX6U>L}dc{>!nHxF8KTqQ)H8wd_zv*0tNC zF$wuk+ErT7$|ZFS`jXP}Y$TdtjzXZwXlx>P%k&^?T9-w0qH+SA9e^bVRKjkzxM7pW z+X-Fc)x$+cISKzxPi@jlAoWTC$$|BBJ91$&aaD?^d!@a#@sddl{*~CuK8SkCY=9hO z5Jn7P7FG>`T@JFjcDl6nfd9!om3v2OwOl?Mz<>YQf07T zydEOtd;Q6Qcf5632K>`0>#f6pc}bMok>q?fGl*;z1D6y7NV-&i2N{(gkaTF<(#a-h10=i$Y-(|b zNhi;MyF)~uP~|iA?lNfdH;eV|;xLY13DDu4^&H&dbzDOQ4G6^PBh1i5ftWmQLQT^B zPkI`eIHoO_T^2b|wF&o}sHRJ(J<4DR_M8v`BNI>nWy?d4*&AHM2N7Sz(7~>huQ&1# zWvUtMiLtng)LktHJegHP@4>i$nL#^#?wMmn5)C27)MK4OC;vlc{;O3bI`dxC`VGw! zS^xn2e}|`|$$!dBr@s)oqzUPbV}k0JbYYr!YTuOHQcv6BpIKy645ZZnBFvRM%u;O& zN2r!-y{S+UMHm&(uN0AUq!kKv};5sM>%y3J1hf;xk1=T*5O)#GAyX z{2n0a$SyJo9?7jFQXbK*1rmIMyGDTcjv`VVpG?X`H zkI-Hvls9ZH$*l{Le8O`m&~~sL<&DiVT*Nii4ev8wL>cNcAP&*3FcLq}tr4g%5I^ZH zGpH|Iufk5+4K-+Pfd0e{HfC;0K9y;yY^P}8c*m+-p)~CNNT@O{^p&a zgv~Oa*p!R#ef=VsJERvFlim#@L(R?o)tc2rZx)A#%bBIdXUC1@X0D$KkNcsSy9`y8 zHBGshR=%4twOBljR?IBY~x-fR_Yc6kO2>vjNdE8@SJ5NnNt2bi>0!Yt477BU&laQprGO z;8ZYjX|q=1cQ9S7x*i6mmR3-3w0d!IhMIO!wEM%*PWFJ>Dps)uF{RcRU&y^Ab>jdB zi@lW6B`QJIo{UvtjX@-u3TToZq90Ub1PhbZEgM7utA)N$hq8F{v}L+PWSv#;x;TYE z(|#*B6#KuMXvCLnNmdzRTnrvNex7QGdTP3Xkmj@Nfbr;A_SYDK9v5X_=aYVnk1S{B zo=xshFb5{x12!T-qje6*Xt(6bVco0o_WpdwUM;t+n3`v>s4Qk?vz1kDHhu$+iZm-(m^Bna;wfoOS8fl^`O*sIHuu0!wF%ov^7Fx@ zmq8v0X9hhL#A=)mRce+e#t1bRA5`4wm|m<9^H_P2Qu&6Wf8MaVIYgWtut#hZ-Fkd4 zg9D2O@we?muAocdX^RY12I>i zKyt#G!?t2SSf!Q}{nPqS-Kz^8#b}vqAEHMK_6Xppprhk%F?(_J0#;aixXpH(GuopK zuJ=L-{i_cQ&>ib&MeB~;>uQaywRKl*yVMZmg!ef_+&2$l+yaUKkA<+M)ljR36NY#W zj#=#F202GpJSJDTR#wo4YKAH|XWI;M3cDJ`j;u3^_BfMt%~-hb#Zf11^rZhZvB*mc z(}oFTBewOC-jL~ZLFiQ`^o=|G+{4W7$6(>$!V9vD6KtOF7pommB;8M3S>f@STKHaI zA8^$!qnA9>mfq|G3f)!1Rc(xMjB{5wqgPI2Q%9w5-6`?thYv-I;BZ7S2D?g*G%a)g zT0&FdR$!yg#nR4sfBlSvn%LFC#tpN~waKoxak%GcsTfszSgpX*UNVs`Qs1W-cRyxi zffxS6@L!8C40+(n50Gaa)O$r(d0xaq-cAhb*18r{Ja=Wy=HJQIutdRoIFAO z7R##`xQ8lH@_H7|NcI`gf!W5c~h_)NVxY3{w z-v!xP+V8;-i!#Irk?z8v6V>pRM(CS9Hpsj0*8@~{tW)3VVFvU<4MMHwO$g&=f`$T#^{PX-~|$%YYhCOr!^M;#lv%chQAMg5Grm~+FhLk z{spY)#v&}}#$rr*a8__TZ$y~v>km7+@yjWlg$p#a9cT{?YGc4HqF~*TK|NN=i)y?J z8;DME4afzB#%{XVOt3=QC)Yam5})yP~A55^cH0gqNgyO7#|`c`n?Dq zH38$i_+L>TMDigd4f^RPX*YGBw6BkaBHPoXul@)vv0*-BBp0{?y!E-;$a#PIee-|F zcOeU2AqBG76QF*wzri~axIqhIdBl70#d~=ZpxzL&y)wY;xZuUU?jkbeqba%LhOU1B z{aunRWE?HMe9P7DZ&^n0Z#kcfle3-8-^Yi%t z+M|kaW2oR!wmm{{tRX3t=TkH z2UlvR4NYlLQF6mzv+`?|_k<~D_9MVpo-RR}DN@u2VY~Jk=zD>C^5lsx&DAZvR|tji zI`-XR3-dkzAzGYjq*(ks!CaYE01?r`m^@$C0`cVj1XcThm)dC2#tj^oFL)hz#C)`h zLUuYI?Yy9|V?OAZSJe>*WZbsecsjmtpX)`4wRJ%o#lKT{FE2e84K2Tbl~0T4rhZG#W-nN@)eTGs+sJ zlK5ime3f1hEAPQGGZH=2q%;YiYIZ(?k62Ghoual7mSNoDI;&5B0q#Dwag8W1MzH02 zz#+|qHjEl&+w{_IY-igaNj zlBFHBG}~Cxj}+Tl(zgo)#bqMIR}hH!{6e~QXvnZFwKg3zRok0EN-hlKgZiYny&zi! z!G1WL%;5Cux#q?<^Lu}PN9_YvX_P2R7ov;_qA_es6NEB_Gr=jf=MNzcor2~>4I(!* zd~>WSDZ{wSk^W3&*Qv=CQ-4$9lnrf8RZ(iibfxl3t>g_IYG+4)!Nx5gn)tDZ-ZT7G z1F_4K)yaD`al_{)b5fAafaAimZ2|N0>v33weL5)OQEa)h{^Sn&Hqgq8!kcIY7VY7Z z4tRdWY4*%7znP|TjqKM2OanblT!D(_l};UTW_4Z1Wc;a=xC8EU@s7cSXVZ_F%FmKI zm&WeR9x25YXm4$vq+N;-?BTqSSujTqQ;x1ukE@P>-7BMQNHL+)GG*<_YARX@R&fxE z$B=Rg^?>tKVUj@sur(ApnCwEKy04b_g6CEbjJ=fErVrKJxu5^xKoRAp9Gw;gYS_6H z3vgu?-4=~Pr^&+ll7#z6ml?fcvCt>cVcGn1E?+0ji5>&htRrSE zjCb(4?*eV5Q>ax2s2q5~*n2y_Wr~4Nzu8@!y9k|j+PdIHi9Ix*6bN(ulIhPPI*%o? zdnKIXV)~q`a%RUG<>82$z(~8a<-Nj{76oWPv37gKMxcOpb?$<61?J*~IcvYkI4m)E zpo7ICh)YYpjzpMv8^q*Bl{6f2_ zz|1Yi@)L*RXEttmGBvn|N$zs4x4;opAeE59qJe(eHWJt;N0>Ss))`Id;KpL{Kev?6 z9KXGWO7AZYLLHd^0XEMhyJK?{YkIMDYhqb3S z$?QuF;z|tYzL0;x+e8{Pp!iwEpioY|3I zkG>bQ5xv32AKQ&iZz(P&YrR3Y2b5ZO5Gc9Ie%gzqw$l7I6yvY|9tr+yE|8C(Yq9M+ zG=lwa&HDevk)`E{1Q9;55)k`AT~u%C;UE0hL>k0X>>XGc3GIIv8uG9T53*Tc&odi6 zo(+E)@uZvYeYfi|t@_dvhHnv%8J1K}uN6Wzgg!E~SplrVJT!AK(IQwix9;ef>e z^Wq<>rj`vu1gaooRDs`1Abbm>DYGz*xsEzWv()(fnmnV(hd+)UPA^`?;!UAnBz03_ z+ZS7d&^fd!s_z={2^mRHj*iSVWP!daP4M-Pb}_M6*xls!cRu`0hyT_t7O^le zv$b=wur>QzCY6#XEx#dvF#46n;c(Fr5}c^CK0g}q7%>GQEk=_w z$`E@E4rx0A8b>Pv7~daW)x~u`k&LqXY>>yzmzn!K3txQ&!1ZQa3{akyXD|~Mct&-#9V&UmHcPE^32&kAFEI0Szs{Z&LRHi-QOD(XmTA2q z;hCQa6YealUYD_j{BokLtn@N$Rp;KXn~hK%XY@{+oAdtz`>F_RwZd!bbGthZJ4!#uT>)WEP$5u#S6&M$r;l8ZH# zlh9dRN!^geIsSR^N>w#*;bb2EVz@-ltzIXD2U7>GoH)qQ z<-N&D}P|j6$WG2AnCk*_7mpkQEBHA-Aee`u(LBhvr>@E zgc1JZhMCr<&&RFpK7GHhPjdgPpRqZ8TGcn$x?lO+Fy{w*0&*1gQ7aGA^=1xXG87an=2od|5LlKD zklIE%T~@ems$zvls>_a;8-HZURVv)-OjsZ?VG>N3W(|l*ry6-s!#p+a(#VB!Sd6J+ zE-uLh?aA6|!qGpivtD7DP8|h`l-aJUE;JAEGE{8!ESa>iWIGL-xo-O3*U`H$-1Ksd z*BfID=hIg1s)E{Z+t`=|rmD(zj=E*StTX`k<*X}b+B3S%41|P{MfL(i&>t+i@I$DYk(;DYTI*4T<+>no7;Cw~ znbjqQfd2fvPi=J0M+~~yc=#Mka4GG83%(mpIwf4l6ty z`!a)@W4u8nwu3CplHPJZ)TZAn=j6UnD$7ms27NSq6P;fc@*x|t_)2g3TFitl*0x6# zXC|-O>4m*;DP)p`12<>Kq~zkH&%OdS%on4G;NJEh*DKfx}5iCzZ? zQF#3zRP}j=R;@gh>?4+0I0J=-erXavH6G-arp=61yb<1j9szjVQHCc;;3beJ==Gam zQX}mgzdbwW-KAAf8E^IK7oDsmz(VwvVGwOJ^xWXhHGIO2?;#o@zK6c>{2qx#h$CR7 zYaPAg^a~CKI!t-3(4V3yY%;Z&Qnbx!pxptxdxnw*Mx}kC)*{QM`(BK5+e9GSCD?ik zIoEyOz43cR-0@ZO)q7L17r#dxLdLW*jS+Kx(ICjX#JBDE1e2)R^8^GB`O0?pl5)Q4 zPTq5xp3urCfa1$KPJwvu4IQh+|LMpkW_ST_A}@zjeeq|u>leWyTM#KZ2LXMe+#bPg z_xl6?ckr{in&{Df$HspN$bXBEf8)py#lPaCk(H6vQiUqQmw*?e`;DQfLPZ%`zZAS) zsw`8fcB1T=J9*GJUXy@Fq=5#?54&r0Y@p?t_==e{9 zUFK?LYG~rt!K<=%J`P?XpJGGWOCGa<;jyXPnHTvlZHu9?-y2#1^YshX(G4DWcO_EU z=1z=%1Pg@B{R-$TuV{O{5FWo6$`K)?>8P%@sZ@nfC;SJox{%Zr+#bLp8_x=lJhR}^ z>eRN*S1IZrp#FZy0TQQIP~Q=D1MGh(?EL2;3pzQOI6D7lfK|~}M^eQ24IbZbARlGeThc+t`C@HzS&FXwy9woo@2>p#=KRW;=mFf*FZ1g@lww zV%_A9%$dpW;uv0pO(XkaDvuZghU&ED%U1_AW+uxP5j4AwL}h8Oih@5*3nvUwo-qbg zx{Oe_g`U~WO_`Y6N>e(D%xadbQw+#34OFffg_cagz^B9yNm%sdheF=uUd4x#A}jYG zVf!jhrn5@AA)ajE|8*LQ^yqOwT zAq_bN3RX~eX;QT~uQNmS=tw@zpsu>qCNMph7O71_BOd#jsqqP2u`;#x6}P5SVX}BR zoJT%^srA#EfUizkueAM5z@5K3Q#ukB*qjTB*j$F(K|x!0ObAqC4a5ehL2K&=>|3jQ zm-0iZf>l8&tLEGf9+IdK=kB6>LC;rr$oTylT#~Z3c4!AzQCCx-z0X4x8Bw|h$wqH- zO*gcE!3g`w#~KuCzn3taE?`^|JrPV9SFPaQ&6H>@jlV>@3c(uchT?R|0Sv0SMmZeE z8xYRsHddy~nxa9tE|{)JUK(V6+6eE& z0Y^iJYz;a`E=Xkx>Yu<|K-*Yj6tpU1^nKgyz zNhV)l?_L0Hy)5c3GU_12Ab3)$6?)n(vP&3j;1GwHfd0>!o&d;X>&Wj6rS|*rZ<&g+ ziM8oplFsluz5feH+z)mud|+T;!eDZ)V6LuUaAIIJ$%}gjg_FgL@!n!!ny`8Ah0Y(* zLz@SMi+e~u=yf`RlBT}7&88R%4)(qlijEc9rgBuoLH72Ra#$jwN~U@pdTNH6M8rWX zk$^v?Ffc&`BJZ7${>(poBsC}{Nv~pHVqm6Y2>2(2Bm`sxfDRe{08NyEvHpifaTFNr zx&AJ=n0^O@f72++&W_(3_&0U>U9OYI`YzXr#fN|n6B(j5H$4VMMLsQCRsNJj)=ILp z_SX54%-U8tq4XB_s+FW>DZBpk`Lon46&3xrIlk-TWV`n^yV>;n%iAAxe@SZzjHG@B zI%5B-XmAYp1Xe-=C3owmY3LR;rR7`KNDMN_^_$7JE zmcldewWWQdnzTis5PBw%R2JPvH41v(hKZdSOwwtDDJw2NeQqjyCvg&{p*u0f>Whj} zvd7p3yOd@sVJf?H@U;d{6&8=Baa--uQv9kvmUD}-v{SPYrSzAy0`_3EMT!Fq89ji* z)Nio)K*Q+bIs`FDfmc;6B#bay5rW>950Uiw>q;1&^Q{FTY+_{>7QrmUZ?0DRP6_%s zW9rQ^a~SZlpU%@Ybn|IO;bpuj6B}YvG6zHv5Ia1y81jTC$bNZJ2^MyoQou z2*T`xv%gyr`l0ls-I4nNQ0if%G-7rbmoYkc<$lfjO}!VCYOf=@fhKVlsZo|V4@%`^ zW)3Tpva8~70(MU`%obY8Ry(GV8QO08Pqa4AF!*ibG>K@7SD$M=sO`q1TfFY;HI6du z_T1}evbMfR#+-|8F`3iOh~B0nriQZ$Ohdbgqgy=aT1tO7EnnvUiKe0mQ_z?!KGhc`? zK>QjOZ#iImN^f{M4*!ciDol6yQm#I)<8g?RuOLSuPo<}T*D1gro6lG9{x>PtqhU^w zi-=#|+OPqa=}>?i0t$mrkK!FwF_rKrPGh+e2ztpchTL^p2{!HcA!Z(O8o{rDC_ayX zny<1vqHP+FvIyHyileI%`6S~xD$f?UkK~1p{QM{LkA_OG{v#FRi>f)lzcZ*0JDEw^ zH-kccYZRJ)YLx$~ZvS86URBp=K@5c#n>vA51PA-U|i-4;sf}58YaLU%+&oL0Dt(th6ZKAHS}h0X{*-hnzQpfE^n&` z+#VMmRc8N)1nF6@pZ5Kyz_3kychT&OJk(Vo$$oAihb`0uJ<+E+W|YHZ_$nzTD&_oh~&{o@o*pYf9RDj7rN z^9e8GCAE%;#Hw=yxyT&TwX)3^vqqXQ>D+XJt;;9uy$t-r#3w*Vt_8NXeek!7QI@tm zW~7$>=HLh&VRE65YTJhMB=5|{YRS7k3}&_7m(VYfwI*4+fXvy@j!8QP3F#bKOGZUz zo1T_!Tl+Fw7Mg})%bZdJ8;n@W#{k7USD7@yC_^Z;Aq3O~^EKR+Chf{k2%CKyq$ zk{Y~5u?#U3>nWHAdJPm}l;&DRd1DH_HnVVx0TOUS25)8|u>N9W&n{Yb%sVC-yO$>R z=Ze$UkRB~r%Uu<2i7O|DY;LXyLOolpfS%Uzht9!p=(!8g!9(CKs`DJ5GD&L)MLJx{ zK~_brVa~~Nj*tZ=HI?_!H>wKve4>ctn?vLGnnEzy5vrWTBCMI}OKmmdUqkVt)$43- z-Z|}+hG1qYC=4_C`1)3J^H_tMw{Td48AWYG0pJ;=SK6C@-iQyI-owd%cxH8I#CD;y zBc|Dlm>TwpP-WOIx$+L$-u3elH;LMgbsW#Smsqm)5}KScW|xvXM{^K1pHP!JgXFkv zXNJ;91|H2iq9G0EmeoQx+0Al^RTjGS-w$9%cNgozpr5)$s(shFG-V9Y(#+GYMEA8D z2EWbB!(1QF^yrezoncTrY)#KQtmvROx>}HRYet8H8Wx>;gBu zT1BJ65%3FZ(RT@ZH%5&CQ_O^a9>*Kf3k^Z`Ze8|RIPS7=W~#->BtbizCW5qmDUj-8 z4CK59Fv$BM z1j!vxg!O8FY|cn`1$AU_apIjDo}rF_GMrPxl@Nq(47iH-V=aeFh+$+IJ%hM~km8T=sMYk$2WR zV^Mj)l*ueJsA&RGGLH&oQLRgUY(B^E@~BujUfrN)lSry(y>f3V+6v?F7?bGqV--f- zD*~F2)F;pGRPM5`glhp?=E*nkr68f*(L>ZeTPmkg);@>V42?7*%lhm~f|3Y@oP#;K zRmWRf!Gg~y{R*r@-$w>hZ9Yz-69o|^D}$@mDpm1NJM?nIm8cPz$g8}%Ga)Q?j!l;+ zarY)Q{!IsGa5y!uhdSKg>Jai&HG)uB2>~~j`i+%Y<`G@kN9!64=GaoU*TVK-oPCB_ z_cElTXyb#vB6(e0Ed~T#mSO4X|D)`kq9l#7tHIEh}sD zKWDU{nF#{gm3{KJ4l6I%=uzy%8AV z@cuNyDY~b6@u3>8Kg$ereOS2G4{WemM+76mjIcqAbW*#4QDbmjR<9J}CH|4HOQIKQ z%g`F@bKOXS=u*4SSq{;zWcqIzXhgqbk6u-N1~)G5t1NHqa{xD4V%mXo}e z?eEq#_pD>jE3|;lNq%12wzfzgR?j3&w^1IgOAvG!2Cg4I@dFBJMVy?0v7k4M9hrak zx`_<&x=6yuq57DUg2Be>z2FPoc7i26Y<^}%85?P1VA?M9UWln~ zImor%cyRmqgi>^$DRt;S$xfN~@=atByyM76uZ%g4Eie|%J^jp=N561Uy$tu0 z8X$L6@f;{cK+eU$zX9)E5jdhR)9D^W?!Ql!|88;N zx3ZEo`Nv^lS#`q^SsCNYI%8U!A|HLASS2W<#Jp1v(Oi;6j;_CjfR+}t%PLX2Gmgx; zF&OO{op0$@dz2mDOCKkD-hU$M^&qh4_2_G_@HM-!lYF{bifin|$z-)|K-F`eYb?uoc(|tHp)mzRx z%~;W#p6RE__hl_67RWbCD@;6E49AcAGlBKF2$QcgRNFRJ2L}p%UnHJE4;^-7r1ipP zCMQ{OJA7IriuWUV-r8t-+9`_>63s*eJldk=%_NJHi>(}|%zLiA=p=F(beQVj>66(r z3NtMZy~)C(t%W&@45QS0e6(@!yJHk?w1kkVU+WO1ru3HPj%Ay^LewR&-t$Y)FZox{ z1FO4jmLx=Kbl$OLa|z|gG-f9L)#9LJO3E@STHRxUl50Bn{z2L2^N9#!H(QPCB&6%8 z+M&>=2vbR9Bx6*IDgs?Dr|0#{A>`ndkfdx18S9g5jbnd`yUOX!6g}ii)yBPg^eSN7 z>nl)3ms!fYnTF0h>)Eb4oYv1d;xd|5gC0!JAnI#2Ub93Cn)_MC#AnV#=8HD8mllG( zLG}O-h~o{sb4W?Sc?&{-gXJ zcYdbTBe!(#h`Q|$*)e2(**5c9`olKmRjm%eg$RFuO{j|^s4i@^i$Q>507f5DwOqSA zm@)wDf2vw_eyO=p>^;QJJ7C`F}sUXg^>{XI@afPrw!u@crUTSFg;_7~D1983g zfdFR5H?Xn*FSEd~g!))H_~^Ym9F1TDz;gCGZ%mm(G4_^f>sZbUk!bCtvw$zyYVNGJ z`%B~Oc5h*?rOD>*boRXI{<#1Ep}gMEuyl%>vefLJi43cZjMVtmXcE(`9ZCgv6O=Nk zp=lCse^^dw3k9q)Bo5bPOIrZB=$7Z&xX2t6j@H!Q<0iqUC!7>l{WHHm-6Pr*^dW*- zs5?)TR)gSC;aFKa<7{RWSDFzha{|5W)q*UL{6x3jn#io=U-GzXU4cDT9 z+sq_I1U=e+Oql$ViEK*sC88y_ z&{4OM^B$!~Lszf7Rr-k11$UduJc)jnE2<4-?j8YVLs0G>rjzI@rlZd zF6g5YqK!dX@>UrnbI$3wve(ys2eGbo(YO5K5C3>)_!%LQXVA6`0)vRYACfCV5=C_f zMXv zq@6mN$WdMPp(2(#B-d4;u}DwkO1+yEs2JsRvreq_y~$U_prT_hJ0Ke zAV70Ao^-xPMc}SWdu)MD_(EZ*hUBv02Csa;b7|y_H5!H=eej&HYrmUqTL;_Lb`x*X zuJu;YH^x93@ydL_J4b?huzs{E49GJzI$NFCsC~>5-E@9PJ?W9!pqJ?T;hXTN=@p}V z%V~4}veolVZN;WO*L9jQ15)Rh05S9D7{(V>m8to_HTu*IPA^9%+p~+P3&YEXvY~r^ zdK`MpMk|mF85AN>j?RuXq_VERsNA&>VrjWnY!z zqp5{oC7~m$1S1NfAmaZ#h{YLcv~|iBjF%RKBj(1^iqhz&FWlfgi10))Vu_*U7d?k<Zaz|9RI?WxxljEJKWjCJ|sMAY-Kg zj?y=+`a?*XeBE^$w-Z;|MXEd=nWmOp(RIW+`-15%edr`BdkxnKjTl7=zvxz*NE#5IQ>JUKo9G02LGF<42{GgMe;MAR1VjhA{aO^Ge z8g{wn6F%SHbH{s++*oJD6&YOFbC~WpxpEVZ9R)z&a*v$PX}DBNq+aHn%-nN~>X@_{ z*6PvsVEdxA9r+;b9HG#3=^h?PP_K4VnWk6Lnx%^3tW<;^j7m^mtff)MTX<}?m^k4> zasTTR=2L`wF*Y@22bnyK=0`kV5T5romPfHCTyE|;&-j4~k2}+JrwV!Fqu(;QG8sjG2D1ug=uu~TF^}w-u~8e$yFeG?DYXwD0rEOX-?)E zBA@@aaO(h)HhL<{+C*bLhEA}$33Q|KMcQW>^o+F|$AP!E0if$t>DWTd_7JD+fdwr* z++lSOtgV6YYn+j}Df7{&ER+L&b#hL=!%w?2dIV%^Y7X3qTCi4*zOehRx7pPFlyVQI zecvCDt(iI83C6PzS(^ID7LMNOJ7BHV5Im0j6O(9HAPzX->C&E~t(L;rjV^8v{MP9g zcdih}S2}=i_D~xpN+I2Q#xTZU+40+I_(xP(piUnv?UhTR1$~VWcmU1&I=P(FdaP$1 z1JhGM#-za&0ssS7WJ!=y%e@zJ_x?ht=l5rv!SAvVE+h!Mzb25&H2k6`q#LYo4 z3ULYS<{Msxa^kC#f@Dw?9QlMHa$5q0rKOB-M`GOUMMifDgg( zG#RI@IH#{c3Nv$2R^zRe7SzPZ+n^o+4A>w6(G^183wTz+27(hf{?jN-3d(roZdn3Qd^uxElq`lpfXm)f?Tp-8H^A-dpKTv!Pf|lDGye}N`nT4 z2DGqcz8Nh_weh|_O1v*fF7rHZ(=&!cDq(Mg3EV*^fxE7n926E6v`8{&;Y5JE`OjDp z#9@C9lBu~MOy{VA0S1(id0g1Exr2H1bB~f352#_j(uNPw45t!vI_WGmQdp{F(bS0} z#o|0%v0}hJ;%mjwoo8mk!6p*BwKOAW|0piYkGQ!wOX@`uy~F-t^_EOeLW2V z5z-%JH(yz4Tdh;FLD`_NIdDkVA4CZ#9DcVD!Blb7dfl(!m)mU4!pMrTfEi-ytA74Grp4- z&t;SSGae$rW8WaWe=`z{3SqX`WxCz(Sq{HmZ?7kqnu6I%icoM?w^^g{v7dX&c zhhAN0%VN=(a$fuAiRw}TMMlyggCP9kCW>h}KygZ*#d1`y`OiY} zhIcblw~kpEt$D0=8KwLrqn-+RY2=FS8e$K+8nS*8p=kRvx%Xeuv$M#Owf~JClW+9! z|Nlmhu({KBebK+*r}#T)u=pK~cl;%#wU_}!=P%%oCZ^~=Of7!T2LeQCt=t?jfoQ-=3V#X;%Z}JbNTjhJWBsVR=!aWU;}Er$!xzP z@U!x@*#zJp9tuN6=ui7#)gjE1G9#K$CC<3c&94ACZ`A3Ty!k)c+PR|VmGmG>W(j;Ly5$&svAkc zEa|bz`MQ!ktgbLe$UP!qv16^Y1cLRQ!LYG>|A?TnV`8B{Bf!j zA%gO`!hr!D@3+r4MM?;XU?{kmvK@x2F;G00F{cMEvEGz?IZR*l0WqT{vhh?pn`kxm?ZXE^I zVx@h_iss2^)?undy*O3YXl!WKVV3rByFpd2D$ULujUpeW^VxF|*2c=ENig>6sLFWb zFtnwL616ulQw%tz32F4mKb#7eQ{@>J(~Kku{VQbbm;=xr!BX0jl~}$Fy7cyi6lRP= zcOL5H)>I)>+grnR&6P-Bw<4a#Tf3M$q`6kUh0%fC$lT@k7-Q`|n{Xx9uasFQ_5c&K zBwQVCy)lw|`sC{*De3u&^uG&|IxP*+Y-sK3Y)ib7%gq-Djt)}IZrU7M4l((aH5qI_ z2K79tVQ_~+^;yILRt)6^^hs{=rWoQm`BFX3s_&o!a!pW!g)Wf1raCnzDcZ)=rlOBT z;!vkXwXp$hs){r^xv_w+Di^9 zlxPb_M)qw5;L_7-jZK94Msp{MWT>k-df65!q~)Y$W2#! zUy_Z1SGzOzpaszrh&|JXb$Ufnh{dDI8|ql`sF{GzMUOdAHbWyun?_7$D>ti<_#qO) z2z4m)fjf6t&#s`Aq*2QZ6Zp7%`I~j8eZo@ERAMbi{mIxcqia$Myui`|LeFQWZ6YOd ztcGbp7kSK&x}N=4o&3!($6G@u8+_u1Yzh2=bA)+8v0gW|?8ldQMGkv-@|g6JvQgga zp&b0buI7(A+y__4Mw~xhW{Tql3trmBe#fJ-Co=>Z%VCq2u4Z8T>DY~FatOo_3CnaO-OKuZatdjsN)&=&jL+#1}tLf}}s8N1*Z4>{;q4rPvh_Mm>KWi0=Ri;(3 zl~KN=krLuCH6;9zDA1blUjmeZqDdIPq3<_P2XQx@}D$2&Fi9N2e#dueV&UueaYiZSRhM_kP0dI(wn=qqJ(w2XA<# zhwt)s;SUg~ng~zn=SaE|sr79^pv50b(gncRkpS?19h`kY;OV7T;@dk1=hoaE61v_{ zfN%=@y3?oFlqLir+ja6!kH}Y{QC@YZ(xMzkyL6eVnap(PAh8^FT47SE<{%?bN})B5 z#sumxbuLWPNt}%6m!jr9zDN|eRH3zKP-Yzy%`KgGqhn7YoZKzZs$fd|L9;sCk*I4L zAv_8g0#t`WBe!o(54-=AA1$&dFK+6Ou%hlJ&_rWqxiZsQR-z^*K<0*8$1W8edQR}` zE7Bp@BsW!#o>rZ7H#s=)8m|ed87n6JBiDXq16IYFyqn97BQOt}lG7lWVHynSI7O%O zad|n>6M8?YyH&e%FnM&SWtNb&!6UGVdSB;8z&8i~)V&fZ)(@IY9QnDnx26dGP`@AM z?1eP9v8m>#%NC*2U0s+s+)`CVijCHvi8$92Yb3*Z=><~6+rWvZ&)2Nh4z@(s?04}+ zB-?18ho|$~;&VaBdV9`Ll)6K0nWlLvMM;sgK-w(BW}L_Se(XSIGNKrJ!-LCK~bZ(tNjf9THyL;zg^}yN}z>Wpz9AO1y@xP>>*`ui~Vv;%Aw5UB|1c2oJRmU$cv}Tct1@u zx(tA7mJ|&fq}dv*3MW{CqlaTLV~Ia4;(=n7tMyzHz&eMW$ii5D2}W-gPEA{EI~`uF zO-XH@|GhS6Q(AIpSJ2lW6dk0}TMOK}-Ouq)Daco)e%HQ(^E%VB6=|f9ouJo>hfR!M zzsb5BE#wgfUqbqtV#&M9DF_)2zXbx5l%m#nmhp=@DkLP_!_?xLy3sh>-dC|85VBga5t62YN{W%my)9t_Dm9VEXurc;S~|P2TYn zG-@~E{L?mIroZ+xh(Y+~vcP#JSNxLbj#ebWt27tI9(@6C-K%Z1HK4qYPNu7GJf62{ z5f3wK!t3i=_ai1S=6Y^#b931Ic!eL6Ug4Gx7D3#Scr!cb6p0XzI4d#fk%zQLpbdVa zLu1km)mAUbE^-V&wO!=3QO0Atm!YXbKDn%s^1#!s{)-6ucWYf_+PYvVK6o0D%c02l zwKDgWpP^lB3ht+FZkiv%iqT z`fpCiqXKSIwf{;CGyU8>^T6zd22Rjb4Wcy^ z`{mB*zh`JVP0V))zDH%|w;KPSbu(cXOfdS5K#)`ZuoHq)uQ(WH<2ebaL(KC`$cdv*N{?UiJsN8@Pcl| zqhNl)8fso}>t8ShVOMB#&P#>NTMt$p$}EWtFVS$f?vLHW%oEj~R&24bhKTDH4+xYe z>5_hjSXSG+Cm3>WpV&P65ISs?#+Q?=Yb-mbMbw!kE!t%ghFaw1&%rCkhqq8eE|6{F z2W@;&2bUZ&Wm)fO=!vhJxVf!2WS*F*+HSWW;1>^x18^Pg3{jU2t9?f5lK%J<{8Dyw zR<1q7Tg#w~yW7%XW2rQ_Q_RHn@OcdL{}Zr5-PnDHTy22t<+o!X#z`-oxr!UwLfC*; ziSd`KJRVuL6g!FV&u&UoEpWVkfiDXTzX4gppYz)6#7-ZW?9oZ{kqQO56$!9Gr6VNc z3Cpf^Oa~=oWx_hJL4)3v)74yi85izLww^uR`Gp=5RoaW%2Ni>6S!^+4-^~EqgrFWj zOy9Mo@8Jj6Hhiity$Y*|s#KlBxuHOk(8*SAxHG#6-$UwNzT&0PYPK1i=*i`<6x-EnkR5f1i2J;vEetrOv1k|HF!U!>_ z?rt1m!I`;yo)d;BRL_tq6yCmNh`zeRak!>A=+3TY$hkL|ieB^r%HNUlU9trj=C5c< zSU!;^-Js4yk-uY8ud;dtsuDYs$jj@?Ie!)qlL?9@B`YqAJo^-Vs`tH}$}wwRmbBV% z&sAM3{5(7=PL~sgv@e?I*U1>W*Xp+Je=p!I;65$h_P)h5q&f+lAY9`z)99uZ6sY`m zQJVNdLenYSDMWnLFD#1mDc}`v{h@%7$DEuqvnsAo!prArb;VxSenAiMF4RgeVuo9S z8%8YD^X-}A*b>3Dmf8g)kd1j7uW6;cradH-T@1&X9QGFP0XNf~Z9y5aE= zvF{c|LVV*6;s{}wqkgT>@xd!IK234(DR=`trQg;%0EcK_)i(2`I9;xRh%J?xJLw9E z?=X|L61-#fUUcmb-+^R=07bafF?8;+4l@U*-t?6b)b=MJS`WrmW4vGg7C6`|EfQY& zcJlrBzQg8!1rGjOk{AEy@|B(J>xdAGcCcZ(gB-Y!+B<-ApQy7)K$2 zgw4=AbJB*R>43{|b9J)zbb!xQXjs79^FudjztMBlzRy1b!}MLR+mA9^&94L zC6cI%NTJ;>+H0&jw(-V23yf~(K^rArPtlN1OHLz0n7EoK6EgCg1Cct;Z_uekst?I@ zqRH@~;?Bh-W4DNF~(kFn?Nd3sFW!jp|p)v$u=jI5(?! z@lxwqn@1F}&2QUG+f6jH(qhC*+pX1cQze7+NiN$4#kCIwRpU- z^#OkTF>R+-%sgQtu%(-OF&N^N%G|sg2yZ1_apMh*bdD!!qxmtBZAnA%F{}21`rmmk zfl*|f^Rj}HecDYEwXlvsCVsYXdgrX&ni%CO(p#lb)iu2~HgP0I72_v*p=5oht-0hm zw^r&Z5$X5cib}>Z!R2P@N=}XSJ?hNADxp!LvzU0%TG16|yiWpWUm5m{6=a?}Pi~PG zGzS#DT$A$h#*_B##t@YJ%z@~e1v^2|4~7D{%>KXKL#WIFbBD7D~ zYII-J2EP|Iaa2#-<3;9Z{42%wSv>+im07yAftRKxdpHg{@t%)>?vSR-m`^C%WxZ_3 zo}dk09ES{_8Gp`hKlrWpAVYowPJgDSWBpMvCX z(#e{m+(MDTW*xGUlhFLyOY`fvGhkPTFQR6R`511*>qMF zbb){z>=kOqRRqy5#N`Ev2BeLZMC_Doh^q^@W^Pr-e;t5Ju?R{3S9|P!_UXbEkZ|wR zX7|&k3y!xG+5Wx$iIp0H8`59*xrnB zqU?bVWuC>`6)Xe5!H!COx#<`&SP{AWHBs3JOQ6iLu`5=hw00D^KALR;^b6S22uBUC zVGM%}uwFFUVIh)tT+i`hHGW3x)q_`g{b|V>e%?qyZ-|2}RHG{i=YheMmG*#{#U!iklyV~IhS8$2CW+nHoi4etXn96qr1|h<8-Mdt z_Xy$isC0rZR*q;uNp#e(U06k9iTJUFWn?d>U5p`-N%he7H0U`s(~iC1U}vOada-Y|q*)p+Eb@~W zZ@K;mmb;XGhFZ}`)ESV&?|5F0K%WX8rw?>{-S$kvViy}aleAdO6!X-vE~7k3%hHN` z$@&D2CZ6;J@*OhoIHG01g&>c@+y1{1@LWGK%Q3!fXSMMEp-8u>e3E5k$>7v%>smq*c}B8U{eRuQbH0aC71phBTiwjz$9cVQI3 z94K(v{b)e{yKlAU86eoHqFG#Xcy=baYT+x4|Bl`KHU*Oyo-TJXnYHoD(|70B&L7jy z_v6*kAFsFCAlYqeAc(fY^D&b0Q+g@B+c5y98Wun{MU4O;P=GkXivc|ZCm;46kw%XZ zhBN?8D-xhxhM1Ih+w6cL+0~5~GBZb0=^(x`)n$Z+Zk%zFMR5+DE?lm(WIQ;X8(*0MDV#VhPPtB9MYFw)@+Pn_>+Hei9qCYL zD9Wh>D@9+BBl>NHT6>vQV+&`kFe?nNL^t%Ox0aAcLgriJ^x69<9ok<6;kbh{ZCYm8 zLgEZ^lNmbmu}oUYz|pNnMB}h^@A@Y6KTl25Zbucmvr{c~Bt=op`Khs$BH76o$Bf+7 z=_d@K=pQ=YD?RX^2n^6+5V`9VgTfCPY{J^YQ4uTM=%X}=wnxE1IJS^SLWzD2j1v9o zFNNVQ&XH&@zUo-SL(JV{6EtYFg$A$Vj+zzr@+agPiO>jj*48*oI3&{zxlIn^ekO>j z74{0W6~@_rv~D&>xCMe^z**BGI<+8mQ000XZE(q(cevXHB?YJwoV-I9f){?JX!i{EPmLU)B2u{g0#=$<>(x}f9PNn z17%$utFL@GCXldI;{7FimV|v#h(99pN=-_7gDq&CCGyiLKmN7I@XU2l%76VwbNm5t zoza;oh)jHmgMxn^M~QQz60?c7QY&u#5<2jXk;-$gFuSIBo; zeAd6xB&!L>7$}BzI9*qcXZn+)Xs<@3BU&+45$yeOj_Ll z>U?^*UJ`6l)^lFa2Uew6R5jPiv(hOhPS6&=;IAycMDUl4qmV(WLsPhc5E&Q5_P;L1 zOCA4l_)_F-f{CNne z5RN~Ojq*$uttuwRF5cS8BP1-PwvK+90JkV^U+|_?;Hgz0YM-LQ8LR{=f3+Wk8m^h` zSWP7~>lxk>qd>J|XEOxj4xu4T@fUl2u{W>KA<_CTi>8^U6}9YbJ6~J+a%Pi_v9SEP zF~zP>?m(sr_XqvIvf1);cx7bY6wUj0BIIx(dq0HbFyM@< zU&ve~?@C>H;~|p{H^Ov$C{bofy4PW>>!|3=;}U{|kV$titIz27TW=(Q9LUSZ!m0liEw$d65HmFJEmYf5*Gt48B$ zws`=0s^&GcS`eA`UL|@t{j&8ULbw;#BJ)uENAPPL!s-yW!GooN>z1qVpmqi49!r|# zdeXykGvF^ed`+a}nP-P{Bl;D)^-e`&!l8Om2<(Q7S7PfDa>OZ5yR^66CNY;&@o!Dn zXWB(WUZeG#MJH;j4M4+U@dz4cTukG$+$hJ)Nt!5|{~On%+){mzB$vbHU3?7E4h>Ny z@hmO8lUGzI*W+z?jOa6q|Ln8>YmN-Te5H0+dDF4{qp>Ut;1BJ5}l51Ap2@ z1cDee>M>2o@zFlK$J6iuvlt$^mrqaYZlQAs6LVJ47m5H^)w>GLeR3fgL|!=a zeH0+B^%6xvE>!wZr;ad1((HiAF|nHjkX6v<+A!gpJna-RuSPL>E^9d6gSlHMolC$R zY3RsbI?f!i7~_4;5Xag0FkV3#kE}Q3#u3Vp90Mlu68XTR=f#wrv1|f+8mt7gO~LO| zA)0B~)_oFx3Z8Tgajh{;nB_jT;8M*kJ6U5Jaif@HN|BMGU`rhNiFpq&d-N)a4OXq> z<}iY*Bp^nS7K`6v2iDK464-$!2nU|6+14DwimE9~g316Gk|; zH=JVj^MiY3BM();Ba_5Fx<)^kq>fDO7=m74ANzsa|K3#KQ);Xig~}$}B*%V%!`~-h zZ(G6!YHD{NQAzbiCB;5iEg(e*xc?(2KJ-CD#P>x0q7d!}sw!xoQmS#t(Jo_^9A|&K zr2)QLt)cRi<-Z@!VzlPE%f3fU=r>hE@*f2=aYu0*M<;z7L*xH3mPV^+Yho)S_^^ws zv(fw%fCSaRqA(DnsMqMt2)k1+r(8lRUyAiez)2XMw(00Bm-`?->sIZ~^QLKjbbtS; z^PK3F)d-m>TgT3AdX$y!ew@wO`S#T7`w6;>u!J7x{~Az*?E1Mw0ZKuG9{0t4+X+aDIE`)JS#|8%R2pu3M<|Ee+)NHAhw ziM|6lE)pOYP{VkUexT?k2H7VNIv0Fsd6Ib`4vTr?b=MY}T>EZ0L*R*j^&WiB-PoACe52 zfy4Q0@ui;z)ImevUj6L2C+zgH8_2S9*_gOQ{!_lfq|%<<+7wZkE@E-@3$>E7ize*k zCUH)4#frTt=ytJC3<6Dyb+oZ0NV1+83F)VIaEQMaYpg7!<5rtFq{{~Fl0-Ne;s%mU zNh3Q~K7G!BPOI9f6&tA-PNya-PW6;4i)JAn9cIWW!_Nhmx6O<8nY$Qs+=Rqj%us_) zUQOPkk@Et_+1%)B5A13zYOIoK%;7{wZKUvRt4w9;*;Q7?6v65HPJ)@rFhRvzFcame zJ>1*8;xuSe99Zz*!8-q zIZojmIUfLDDOJjked^#lOxta@o?HOdC=rYuO!GUB4|@8ud0}I;;_n$;lXO8_ypF$< zx@Es>n$Ds1yzE>yYIo@o-JXT2R;iPCmwUu!`95Zhv*+&#C%wevVRoVwOfez5sdX&H zhnMtx`a*bp#^bn~lFDJRT+4Y+Gili3zdY(tB;F*0x9D+z@Z+0dWZ%9o9RE_Izxx$y zf_^!M4>+Z^XCU6}^alPk@fqX^ZqRnB%~Pvp)d^MV20B-*h$ySIIWPDLfT+JP$AHn3 z7tA|`gF@4jzbwH`d8L2jOFT4wn-j`n6IjnJhKNCXt}~b)^I9KJ_#7y+N&fwjiYSm| zkwK(Wa{IGJFS~6D=@BQp4B-{DmT0mXQJPi5Cc13ZEnCe4{dzv8>{fMRpS+!n)JM?l z7mj7?vSr2fqfKoF9Bn&TR0=Wj=t9uDA@pdtbMo(S*(4!%4k?l8%RzYB*=yM z>+DZb4pEJ;K3JqI$O6~!G41>VAe*L?HOm>S?a~Dj*S~}|Z3m@sHNaa{vHT>6IS$B3 zeE9rjq`qgya2=%z50yzaSpH$Dqye!MY#%#%i1^3>?(Dfc)0JHV4|LIglEJ=suS811 zbwP8RZmDTteNyYRo;2;BRCIq&2YyL69u=$Gitkry+5!|+ZQlRwCL_kr2%Woc8VV8o z|4r`_cl^G_=%1^UlBMjT9EQ(2Y=;YKl0Ej=Fty>Lw36If7Es`jkpKV{ z7y&Qj79#eKsd`_8P&_$OjzMzu3P=$r1naO0JZt2j+jbLGxnOaLhQ^>wx5Gyg5!ypU z{+hJpKEoC}r6Ns9V-jcDJnYttL)geGyXNLT!Y0e)k~v2$_PR`?%0g9vLPdfpiEV|1 zvuwRn%TpHro1CrO;FV8>xp{eNH147d_Yn8F%-L~sqmS^hm+9N0(_mC(DI6k34e*KBx z=>)KgM{y5{Yu8w=OvBBQERCrWcBj^&y6mu;wdS54g5=$+uz+HQm}uz1rs}d5^K3c! zuG|=(B=DGIi$ppmzAzjWFF3yb$#A+S`iq)Ba#$L&*-8wVDHYb|R%s-r4hdD!QI%t3 zarVM}%$SO4C7i{Bv(RG`-wiiREA{>Q1E%k4AFMw!nH<#O?2%hJq+a9m7f09pq8_>R zZMAD0!$^vCR-+u`-*#gpHT?suPeqDVo3AJ%+m>->wt(R(dG{6OD!^?dPJ3|+KMvMB zc9bd}3eBg`q&M?YDWz&LKNO|(8U&m68KZt`B-%9L5z2O`6+b5 zEriwtWq?97asnOI`KJjRJS%y_yMUVQPXughTwzlIwF}12H#{4XPgpMi%uhUgLXh8t z7|)wT3}WMX18jChpg8@`Q*M0?iRia}r@RAM;P+QJWQ^b8y&v#kt|9z*w(G}9SxM?t zY4`pa6UkZ51R2Lx|C6zhn3MuyG@g2!{TNl()j;(d zJ% z{jaMA|9SHGucFw0{9FFvJx1WoEOG{bNI-WBh-=!2Yh<8Nq>@olRZ}TL9WGEnY_r8A zcQ{;(xgdNH>A3loqQ$uh0}2ruTQ=5Y-UWy*FJ^K$9ZgI=j;~{Nf2`C~5(g?^O{!Pz z_5>+oQYH;4q|}Ev*LxD|5e}LuGqadR5~@?MVJL8$NE%~QnumDIowF!c&SY}AlUbAu z`~_=ev46~_JQi!jJhCWRro+FDF(_|QRFRUTz1{%l)vjfb3I>+#IPQO0E3@d<`BNZQ zK8SlLRt%FEyw3PFHp#`leyBQasBBL)3=cDfG67bDagbs`owA~I9+XBOq!u!@@%Ap}@ zZPp^SUfBtt6ABJ#B)N|i| zp?aPvxCC$X_lEKCO$&RleSnd^ty%{jg)h6gEBj$PYDG_6036wh95K4sl9BryetbhXich*D7#ca@HyN4RHj-5JGJ< zDwqS=0HbO@UFs>##;>CD2}}7Gv-}_x;<#;+^Dy5_raqGdAG&T5{bDig_Rl%WVZAI# z4{>^5XOF?3?(_npQbVRG0~@oDC=AZ}Fc@eXl(^6Er8mVWFK5(;WqSRb6%ZSu>o+v5 zkYVVMuE;{RT>S?ag(N-N5I?*O**eKq8Y05AzGMIVB75joK|#bEZli7*S8$`pMmI;< z)S0+PXRyYumunix9Zz`BRkVL!e|O(>kqSbWb(S)Ks-Ad*{~>fY7(9-zjNtaC7mC4(y&|_X$XSw(tf-hI}(jKM_iP~60R_SBV+}gi( zD;~^NIW)%b9Lrn2NEr<5A;(ZC5s#lrxm@dK8`Qex&}*KF^8v6?dX`vl1B81w5OT(` zaS0){B3;im8xMJ*N&;IhnNccgRx6s^SMP%Gm1tIxleK$CIs+(<6Z<~43Ehl|EFzn1 zB%6gDil~|=fh%d>Av<;yJU1;FPo(!WbG8slChN4Mka%EsJp3=Y^yjVaDeS63-IxOR z5-YSv;oA)3?-n=^#ozDc>c}%8#4_?wt!>ibWAm#lY6#(5oZ z*mo7u@nzU!HuqF^J>Ebjz%J7O(YKr8H-=Y{h!)*PkGzr>YYzH<`dwCxaDm-7+46`d z<055C%K$O{uvS=Yk)AMC$@=;W1;)wg^G|6o>z4907WxY|Vuat7x{EBso>;dUUX0Cs zjoB+FR*8|*aC6Svr;&)y&)p+?ZG2yHgunkb^-4D1` zN}phd&|3-|;-)z?W0H!nu%#y;N8o>)xM72~^Io+8);`ZE*i5;Ewm&1CBy^Yo)2WiW z`Cfh*pJ7gCi*ek7?gUearaoioqWWXzLGCYMiQk20L?I?aaul;AaB(UG;cyJadThws zy7ns20YD%SRyBpB z3mxKkFgs^WWE;vJU8t?%99hx$LB?G(*y z9h?lEo&K3C`7fp7A4pGDwpK)vNAaPfqZ@c6qD;?Uh-}XjvDJW(H&;iq05yNK_Lpwq zPf<@PF?l8aTW;%fE2;QLjafSP4e=xCY;y}#Fr`6%&2hHfH20q87?18dRq_e7%d_%+ zGVBBox9{*nH4Z`#O#D+UybX(wec_iDvi(*pp46LN;D-8V+Wnr%k5&eHKuZ`mOb_fZ zO_EaK$Xu#>36CnkxVQmNmqA%@Jaw5wP*z2=mcnF94wJ5}sEDbf9*>?98&t45{Z<&8 zo;7`vbn!v|M8+I-T8bGbd5cO&6(fkVTkIy3Nkdq>!uCL!c=QP)0JA$UNfkwKzXus* zDnZ0+R0A5_Nif<}vO^#3>?o@zel@JQL^X`R4E4~s*`KBUcUV$!u>OQ}-|q)U_kt}W zz~&eEfWv3H21DXJIm~B)1~rC;&h#mapab=Rv}LVD_?{ghdK@{z&HO3++&5MX`+LaLT*!9ALHVkOMbqR zZAYa74g*)7ihYrea0`mFa%l<7GPLP;QSM6;*hF!XUBaV^)1T<0r2N9qq$a5@A zEvYWZ81m`XkL!E|6B02iZ)N-ec}>#2r6xJ@eMn7cK+uTv;3llAEDRO0(rt>NqZX5N zC7XrGX}oK?|Np7%Jm9hX{{K%%xb00wHrab;-9#aYWW;TgRQ6tR8)bKAXA{aMD|^dM z$;h6GvNL~|&!@USu8%(d|M&8^jmN`zo^xH-xz2UYd5_ojR3_ZoJU#W2*s?T5!!{eP zo^lRX4$pO*q%66YI% z=|e%EG-EoCDL=g}74LmXkb18&Cf{nAI+>){bJn#FpXar_sLB`Akl7Bm_C1s2dgB?o zDOaVtIGzFnO=uZSQG)#uDKj zzbzKN^K6PaA;{Cm0@DC;Em}fyOGwdj%4`?DN;wtFTZ`8J_?wM_I@|g)dzFr5CU_urZrD~|5r@PU z51R+{yOhToTFrEurcJP%ES7f!Lemrj2d^@SIj}}PubWN#tvYc8;v!LK7!4EsBK95O zE$P?WoV#IhRql*{I!!QQrf3o9G-dyfP6M?y zwZ9F-eEmJRhel1<4)T(;UU9Y>F@;f&f8aZM4WZCueMt~QjUX_-jlmQWGTGBT*2<TmY9P^C3I&Q8rzFIS{R71L9I=pPn96j|}Exf@smKGb{5_Y{g+T%U>ve;VN zY>wkVM4ME8M$zlR{>XO}!V)=D8C*X=sl z!(7Is2&HHaGTU!Mp4y#PY1Z!&>|po-hncxskd<)QphCLu6m~Sy+0!V>X(T4hJ@)lb z(sG{Toe~FTA^UY$`xXKB)AFx$5pyY}u?i?J?9eOUlv?#omBtdEOjR3l$6l|t%9ndY z-|fqzPWy!>nni~6t`C$`tB^D$jH*d;OSP(XG;OQ3EUMDtdgIBQ}dx-v3(dpgh;0e;i*!a-A$lGe{1CyHyv z=PjPq8m%_5_b_8!-KCyON|WT&dylQnwJhAtVw^wkk?8k|G{UIn{v}%3kL~=aJC?%k zpGBS-3Wrarp_Lz@xKzkg`fkbD6UMw+=I@5w#$Fo&#hVs)#t<$5eWecQD{TKUz-T(a z>>N(@79cPXh_y9zwyN@9d0g!Dv>=qP^#c}1^PD2He`(%1BH5(L9^AV?pN*b@?5gYg z_{X9XUGbp{5LJ8ISjBLaX>?&%s#mOSJ3QI24y__wLfTqq>qZMOrsyQMyrvTND87BK zqI+_+O@vpRxH$>gJD9Eb#N!6dg3}2GhBu8X_?q+zg zSrOG*uBOz+Z!x@RZrvC5gZC!G$FFRfjr{W6h#vfmFlWk|n#G08(aE07>{rvVtW!CQ zpQa2uJzDD7?xiR+mc1L0e69q!rZ+km>m|+Yn<|9sT)xYyuT*q{WQmsj5!-~uc* z>{w2byE0ksq*gE8pX-MsxR>c1mNrk=mn(KN(xNt_B8${mv?8d=OsbUgLG~6Uf+zL| zZ)+tJDwcP84PR#y^AlaUrnJ=o8wPVA*9um<9Tt}2DA_cjLmVgZo{xFSf~WkJ*%$Ox zCZi2}pTMqX)H>`!w;vAW=J&sQ_;&O2E+{yVfbeqgFt9Gt1lIq5=q!%L_J6&QPDPOh zJX6)Ak|lsopz7=Bv>1^HQ4wDEGg9b&V;J18BW5Wn6Q^RQYvf*gJ=-t_p>;FtF z!>%V>CDTHOkf8Kcd{W%1SJnR4hPq>~!}EntoxRW_Z}RywU*YPKeue%GUER}VzRCX4 zR%2ky^fH1xZ@Px%xg(Eo&9Lc>*KQw*Rnu=8UHD4#h1D%L<2H6qX^o!AjSrzAu;>NL zgDTgfh=vk_ZhQFT3ymqd;q;J6JQearvcKwfkT4 zjfM8^P^l>yVtz7tQSxA^%dzUcm?f)<&hu(?r|WV?Lib5HstiP|{4Xa_@>>XTJ2+*P zd%f)eM1`t!MeIF35`-I-y1#$IpeTQ#KnOAu2B%=5JYT!4&9vM?jjQLusb7*{+aOi4dPFj2 zFDiI3a3k150b?p4V&NPbH`5%|&Dn(+tyC{89AXFkM#koI*{pO4e$OvJzkwd(nBf*7YO^H2$eB$>ukThXsCqekkDc2J&``wfxZa!ko6 z-ZZQ?`C)JX@^7XQbN^BbJRNg@;p|_bvsShaW_GqP8y;CZJD967@COVKp!oUbeWrKf z*w}VF_}sRdQ(MpWZr?eE`-B`JBDNz0s_}x~e4^^3($KG0;~z^1XCtWU5+n&91knz-Be5INqeN6PG<8 zJLL28VG|=Le6eOm%sMiaXV8_Qx|QJ0`Wtllv{@J9N{w-nb=(PufUwD!%Ien4^p9L7 z3R;QcO*$PhPPL7BX6(xxYc48R!>fPzspVhA$@fskq9na*Nah}LDY3)0?-7sArg?Ep zCLJPec`c+qj{ix4czK(ae3V)FV4al}TU+;WsOZE}*;Re}p$F~7E??2j4B8*5&=vLt z!f@C(bzMR%&cD!$Z6RoCr_5ihYMi%~9SP-NKd>&~wC?;aMKr#l74N>3!bc@!F+~-1 zex8fdsJ{`X#+2fU{M)VNP~Gkr6`R-Z9jN@p+Ninh)fp3vGiaD|w>HZ+^Ri_r6p!V- z;CWxIZ)_!{@ip6|KG(mS-I~Siz``5l6D&+D^dW~lK1aXecAkp(3!1S!Ux7T5QEq7O z8?|P3ePx&O+=ChIfim1^{9vaJ+wW0%k6~`&ST|ZOT*?{B#v~uW%@mW{mfjo`mC4(= zFo?$+FM-|_utOLxDzl3c8NMi{_|c8u?ZOO`NKyFk8x;PlGq?&?f>@;TiL|EJWN^0G z3m9+JBo0-XevG60@g$v-k{M&DGoOU6!vuHcYZ(>lh6$&WjTEFAiH_{3*r|3i&gBkm zKG2{9V!)r2$#|3dCeP1)z^Wj0Rm!~Ba4-U=k_=QyN*l<~Ar_K%Ta?0dljv0 zP0fBj0SGNU&5KZyBR6L!OgL6dKmf|6J6KWUFc>Ze{0T)vXgkqU8yGkxEMEt*L09Bkbd#)f-9u&AH7bfrWL?Z1tUkAH5GOP;C9~ zT{WsAeH%+?tQ{mqx@H~Q=1z6r7Uz5I@Mn#p6k`o}>MXrNrVn#u9`qlosRUnH?h?>h z>9oZ6eFzx7@hDvO^2TKS<<|*jJrTN|meTwn%Be$X;JxG-%+C{TX&qc3|HKl*WWvX&^pSIiH@Q`34XGBf;`rbFc zrK-CT?7~2qfKiURw(#pI{Bts`}m$2w$nBVMZtQ$%!>JG*MvDeO`{fx zxRgiOsyPRfu}R(_|UL^aqJ|BMjU5}BDC+>a7~0ZtH*XE(^pD+31>EE6D=v| z{viC=IvCs$m(iar>AQy>e@pj;SB#NT?=i#9hqCkqZ^_5yTaf#D*?pQZYJIi`ArxFW zctos=lF*N9#h3irweAei6PciksM{sxk5Sl0eic5PM^CMu6?m$aCKke^Arxe(E$l!d zmX=DdDhL@MQZRdwwh@(~bsAK&E%ueAy4+lyq<+Z^Uukm2_sCCgh{Rw!YPSIEm2P0Y!t=+G=CmS!Hq6HH z=U#p2P1O^*FV8Pbjx!ZZ9@#fW)`#E(Agr5M!gz=@1L8qg1O+082E~Q zuvE`ho(kfJL(aAC7LDQf6d^R9ZcEZa(c3GzUGEBJMm>50s}w#oD(H&10&(}}ev?Tw zp}6oONPiV0SY~k}rHe6V&BQ`l8X*r?lz6(=!+vFlk?$!@jxixSttbs);>F-pI%V}- zuiF+XVy{f&yzo|srKOUyl!rtAv58b1@qs=WhDCcqX~SR1 ze#kZS9ioom_3Gye6dPG+Kj(J9HFAw@@IEs%-OrU?EOP}XZg`r>T=iMZV(E2?=Zj8l zRZi(g)U85x=e@=*>nXpw9*@Ax-BuWC<;XSBO0c2QyY6ta?4!=LmAxycd&KVT)gVb= z+QkbPYefE+9&vgShKN4NltchOcEn=|vx3Ey&Wa)oYO=-O*a%&0rm)eL^T-y5o+-F`Z2}jp&YeS1s&`pet&TBJbZATE+3xp4 ztgZf*N36u!WVphrolEag>1aamrRCGCYqE}#jEXdb(wNf`8Fnuys)z{_8Py{3&>d}7 zH@joT8T&V^J|?*BKa%_$6i6oIYL00q{CY0z?F-Su48;VCpd!X4@%7=p)S2Qip;rPF z3uIbK7zyh&IWtxMw;qPVb{bPH0gi!g@Q+F8{a4EVkxnK6u&c_sR` z+O7!6f#}-eRn$9V?+>x(Fo__^=8l81EOhS&v#T53=B_Ge!*0$*{P64P(w`!aD##im zY2q75Ug*ozT$FQN^&ji%o!5d?a15aZqvlfkKR(B zy2+;x?CfA|jW>qYe?D<3K|M!;2KdSW(;tznB^jU>{ywl!fO*kh2LZ}g*^^&Xp|@nY zl+_e@jyh2Qb&y|0FQ5nmMR$&el=FdqLIuV+lD~@m{Vl`y#8&gWsH&`*vLaOT7PqP* zl7NCD1giX3)hH+@mE!=+2X+>KJMphN|J__5?a$BSq{N9n)JX|T*nJZ_Gkb?qMZuL3 z{VMraWjf%Zf7wm{Sv9yk*{SkD;PStxkx0hhQlIwdml7@kuY);Y000tv{5~>#YXHV| zWqGKYCY0O3#Q|KfAw5mwGH}a$fD6s=yBG>ehVO}L=&AFTgV~$?OP2-A%VDO&)&oW& z8KCrud&I9J!}k$zS^vd5wM7DEt=AQ8Bm;nVz~?mU0s)8x?ERZsofzqu`2Jo`f>{T{ zlkB&F3uFkKE7Pw=0Y5W*Xa3CkyLF~#6ItiKw&(z7+76s4>nWlKa4k=rDYA8d8`Xb8 zxpuVNrT|zjaMv!Kf>M(I5vu86_VDaBy4pJsngM6c4rDU8cnT**@h9BBNhgmpwD%zW z4M17s`rG0D7c9efnEGF&--?MpZ86}R0hW44!rn21VgD9>2h+d`;7A%8+nKaqiYfou z`M|2sNGg;AME%D@akfS@xW!;$UL>0qxV)#j&Og}yzA-1G2UzeG$sz*ghNoF)%fEtK z2Nn%Q66yIs#8VQYU=CPW6UmY12XoHQ*#zUjT75{Ij4%lIpEnjPM~CEO0#m0`7wjkJ zpW<}jR)IyikhHJjAlm5(`Pp|9ERBW4l}mteXA5P48wl18LJ}9GLBwCr#UGS}z+|v! z36k6{_XqNS-Waf40g^|n1mgYm9{q=S0k~=4Y|uy)w%VB}WNv6M3Y?4-iTa><77Ce& z^ykU`S87slW#HVE$jV5x|JTaS$Ycqw4xH!^S)I1d|5tTqcVcj=F(me~!CBb9$2enT z;xTYL!3lYgKyBl*fd5F(14e-pa3E1d=4YXPrQ-l|z@hs{PM!7HoYR5)U>-PV8p%W4 zKb!aG5Na?R94v=q|FA!s{g2Q&Fbo_PgM{h3oDBm9$$*Jq_j4ps(erHLZ)bEc3hbPV zMA`fN0rlHe7t8`XKq6UskI!Zy-66p&u)i6SB?>=_^+)eBFc|C`g9Oh7p9wz0QwGcg zyG|gPR8RlRJncvUW`a%ZNTy=gpP68TJD3W##UiQp5oc1*w9JC3U>g>a8W|0u{$7ur zVbKC(!S(?p_UZFKVgGC`0Mo&Hf=K#y{GaHjCnW#aAq2z0+e=9Jg{1!hetNU%#x)GU UgpPtD2z>DYYp}SJr5?)v0beu;=l}o! literal 0 HcmV?d00001 diff --git a/SDK/src/main/resources/javax.servlet-api.jar b/SDK/src/main/resources/javax.servlet-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..8161e88b90997cf904154544dfd2f022e46daf6e GIT binary patch literal 86333 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�(326VBVn=kclwd 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 Jdw_Uu1;s+9naEbs3qXDf$X#4OFk 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 literal 0 HcmV?d00001 diff --git a/SDK/src/queueit/knownuserv3/sdk/QueueITHelpers.java b/SDK/src/queueit/knownuserv3/sdk/QueueITHelpers.java deleted file mode 100644 index 6cd17ab..0000000 --- a/SDK/src/queueit/knownuserv3/sdk/QueueITHelpers.java +++ /dev/null @@ -1,215 +0,0 @@ -package queueit.knownuserv3.sdk; - -import java.util.AbstractCollection; -import java.util.Iterator; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -class Utils { - - public static boolean isNullOrWhiteSpace(String str) { - return str == null || str.trim().length() == 0; - } - - public static boolean isInteger(String value) { - try { - Integer.parseInt(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static boolean isLong(String value) { - try { - Long.parseLong(value); - return true; - } catch (NumberFormatException e) { - return false; - } - } - - public static String join(String delimiter, AbstractCollection s) { - if (s == null || s.isEmpty()) { - return ""; - } - Iterator iter = s.iterator(); - StringBuilder builder = new StringBuilder(iter.next()); - while (iter.hasNext()) { - builder.append(delimiter).append(iter.next()); - } - return builder.toString(); - } -} - -class QueueParameterHelper { - - public static final String TimeStampKey = "ts"; - public static final String ExtendableCookieKey = "ce"; - public static final String CookieValidityMinutesKey = "cv"; - public static final String HashKey = "h"; - public static final String QueueIdKey = "q"; - public static final String RedirectTypeKey = "rt"; - public static final String EventIdKey = "e"; - public static final String KeyValueSeparatorChar = "_"; - public static final String KeyValueSeparatorGroupChar = "~"; - - public static QueueUrlParams extractQueueParams(String queueitToken) { - try { - if (Utils.isNullOrWhiteSpace(queueitToken)) { - return null; - } - - QueueUrlParams result = new QueueUrlParams(); - result.setQueueITToken(queueitToken); - - String[] paramList = queueitToken.split(KeyValueSeparatorGroupChar); - for (String paramKeyValue : paramList) { - String[] keyValueArr = paramKeyValue.split(KeyValueSeparatorChar); - - if (TimeStampKey.equals(keyValueArr[0])) { - if (Utils.isLong(keyValueArr[1])) { - result.setTimeStamp(Long.parseLong(keyValueArr[1])); - } else { - result.setTimeStamp(0); - } - } else if (CookieValidityMinutesKey.equals(keyValueArr[0])) { - if (Utils.isInteger(keyValueArr[1])) { - result.setCookieValidityMinutes(Integer.parseInt(keyValueArr[1])); - } else { - result.setCookieValidityMinutes(null); - } - } else if (EventIdKey.equals(keyValueArr[0])) { - result.setEventId(keyValueArr[1]); - } else if (QueueIdKey.equals(keyValueArr[0])) { - result.setQueueId(keyValueArr[1]); - } else if (ExtendableCookieKey.equals(keyValueArr[0])) { - result.setExtendableCookie(Boolean.parseBoolean(keyValueArr[1])); - } else if (HashKey.equals(keyValueArr[0])) { - result.setHashCode(keyValueArr[1]); - } else if (RedirectTypeKey.equals(keyValueArr[0])) { - result.setRedirectType(keyValueArr[1]); - } - } - String queueITTokenWithoutHash = result.getQueueITToken().replace(KeyValueSeparatorGroupChar + HashKey + KeyValueSeparatorChar + result.getHashCode(), ""); - result.setQueueITTokenWithoutHash(queueITTokenWithoutHash); - return result; - } catch (Exception ex) { - return null; - } - } -} - -class HashHelper { - - public static String generateSHA256Hash(String secretKey, String stringToHash) throws Exception { - byte[] secretKeyBytes = secretKey.getBytes("UTF-8"); - SecretKeySpec signingKey = new SecretKeySpec(secretKeyBytes, "HmacSHA256"); - Mac mac = Mac.getInstance("HmacSHA256"); - mac.init(signingKey); - byte[] bytes = stringToHash.getBytes("UTF-8"); - byte[] rawHmac = mac.doFinal(bytes); - StringBuilder sb = new StringBuilder(); - for (byte b : rawHmac) { - sb.append(String.format("%1$02x", b)); - } - - return sb.toString(); - } -} - -class QueueUrlParams { - - private String eventId; - private String hashCode; - private boolean extendableCookie; - private String queueITToken; - private String queueITTokenWithoutHash; - private Integer cookieValidityMinutes; - private long timeStamp; - private String queueId; - private String redirectType; - - public QueueUrlParams() { - this.eventId = ""; - this.hashCode = ""; - this.extendableCookie = false; - this.queueITToken = ""; - this.queueITTokenWithoutHash = ""; - this.cookieValidityMinutes = null; - this.timeStamp = 0; - this.queueId = ""; - } - - public String getEventId() { - return this.eventId; - } - - public void setEventId(String eventId) { - this.eventId = eventId; - } - - public String getHashCode() { - return this.hashCode; - } - - public void setHashCode(String hashCode) { - this.hashCode = hashCode; - } - - public boolean getExtendableCookie() { - return this.extendableCookie; - } - - public void setExtendableCookie(boolean extendableCookie) { - this.extendableCookie = extendableCookie; - } - - public Integer getCookieValidityMinutes() { - return this.cookieValidityMinutes; - } - - public void setCookieValidityMinutes(Integer cookieValidityMinute) { - this.cookieValidityMinutes = cookieValidityMinute; - } - - public String getQueueITToken() { - return this.queueITToken; - } - - public void setQueueITToken(String queueITToken) { - this.queueITToken = queueITToken; - } - - public String getQueueITTokenWithoutHash() { - return this.queueITTokenWithoutHash; - } - - public void setQueueITTokenWithoutHash(String queueITTokenWithoutHash) { - this.queueITTokenWithoutHash = queueITTokenWithoutHash; - } - - public long getTimeStamp() { - return this.timeStamp; - } - - public void setTimeStamp(long timeStamp) { - this.timeStamp = timeStamp; - } - - public void setQueueId(String queueId) { - this.queueId = queueId; - } - - public String getQueueId() { - return this.queueId; - } - - public void setRedirectType(String redirectType) { - this.redirectType = redirectType; - } - - public String getRedirectType() { - return this.redirectType; - } -} diff --git a/SDK/src/test/java/queueit/knownuserv3/resources/hamcrest-core-1.3.jar b/SDK/src/test/java/queueit/knownuserv3/resources/hamcrest-core-1.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9d5fe16e3dd37ebe79a36f61f5d0e1a69a653a8a GIT binary patch literal 45024 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 UgpPtD2z>DYYp}SJr5?)v0beu;=l}o! literal 0 HcmV?d00001 diff --git a/SDK/src/test/java/queueit/knownuserv3/resources/javax.servlet-api.jar b/SDK/src/test/java/queueit/knownuserv3/resources/javax.servlet-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..8161e88b90997cf904154544dfd2f022e46daf6e GIT binary patch literal 86333 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�(326VBVn=kclwd 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 Jdw_Uu1;s+9naEbs3qXDf$X#4OFk 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 literal 0 HcmV?d00001 diff --git a/SDK/src/test/java/queueit/knownuserv3/sdk/HashHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/HashHelperTest.java new file mode 100644 index 0000000..8000d9e --- /dev/null +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/HashHelperTest.java @@ -0,0 +1,22 @@ +package queueit.knownuserv3.sdk; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +public class HashHelperTest { + + @Test + public void generateSHA256Hash() { + final String key = "528f01d4-30f9-4753-95b3-2c8c33966abc"; + final String stringToHash = "ts_1480593661~cv_10~ce_false~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~c_customerid~e_eventid~rt_disabled"; + + assertTrue(HashHelper.generateSHA256Hash(key, stringToHash).equals("286a17fb82009d8556465b2f0880a8e5e9565b42490669f4b8f1b93b7d6ddd51")); + } + + @Test + public void generateSHA256Hash_empty_value_to_hash() { + final String key = "528f01d4-30f9-4753-95b3-2c8c33966abc"; + final String stringToHash = ""; + + assertTrue(HashHelper.generateSHA256Hash(key, stringToHash).equals("eea56ce827b37369656f502c5a418cce5959d078ef2993589274ed7b26828d8b")); + } +} diff --git a/SDK/src/test/java/queueit/knownuserv3/sdk/KnownUserTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/KnownUserTest.java new file mode 100644 index 0000000..af6225d --- /dev/null +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/KnownUserTest.java @@ -0,0 +1,2891 @@ +package queueit.knownuserv3.sdk; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletOutputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Test; + +import queueit.knownuserv3.sdk.UserInQueueServiceTest.QueueITTokenGenerator; +import queueit.knownuserv3.sdk.integrationconfig.CustomerIntegration; +import queueit.knownuserv3.sdk.integrationconfig.IntegrationConfigModel; +import queueit.knownuserv3.sdk.integrationconfig.TriggerModel; +import queueit.knownuserv3.sdk.integrationconfig.TriggerPart; + +public class KnownUserTest { + + class UserInQueueServiceMock implements IUserInQueueService { + + public ArrayList> validateQueueRequestCalls = new ArrayList>(); + public boolean validateQueueRequestRaiseException = false; + public ArrayList> validateCancelRequestCalls = new ArrayList>(); + public boolean validateCancelRequestRaiseException = false; + public ArrayList> extendQueueCookieCalls = new ArrayList>(); + public ArrayList> getIgnoreActionResultCalls = new ArrayList>(); + + @Override + public RequestValidationResult validateQueueRequest(String targetUrl, String queueitToken, + QueueEventConfig config, String customerId, String secretKey) throws Exception { + ArrayList args = new ArrayList(); + args.add(targetUrl); + args.add(queueitToken); + args.add(config.getCookieDomain() + ":" + config.getLayoutName() + ":" + config.getCulture() + ":" + + config.getEventId() + ":" + config.getQueueDomain() + ":" + config.getExtendCookieValidity() + ":" + + config.getCookieValidityMinute() + ":" + config.getVersion() + ":" + config.getActionName()); + args.add(customerId); + args.add(secretKey); + validateQueueRequestCalls.add(args); + + if(this.validateQueueRequestRaiseException == true ){ + throw new Exception("exception"); + } + else{ + return new RequestValidationResult("Queue", "", "", "", "", ""); + } +} + + @Override + public RequestValidationResult validateCancelRequest(String targetUrl, CancelEventConfig config, + String customerId, String secretKey) throws Exception { + + ArrayList args = new ArrayList(); + args.add(targetUrl); + args.add(config.getCookieDomain() + ":" + config.getEventId() + ":" + config.getQueueDomain() + ":" + + config.getVersion() + ":" + config.getActionName()); + args.add(customerId); + args.add(secretKey); + validateCancelRequestCalls.add(args); + + if(this.validateCancelRequestRaiseException == true ){ + throw new Exception("exception"); + } + else{ + return new RequestValidationResult("Cancel", "", "", "", "", ""); + } + } + + @Override + public void extendQueueCookie(String eventId, int cookieValidityMinute, String cookieDomain, String secretKey) { + ArrayList args = new ArrayList(); + args.add(eventId); + args.add(Integer.toString(cookieValidityMinute)); + args.add(cookieDomain); + args.add(secretKey); + extendQueueCookieCalls.add(args); + } + + @Override + public RequestValidationResult getIgnoreActionResult(String actionName) { + ArrayList args = new ArrayList(); + args.add(actionName); + getIgnoreActionResultCalls.add(args); + return new RequestValidationResult("Ignore", "", "", "", "", ""); + } + } + + @Test + public void cancelRequestByLocalConfigTest() throws Exception { + // Arrange + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, + "customerid", requestMock, responseMock, "secretkey"); + + // Assert + assertTrue("url".equals(mock.validateCancelRequestCalls.get(0).get(0))); + assertTrue("cookiedomain:eventid:queuedomain:1:cancelAction" + .equals(mock.validateCancelRequestCalls.get(0).get(1))); + assertTrue("customerid".equals(mock.validateCancelRequestCalls.get(0).get(2))); + assertTrue("secretkey".equals(mock.validateCancelRequestCalls.get(0).get(3))); + assertFalse(result.isAjaxResult); + } + + @Test + public void CancelRequestByLocalConfig_AjaxCall_Test() throws Exception { + // Arrange + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, + "customerid", requestMock, null, "secretkey"); + + // Assert + assertTrue("http://url".equals(mock.validateCancelRequestCalls.get(0).get(0))); + assertTrue("cookiedomain:eventid:queuedomain:1:cancelAction" + .equals(mock.validateCancelRequestCalls.get(0).get(1))); + assertTrue("customerid".equals(mock.validateCancelRequestCalls.get(0).get(2))); + assertTrue("secretkey".equals(mock.validateCancelRequestCalls.get(0).get(3))); + assertTrue(result.isAjaxResult); + } + + @Test + public void cancelRequestByLocalConfigDebugCookieLoggingTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "requestUrl"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", false, null, secretKey, "debug"); + + KnownUser.cancelRequestByLocalConfig("url", queueittoken, cancelEventConfig, "customerId", requestMock, + responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("CancelConfig=EventId:eventid")); + assertTrue(decodedCookieValue.contains("&Version:1")); + assertTrue(decodedCookieValue.contains("&QueueDomain:queuedomain")); + assertTrue(decodedCookieValue.contains("&CookieDomain:cookiedomain")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("TargetUrl=url")); + assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); + assertTrue( + decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); + assertTrue(decodedCookieValue.contains("&ActionName:cancelAction")); + } + + @Test + public void cancelRequestByLocalConfigNullQueueDomainTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setCookieDomain("cookieDomain"); + cancelEventConfig.setVersion(12); + + // Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "QueueDomain from cancelConfig can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void cancelRequestByLocalConfigEventIdNullTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("domain"); + cancelEventConfig.setVersion(12); + + // Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "EventId from cancelConfig can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void cancelRequestByLocalConfigCancelEventConfigNullTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "cancelConfig can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void cancelRequestByLocalConfigCustomerIdNullTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", new CancelEventConfig(), null, + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "customerId can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void cancelRequestByLocalConfigSecretKeyNullTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", new CancelEventConfig(), "customerId", + new HttpServletRequestMock(), null, null); + } catch (Exception ex) { + exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void CancelRequestByLocalConfigTargetUrlNullTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.cancelRequestByLocalConfig(null, "queueitToken", new CancelEventConfig(), "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "targetUrl can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void extendQueueCookieNullEventIdTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.extendQueueCookie(null, 0, null, null, null, null); + } catch (Exception ex) { + exceptionWasThrown = "eventId can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.extendQueueCookieCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void extendQueueCookieInvalidCookieValidityMinutesTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.extendQueueCookie("eventId", 0, null, null, null, null); + } catch (Exception ex) { + exceptionWasThrown = "cookieValidityMinute should be greater than 0.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.extendQueueCookieCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void extendQueueCookieNullSecretKeyTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.extendQueueCookie("eventId", 20, null, null, null, null); + } catch (Exception ex) { + exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.extendQueueCookieCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void extendQueueCookieTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + // Act + KnownUser.extendQueueCookie("eventId", 20, "cookieDomain", null, null, "secretKey"); + + // Assert + assertTrue("eventId".equals(mock.extendQueueCookieCalls.get(0).get(0))); + assertTrue("20".equals(mock.extendQueueCookieCalls.get(0).get(1))); + assertTrue("cookieDomain".equals(mock.extendQueueCookieCalls.get(0).get(2))); + assertTrue("secretKey".equals(mock.extendQueueCookieCalls.get(0).get(3))); + } + + @Test + public void resolveQueueRequestByLocalConfigNullCustomerIdTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, null, + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "customerId can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigNullSecretKeyTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", + new HttpServletRequestMock(), null, null); + } catch (Exception ex) { + exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigNullEventConfigTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "eventConfig can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigNullEventIdTest() { + + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "EventId from queueConfig can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigNullQueueDomainTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + eventConfig.setActionName("queueAction"); + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "QueueDomain from queueConfig can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigInvalidCookieValidityMinuteTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setVersion(12); + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", + new HttpServletRequestMock(), null, "secretKey"); + } catch (Exception ex) { + exceptionWasThrown = "cookieValidityMinute from queueConfig should be greater than 0." + .equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void resolveQueueRequestByLocalConfigTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + eventConfig.setActionName("queueAction"); + // Act + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", + eventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue("targetUrl".equals(mock.validateQueueRequestCalls.get(0).get(0))); + assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); + assertTrue("cookieDomain:layoutName:culture:eventId:queueDomain:true:10:12:queueAction" + .equals(mock.validateQueueRequestCalls.get(0).get(2))); + assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); + assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); + assertFalse(result.isAjaxResult); + } + + @Test + public void resolveQueueRequestByLocalConfigAjaxCallTest() throws Exception { + // Arrange + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + eventConfig.setActionName("queueAction"); + + // Act + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", + eventConfig, "customerId", requestMock, null, "secretKey"); + + // Assert + assertTrue("http://url".equals(mock.validateQueueRequestCalls.get(0).get(0))); + assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); + assertTrue("cookieDomain:layoutName:culture:eventId:queueDomain:true:10:12:queueAction" + .equals(mock.validateQueueRequestCalls.get(0).get(2))); + assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); + assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); + assertTrue(result.isAjaxResult); + } + + @Test + public void resolveQueueRequestByLocalConfigDebugCookieLoggingTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig queueConfig = new QueueEventConfig(); + queueConfig.setCookieDomain("cookieDomain"); + queueConfig.setLayoutName("layoutName"); + queueConfig.setCulture("culture"); + queueConfig.setEventId("eventId"); + queueConfig.setQueueDomain("queueDomain"); + queueConfig.setExtendCookieValidity(true); + queueConfig.setCookieValidityMinute(10); + queueConfig.setVersion(12); + queueConfig.setActionName("queueAction"); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "requestUrl"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", false, null, secretKey, "debug"); + + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", queueittoken, queueConfig, "customerId", requestMock, + responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("QueueConfig=EventId:eventId")); + assertTrue(decodedCookieValue.contains("&Version:12")); + assertTrue(decodedCookieValue.contains("&QueueDomain:queueDomain")); + assertTrue(decodedCookieValue.contains("&CookieDomain:cookieDomain")); + assertTrue(decodedCookieValue.contains("&ExtendCookieValidity:true")); + assertTrue(decodedCookieValue.contains("&CookieValidityMinute:10")); + assertTrue(decodedCookieValue.contains("&LayoutName:layoutName")); + assertTrue(decodedCookieValue.contains("&Culture:culture")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("TargetUrl=targetUrl")); + assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); + assertTrue( + decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); + assertTrue(decodedCookieValue.contains("&ActionName:" + queueConfig.getActionName())); + } + + @Test + public void validateRequestByIntegrationConfigEmptyCurrentUrlTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.validateRequestByIntegrationConfig("", null, null, null, null, null, null); + } catch (Exception ex) { + exceptionWasThrown = "currentUrlWithoutQueueITToken can not be null or empty.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void validateRequestByIntegrationConfigEmptyIntegrationsConfigTest() { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + // Act + try { + KnownUser.validateRequestByIntegrationConfig("currentUrl", "queueitToken", null, null, + new HttpServletRequestMock(), null, null); + } catch (Exception ex) { + exceptionWasThrown = "customerIntegrationInfo can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(exceptionWasThrown); + } + + @Test + public void validateRequestByIntegrationConfigQueueActionTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerPart triggerPart2 = new TriggerPart(); + triggerPart2.Operator = "Contains"; + triggerPart2.ValueToCompare = "googlebot"; + triggerPart2.ValidatorType = "UserAgentValidator"; + triggerPart2.IsNegative = false; + triggerPart2.IsIgnoreCase = false; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1, triggerPart2 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + HttpServletRequestMock httpContextMock = new HttpServletRequestMock(); + httpContextMock.UserAgent = "googlebot"; + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", httpContextMock, null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() == 1); + assertTrue("http://test.com?event1=true".equals(mock.validateQueueRequestCalls.get(0).get(0))); + assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); + assertTrue( + ".test.com:Christmas Layout by Queue-it:da-DK:event1:knownusertest.queue-it.net:true:20:3:event1action" + .equals(mock.validateQueueRequestCalls.get(0).get(2))); + assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); + assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); + assertFalse(result.isAjaxResult); + } + + @Test + public void validateRequestByIntegrationConfigQueueActionAjaxCallTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerPart triggerPart2 = new TriggerPart(); + triggerPart2.Operator = "Contains"; + triggerPart2.ValueToCompare = "googlebot"; + triggerPart2.ValidatorType = "UserAgentValidator"; + triggerPart2.IsNegative = false; + triggerPart2.IsIgnoreCase = false; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1, triggerPart2 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.UserAgent = "googlebot"; + requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() == 1); + assertTrue("http://url".equals(mock.validateQueueRequestCalls.get(0).get(0))); + assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); + assertTrue( + ".test.com:Christmas Layout by Queue-it:da-DK:event1:knownusertest.queue-it.net:true:20:3:event1action" + .equals(mock.validateQueueRequestCalls.get(0).get(2))); + assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); + assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); + assertTrue(result.isAjaxResult); + } + + @Test + public void validateRequestByIntegrationConfigDebugCookieLoggingTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + // region + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerPart triggerPart2 = new TriggerPart(); + triggerPart2.Operator = "Contains"; + triggerPart2.ValueToCompare = "googlebot"; + triggerPart2.ValidatorType = "UserAgentValidator"; + triggerPart2.IsNegative = false; + triggerPart2.IsIgnoreCase = false; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1, triggerPart2 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.UserAgent = "googlebot"; + requestMock.RequestURL = "requestUrl"; + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, 20, secretKey, "debug"); + + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("ConfigVersion=3")); + assertTrue(decodedCookieValue.contains("QueueConfig=EventId:event1")); + assertTrue(decodedCookieValue.contains("&Version:3")); + assertTrue(decodedCookieValue.contains("&QueueDomain:knownusertest.queue-it.net")); + assertTrue(decodedCookieValue.contains("&CookieDomain:.test.com")); + assertTrue(decodedCookieValue.contains("&ExtendCookieValidity:true")); + assertTrue(decodedCookieValue.contains("&CookieValidityMinute:20")); + assertTrue(decodedCookieValue.contains("&LayoutName:Christmas Layout by Queue-it")); + assertTrue(decodedCookieValue.contains("&Culture:da-DK")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("TargetUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("MatchedConfig=event1action")); + assertTrue(decodedCookieValue.contains("&ActionName:" + config.Name)); + } + + @Test + public void validateRequestByIntegrationConfigNotMatchTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[0]; + customerIntegration.Version = 3; + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.isEmpty()); + assertTrue(!result.doRedirect()); + } + + @Test + public void validateRequestByIntegrationConfigNotMatchDebugCookieLoggingTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[0]; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "requestUrl"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, 20, secretKey, "debug"); + + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueittoken, customerIntegration, + "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("ConfigVersion=3")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); + assertTrue( + decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); + assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); + } + + @Test + public void validateRequestByIntegrationConfigForcedTargeturlTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "ForcedTargetUrl"; + config.ForcedTargetUrl = "http://forcedtargeturl.com"; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + // Act + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, + "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() == 1); + assertTrue("http://forcedtargeturl.com".equals(mock.validateQueueRequestCalls.get(0).get(0))); + } + + @Test + public void validateRequestByIntegrationConfigForecedTargeturlTest() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "ForecedTargetUrl"; + config.ForcedTargetUrl = "http://forcedtargeturl.com"; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + // Act + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, + "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() == 1); + assertTrue("http://forcedtargeturl.com".equals(mock.validateQueueRequestCalls.get(0).get(0))); + } + + @Test + public void validateRequestByIntegrationConfigEventTargetUrl() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "EventTargetUrl"; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + // Act + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, + "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() == 1); + assertTrue("".equals(mock.validateQueueRequestCalls.get(0).get(0))); + } + + @Test + public void validateRequestByIntegrationConfigIgnoreAction() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = "cookiedomain"; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "queuedomain"; + config.ActionType = ActionType.IGNORE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue(mock.getIgnoreActionResultCalls.size() == 1); + assertFalse(result.isAjaxResult); + assertTrue(mock.getIgnoreActionResultCalls.get(0).get(0) == config.Name); + + } + + @Test + public void validateRequestByIntegrationConfigAjaxCallIgnoreAction() throws Exception { + // Arrange + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = "cookiedomain"; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "queuedomain"; + config.ActionType = ActionType.IGNORE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.Headers.put("x-queueit-ajaxpageurl", "url"); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); + + // Assert + assertTrue(mock.getIgnoreActionResultCalls.size() == 1); + assertTrue(result.isAjaxResult); + assertTrue(mock.getIgnoreActionResultCalls.get(0).get(0) == config.Name); + } + + @Test + public void validateRequestByIntegrationConfigCancelAction() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = "cookiedomain"; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "queuedomain"; + config.ActionType = ActionType.CANCEL_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); + + // Assert + assertTrue("http://test.com?event1=true".equals(mock.validateCancelRequestCalls.get(0).get(0))); + assertTrue( + "cookiedomain:event1:queuedomain:3:event1action".equals(mock.validateCancelRequestCalls.get(0).get(1))); + assertTrue("customerId".equals(mock.validateCancelRequestCalls.get(0).get(2))); + assertTrue("secretKey".equals(mock.validateCancelRequestCalls.get(0).get(3))); + assertFalse(result.isAjaxResult); + } + + @Test + public void validateRequestByIntegrationConfigAjaxCallCancelAction() throws Exception { + // Arrange + TriggerPart triggerPart = new TriggerPart(); + triggerPart.Operator = "Contains"; + triggerPart.ValueToCompare = "event1"; + triggerPart.UrlPart = "PageUrl"; + triggerPart.ValidatorType = "UrlValidator"; + triggerPart.IsNegative = false; + triggerPart.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = "cookiedomain"; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "queuedomain"; + config.ActionType = ActionType.CANCEL_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + // Act + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); + + // Assert + assertTrue("http://url".equals(mock.validateCancelRequestCalls.get(0).get(0))); + assertTrue( + "cookiedomain:event1:queuedomain:3:event1action".equals(mock.validateCancelRequestCalls.get(0).get(1))); + assertTrue("customerId".equals(mock.validateCancelRequestCalls.get(0).get(2))); + assertTrue("secretKey".equals(mock.validateCancelRequestCalls.get(0).get(3))); + assertTrue(result.isAjaxResult); + } + + @Test + public void validateRequestByIntegrationConfig_Debug() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.UserAgent = "googlebot"; + requestMock.RequestURL = "requestUrl"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, 20, secretKey, "debug"); + + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("ConfigVersion=3")); + assertTrue(decodedCookieValue.contains("MatchedConfig=event1action")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("TargetUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("QueueConfig=EventId:event1")); + assertTrue(decodedCookieValue.contains("&Version:3")); + assertTrue(decodedCookieValue.contains("&QueueDomain:knownusertest.queue-it.net")); + assertTrue(decodedCookieValue.contains("&CookieDomain:.test.com")); + assertTrue(decodedCookieValue.contains("&ExtendCookieValidity:true")); + assertTrue(decodedCookieValue.contains("&CookieValidityMinute:20")); + assertTrue(decodedCookieValue.contains("&LayoutName:Christmas Layout by Queue-it")); + assertTrue(decodedCookieValue.contains("&Culture:da-DK")); + assertTrue(decodedCookieValue.contains("&ActionName:" + config.Name)); + assertTrue(decodedCookieValue.contains("SdkVersion=v3-java-3.6.0")); + assertTrue(decodedCookieValue.contains("Runtime=" + GetRuntimeVersion())); + } + + @Test + public void ValidateRequestByIntegrationConfig_Debug_WithoutMatch() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] {}; + customerIntegration.Version = 10; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "http://test.com/?event1=true&queueittoken=queueittokenvalue"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + // endregion + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("ConfigVersion=10")); + assertTrue( + decodedCookieValue.contains("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")); + assertTrue(decodedCookieValue.contains("MatchedConfig=NULL")); + assertTrue(decodedCookieValue.contains("SdkVersion=v3-java-3.6.0")); + assertTrue(decodedCookieValue.contains("Runtime=" + GetRuntimeVersion())); + } + + @Test + public void ValidateRequestByIntegrationConfig_Exception_NoDebugToken_NoDebugCookie() throws Exception { + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + //region + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerPart triggerPart2 = new TriggerPart(); + triggerPart2.Operator = "Contains"; + triggerPart2.ValueToCompare = "googlebot"; + triggerPart2.ValidatorType = "UserAgentValidator"; + triggerPart2.IsNegative = false; + triggerPart2.IsIgnoreCase = false; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1, triggerPart2 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + config.ActionType = ActionType.QUEUE_ACTION; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + //endregion + + HttpServletRequestMock httpContextMock = new HttpServletRequestMock(); + httpContextMock.UserAgent = "googlebot"; + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + mock.validateQueueRequestRaiseException = true; + + // Act + try { + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + "queueitToken", customerIntegration, "customerId", httpContextMock, responseMock, "secretKey"); + } catch (Exception ex) { + assertTrue("exception".equals(ex.getMessage())); + } + + // Assert + assertTrue(responseMock.addedCookies.size() == 0); + assertTrue(mock.validateQueueRequestCalls.size() > 0); + } + + @Test + public void ResolveQueueRequestByLocalConfigTest_Exception_NoDebugToken_NoDebugCookie() throws Exception { + + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + HttpServletRequestMock httpContextMock = new HttpServletRequestMock(); + httpContextMock.UserAgent = "googlebot"; + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + eventConfig.setActionName("queueAction"); + + mock.validateQueueRequestRaiseException = true; + + // Act + try { + KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", + eventConfig, "customerId", new HttpServletRequestMock(), responseMock, "secretKey"); + } + catch (Exception ex) { + assertTrue("exception".equals(ex.getMessage())); + } + + // Assert + assertTrue(mock.validateQueueRequestCalls.size() > 0); + assertTrue(responseMock.addedCookies.size() == 0); + } + + @Test + public void CancelRequestByLocalConfig_Exception_NoDebugToken_NoDebugCookie() + { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + HttpServletRequestMock httpContextMock = new HttpServletRequestMock(); + httpContextMock.UserAgent = "googlebot"; + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + mock.validateQueueRequestRaiseException = true; + + //Act + try { + KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerid", requestMock, responseMock, "secretkey"); + } + catch (Exception ex) { + assertTrue("exception".equals(ex.getMessage())); + } + + // Assert + assertTrue(mock.validateCancelRequestCalls.size() > 0); + assertTrue(responseMock.addedCookies.size() == 0); + } + + @Test + public void validateRequestByIntegrationConfig_Debug_NullConfig() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1 }; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + requestMock.RequestURL = "requestUrl"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, 20, secretKey, "debug"); + + try { + KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueittoken, null, + "customerId", requestMock, responseMock, secretKey); + } catch (Exception ex) { + exceptionWasThrown = "customerIntegrationInfo can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(exceptionWasThrown); + assertTrue(responseMock.addedCookies.size() == 1); + assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("SdkVersion=" + UserInQueueService.SDK_VERSION)); + assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains("ConfigVersion=NULL")); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); + assertTrue(decodedCookieValue.contains("SdkVersion=v3-java-3.6.0")); + assertTrue(decodedCookieValue.contains("Runtime=" + GetRuntimeVersion())); + assertTrue(decodedCookieValue.contains("Exception=customerIntegrationInfo can not be null.")); + + } + + @Test + public void ValidateRequestByIntegrationConfig_Debug_Missing_CustomerId() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + + // Act + String secretKey = "secretKey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, null, requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ValidateRequestByIntegrationConfig_Debug_Missing_Secretkey() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + + // Act + String secretKey = "secretKey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, null); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + + } + + @Test + public void ValidateRequestByIntegrationConfig_Debug_ExpiredToken() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + + // Act + String secretKey = "secretKey"; + Date date = new Date(); + date = addDays(date, -1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ValidateRequestByIntegrationConfig_Debug_ModifiedToken() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CustomerIntegration customerIntegration = new CustomerIntegration(); + + // Act + String secretKey = "secretKey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug") + "invalid-hash"; + + RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", + queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug() throws Exception { + + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "http://test.com/?event1=true&queueittoken=queueittokenvalue"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setEventId("eventId"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + eventConfig.setActionName("QueueAction"); + + // Act + String secretKey = "secretKey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", + queueittoken, eventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue( + decodedCookieValue.contains("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")); + assertTrue(decodedCookieValue.contains("TargetUrl=http://test.com?event1=true")); + assertTrue(decodedCookieValue.contains( + "QueueConfig=EventId:eventId&Version:12&QueueDomain:queueDomain&CookieDomain:cookieDomain&ExtendCookieValidity:true&CookieValidityMinute:10&LayoutName:layoutName&Culture:culture&ActionName:" + + eventConfig.getActionName())); + assertTrue(decodedCookieValue.contains("SdkVersion=v3-java-3.6.0")); + assertTrue(decodedCookieValue.contains("Runtime=" + GetRuntimeVersion())); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug_NullConfig() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1 }; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "http://test.com/?event1=true&queueittoken=queueittokenvalue"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + try { + KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", queueittoken, null, "customerId", + requestMock, responseMock, secretKey); + } catch (Exception ex) { + exceptionWasThrown = "eventConfig can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(exceptionWasThrown); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue( + decodedCookieValue.contains("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")); + assertTrue(decodedCookieValue.contains("QueueConfig=NULL")); + assertTrue(decodedCookieValue.contains("Exception=eventConfig can not be null.")); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug_Missing_CustomerId() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setEventId("event1"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, -1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", + queueittoken, eventConfig, null, requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug_Missing_SecretKey() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setEventId("event1"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, -1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", + queueittoken, eventConfig, "customerId", requestMock, responseMock, null); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug_ExpiredToken() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setEventId("event1"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, -1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", + queueittoken, eventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void ResolveQueueRequestByLocalConfig_Debug_ModifiedToken() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + QueueEventConfig eventConfig = new QueueEventConfig(); + eventConfig.setCookieDomain("cookieDomain"); + eventConfig.setLayoutName("layoutName"); + eventConfig.setCulture("culture"); + eventConfig.setQueueDomain("queueDomain"); + eventConfig.setExtendCookieValidity(true); + eventConfig.setCookieValidityMinute(10); + eventConfig.setVersion(12); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug") + "invalid-hash"; + + RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("http://test.com?event1=true", + queueittoken, eventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void CancelRequestByLocalConfig_Debug() throws Exception { + + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1 }; + + IntegrationConfigModel config = new IntegrationConfigModel(); + config.Name = "event1action"; + config.EventId = "event1"; + config.CookieDomain = ".test.com"; + config.LayoutName = "Christmas Layout by Queue-it"; + config.Culture = "da-DK"; + config.ExtendCookieValidity = true; + config.CookieValidityMinute = 20; + config.Triggers = new TriggerModel[] { trigger }; + config.QueueDomain = "knownusertest.queue-it.net"; + config.RedirectLogic = "AllowTParameter"; + config.ForcedTargetUrl = ""; + + CustomerIntegration customerIntegration = new CustomerIntegration(); + customerIntegration.Integrations = new IntegrationConfigModel[] { config }; + customerIntegration.Version = 3; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "http://test.com/?event1=true&queueittoken=queueittokenvalue"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventId"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(12); + cancelEventConfig.setActionName("cancelAction"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, null, secretKey, "debug"); + + KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, cancelEventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(responseMock.addedCookies.size() == 1); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue( + decodedCookieValue.contains("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")); + assertTrue(decodedCookieValue.contains("TargetUrl=http://test.com?event1=true")); + + String configvalues = "CancelConfig=EventId:eventId&Version:12&QueueDomain:queuedomain&CookieDomain:cookiedomain&ActionName:" + + cancelEventConfig.getActionName(); + assertTrue(decodedCookieValue.contains(configvalues)); + } + + @Test + public void CancelRequestByLocalConfig_Debug_NullConfig() throws Exception { + // Arrange + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + boolean exceptionWasThrown = false; + + TriggerPart triggerPart1 = new TriggerPart(); + triggerPart1.Operator = "Contains"; + triggerPart1.ValueToCompare = "event1"; + triggerPart1.UrlPart = "PageUrl"; + triggerPart1.ValidatorType = "UrlValidator"; + triggerPart1.IsNegative = false; + triggerPart1.IsIgnoreCase = true; + + TriggerModel trigger = new TriggerModel(); + trigger.LogicalOperator = "And"; + trigger.TriggerParts = new TriggerPart[] { triggerPart1 }; + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.RequestURL = "http://test.com/?event1=true&queueittoken=queueittokenvalue"; + requestMock.RemoteAddr = "80.35.35.34"; + requestMock.Headers.put("via", "1.1 example.com"); + requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); + requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); + requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); + requestMock.Headers.put("x-forwarded-proto", "https"); + + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "eventId", true, null, secretKey, "debug"); + + try { + KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, null, "customerId", requestMock, responseMock, secretKey); + } catch (Exception ex) { + exceptionWasThrown = "cancelConfig can not be null.".equals(ex.getMessage()); + } + + // Assert + assertTrue(exceptionWasThrown); + assertTrue(responseMock.addedCookies.size() == 1); + String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); + assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); + assertTrue( + decodedCookieValue.contains("OriginalUrl=http://test.com/?event1=true&queueittoken=queueittokenvalue")); + assertTrue(decodedCookieValue.contains("CancelConfig=NULL")); + assertTrue(decodedCookieValue.contains("SdkVersion=v3-java-3.6.0")); + assertTrue(decodedCookieValue.contains("Runtime=" + GetRuntimeVersion())); + assertTrue(decodedCookieValue.contains("Exception=cancelConfig can not be null.")); + } + + @Test + public void CancelRequestByLocalConfig_Debug_Missing_CustomerId() throws Exception { + + // Assert + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("event1"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, cancelEventConfig, null, requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void CancelRequestByLocalConfig_Debug_Missing_SecretKey() throws Exception { + + // Assert + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("event1"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, 1); + + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, cancelEventConfig, "customerId", requestMock, responseMock, null); + + // Assert + assertTrue(result.getRedirectUrl().equals("https://api2.queue-it.net/diagnostics/connector/error/?code=setup")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void CancelRequestByLocalConfig_Debug_ExpiredToken() throws Exception { + + // Arrange + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + date = addDays(date, -1); + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug"); + + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, cancelEventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=timestamp")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + @Test + public void CancelRequestByLocalConfig_Debug_ModifiedToken() throws Exception { + + // Assert + HttpServletResponseMock responseMock = new HttpServletResponseMock(); + + HttpServletRequestMock requestMock = new HttpServletRequestMock(); + requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); + + UserInQueueServiceMock mock = new UserInQueueServiceMock(); + KnownUser.setUserInQueueService(mock); + + CancelEventConfig cancelEventConfig = new CancelEventConfig(); + cancelEventConfig.setCookieDomain("cookiedomain"); + cancelEventConfig.setEventId("eventid"); + cancelEventConfig.setQueueDomain("queuedomain"); + cancelEventConfig.setVersion(1); + cancelEventConfig.setActionName("cancelAction"); + + // Act + String secretKey = "secretkey"; + Date date = new Date(); + String queueittoken = QueueITTokenGenerator.generateToken(date, "event1", true, null, secretKey, "debug") + + "invalid-hash"; + + RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("http://test.com?event1=true", + queueittoken, cancelEventConfig, "customerId", requestMock, responseMock, secretKey); + + // Assert + assertTrue(result.getRedirectUrl() + .equals("https://customerId.api2.queue-it.net/customerId/diagnostics/connector/error/?code=hash")); + assertTrue(responseMock.addedCookies.isEmpty()); + } + + class HttpServletRequestMock implements HttpServletRequest { + + public Cookie[] CookiesValue; + public String UserAgent; + public String RequestURL; + public String QueryString; + public String RemoteAddr; + public HashMap Headers; + + public HttpServletRequestMock() { + this.Headers = new HashMap(); + } + + @Override + public String getAuthType() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Cookie[] getCookies() { + return this.CookiesValue; + } + + @Override + public long getDateHeader(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getHeader(String key) { + if ("User-Agent".equals(key)) { + return this.UserAgent; + } + + String value = (String) this.Headers.get(key); + + if (value == null) { + value = ""; + } + + return value; + } + + @Override + public Enumeration getHeaders(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Enumeration getHeaderNames() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getIntHeader(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getMethod() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getPathInfo() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getPathTranslated() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getContextPath() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getQueryString() { + return this.QueryString; + } + + @Override + public String getRemoteUser() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isUserInRole(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Principal getUserPrincipal() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getRequestedSessionId() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getRequestURI() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public StringBuffer getRequestURL() { + return new StringBuffer(this.RequestURL); + } + + @Override + public String getServletPath() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public HttpSession getSession(boolean bln) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public HttpSession getSession() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isRequestedSessionIdValid() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isRequestedSessionIdFromCookie() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isRequestedSessionIdFromURL() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isRequestedSessionIdFromUrl() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean authenticate(HttpServletResponse hsr) throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void login(String string, String string1) throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void logout() throws ServletException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Collection getParts() throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Part getPart(String string) throws IOException, ServletException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Object getAttribute(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Enumeration getAttributeNames() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getCharacterEncoding() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setCharacterEncoding(String string) throws UnsupportedEncodingException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getContentLength() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getContentType() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public ServletInputStream getInputStream() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getParameter(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Enumeration getParameterNames() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String[] getParameterValues(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Map getParameterMap() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getProtocol() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getScheme() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getServerName() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getServerPort() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public BufferedReader getReader() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getRemoteAddr() { + return RemoteAddr; + } + + @Override + public String getRemoteHost() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setAttribute(String string, Object o) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void removeAttribute(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Locale getLocale() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Enumeration getLocales() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isSecure() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public RequestDispatcher getRequestDispatcher(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getRealPath(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getRemotePort() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getLocalName() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getLocalAddr() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getLocalPort() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public ServletContext getServletContext() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public AsyncContext startAsync() throws IllegalStateException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public AsyncContext startAsync(ServletRequest sr, ServletResponse sr1) throws IllegalStateException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isAsyncStarted() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isAsyncSupported() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public AsyncContext getAsyncContext() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public DispatcherType getDispatcherType() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + } + + class HttpServletResponseMock implements HttpServletResponse { + + ArrayList addedCookies = new ArrayList(); + + @Override + public void addCookie(Cookie cookie) { + addedCookies.add(cookie); + } + + @Override + public boolean containsHeader(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String encodeURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String encodeRedirectURL(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String encodeUrl(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String encodeRedirectUrl(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void sendError(int i, String string) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void sendError(int i) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void sendRedirect(String string) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setDateHeader(String string, long l) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void addDateHeader(String string, long l) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setHeader(String string, String string1) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void addHeader(String string, String string1) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setIntHeader(String string, int i) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void addIntHeader(String string, int i) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setStatus(int i) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setStatus(int i, String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getStatus() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getHeader(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Collection getHeaders(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Collection getHeaderNames() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getCharacterEncoding() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public String getContentType() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public PrintWriter getWriter() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setCharacterEncoding(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setContentLength(int i) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setContentType(String string) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setBufferSize(int i) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public int getBufferSize() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void flushBuffer() throws IOException { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void resetBuffer() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public boolean isCommitted() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void reset() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public void setLocale(Locale locale) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + + @Override + public Locale getLocale() { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. + } + } + + public static Date addDays(Date date, int days) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.DATE, days); // minus number would decrement the days + return cal.getTime(); + } + + public static String GetRuntimeVersion() { + return KnownUser.GetRuntime(); + } +} diff --git a/SDK/test/queueit/knownuserv3/sdk/UrlParameterProviderTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/UrlParameterProviderTest.java similarity index 53% rename from SDK/test/queueit/knownuserv3/sdk/UrlParameterProviderTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/UrlParameterProviderTest.java index f27b4ee..36ac538 100644 --- a/SDK/test/queueit/knownuserv3/sdk/UrlParameterProviderTest.java +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/UrlParameterProviderTest.java @@ -14,6 +14,7 @@ public void TryExtractQueueParams_Test() { assertTrue("eventid".equals(queueParameter.getEventId())); assertTrue(queueParameter.getCookieValidityMinutes() == 10); assertTrue(queueParameter.getExtendableCookie() == false); + assertTrue("944c1f44-60dd-4e37-aabc-f3e4bb1c8895".equals(queueParameter.getQueueId())); assertTrue("218b734e-d5be-4b60-ad66-9b1b326266e2".equals(queueParameter.getHashCode())); assertTrue(queueitToken.equals(queueParameter.getQueueITToken())); assertTrue("ts_1480593661~cv_10~ce_false~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~c_customerid~e_eventid~rt_disabled".equals(queueParameter.getQueueITTokenWithoutHash())); @@ -21,14 +22,38 @@ public void TryExtractQueueParams_Test() { @Test public void TryExtractQueueParams_NotValidFormat_Test() { - String queueitToken = "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895"; + String queueitToken = "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~h_218b734e-d5be-4b60-ad66-9b1b326266e2"; + String queueitTokenWithoutHash = "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895"; QueueUrlParams queueParameter = QueueParameterHelper.extractQueueParams(queueitToken); assertTrue(queueParameter.getTimeStamp() == 0); assertTrue("".equals(queueParameter.getEventId())); assertTrue(queueParameter.getCookieValidityMinutes() == null); assertTrue(queueParameter.getExtendableCookie() == false); + assertTrue("944c1f44-60dd-4e37-aabc-f3e4bb1c8895".equals(queueParameter.getQueueId())); + assertTrue("218b734e-d5be-4b60-ad66-9b1b326266e2".equals(queueParameter.getHashCode())); + assertTrue(queueitToken.equals(queueParameter.getQueueITToken())); + assertTrue(queueitTokenWithoutHash.equals(queueParameter.getQueueITTokenWithoutHash())); + } + + @Test + public void TryExtractQueueParams_Using_QueueitToken_With_No_Values_Test() { + String queueitToken = "e~q~ts~ce~rt~h"; + + QueueUrlParams queueParameter = QueueParameterHelper.extractQueueParams(queueitToken); + assertTrue(queueParameter.getTimeStamp() == 0); + assertTrue("".equals(queueParameter.getEventId())); + assertTrue(queueParameter.getCookieValidityMinutes() == null); + assertTrue(queueParameter.getExtendableCookie() == false); + assertTrue("".equals(queueParameter.getQueueId())); assertTrue("".equals(queueParameter.getHashCode())); assertTrue(queueitToken.equals(queueParameter.getQueueITToken())); + assertTrue(queueitToken.equals(queueParameter.getQueueITTokenWithoutHash())); + } + + @Test + public void TryExtractQueueParams_Using_No_QueueitToken_Expect_Null() { + QueueUrlParams queueParameter = QueueParameterHelper.extractQueueParams(""); + assertTrue(queueParameter == null); } } diff --git a/SDK/test/queueit/knownuserv3/sdk/UserInQueueServiceTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueServiceTest.java similarity index 65% rename from SDK/test/queueit/knownuserv3/sdk/UserInQueueServiceTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueServiceTest.java index 1d1c6ac..0270e80 100644 --- a/SDK/test/queueit/knownuserv3/sdk/UserInQueueServiceTest.java +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueServiceTest.java @@ -1,3 +1,4 @@ + package queueit.knownuserv3.sdk; import java.net.URLEncoder; @@ -6,6 +7,7 @@ import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -13,7 +15,7 @@ public class UserInQueueServiceTest { - //ExtendableCookie Cookie + // ExtendableCookie Cookie @Test public void validateQueueRequest_ValidState_ExtendableCookie_NoCookieExtensionFromConfig_DoNotRedirectDoNotStoreCookieWithExtension() throws Exception { @@ -23,31 +25,36 @@ public void validateQueueRequest_ValidState_ExtendableCookie_NoCookieExtensionFr config.setQueueDomain("testdomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); + config.setActionName("QueueAction"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomainString, - String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, + String cookieDomainString, String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(true, "queueId", null, "queue"); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; UserInQueueService testObject = new UserInQueueService(cookieProviderMock); @@ -58,10 +65,12 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(result.getEventId().equals("e1")); assertTrue(result.getQueueId().equals("queueId")); assertTrue(result.getRedirectType().equals("queue")); + assertEquals(result.getActionName(), config.getActionName()); } @Test - public void validateQueueRequest_ValidState_ExtendableCookie_CookieExtensionFromConfig_DoNotRedirect_DoStoreCookieWithExtension() throws Exception { + public void validateQueueRequest_ValidState_ExtendableCookie_CookieExtensionFromConfig_DoNotRedirect_DoStoreCookieWithExtension() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e1"); @@ -69,13 +78,15 @@ public void validateQueueRequest_ValidState_ExtendableCookie_CookieExtensionFrom config.setCookieValidityMinute(10); config.setExtendCookieValidity(true); config.setCookieDomain(".testdomain.com"); - final HashMap> callInfo = new HashMap(); - callInfo.put("firstCall", new HashMap()); + config.setActionName("QueueAction"); + final HashMap> callInfo = new HashMap>(); + callInfo.put("firstCall", new HashMap()); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { - HashMap info = new HashMap(); + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { + HashMap info = new HashMap(); info.put("eventId", eventId); info.put("fixedCookieValidityMinutes", fixedCookieValidityMinutes); info.put("redirectType", redirectType); @@ -86,19 +97,23 @@ public void store(String eventId, String queueId, Integer fixedCookieValidityMin } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(true, "queueId", null, "queue"); } @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -111,6 +126,7 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(callInfo.get("firstCall").get("redirectType").equals("queue")); assertTrue(callInfo.get("firstCall").get("customerSecretKey").equals("key")); assertTrue(callInfo.get("firstCall").get("cookieDomain").equals(".testdomain.com")); + assertEquals(result.getActionName(), config.getActionName()); } @Test @@ -122,31 +138,36 @@ public void validateQueueRequest_ValidState_NoExtendableCookie_DoNotRedirect_DoN config.setQueueDomain("testdomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(true); + config.setActionName("QueueAction"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { - HashMap info = new HashMap(); + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(true, "queueId", "3", "idle"); } @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; UserInQueueService testObject = new UserInQueueService(cookieProviderMock); @@ -156,40 +177,48 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(!conditions.get("isStoreWasCalled")); assertTrue(result.getEventId().equals("e1")); assertTrue(result.getQueueId().equals("queueId")); + assertEquals(result.getActionName(), config.getActionName()); } @Test - public void ValidateQueueRequest_NoCookie_TampredToken_RedirectToErrorPageWithHashError_DoNotStoreCookie() throws Exception { + public void ValidateQueueRequest_NoCookie_TampredToken_RedirectToErrorPageWithHashError_DoNotStoreCookie() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e1"); config.setQueueDomain("testDomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); config.setVersion(100); + config.setActionName("QueueAction"); + config.setCookieDomain("TestDomain"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookieWasCalled", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -199,14 +228,13 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String String targetUrl = "http://test.test.com?b=h"; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com/error/hash/?c=testCustomer&e=e1" - + "&ver=v3-java-" + knownUserVersion - + "&cver=100" - + "&queueittoken=" + queueitToken - + "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); + String expectedErrorUrl = "https://testDomain.com/error/hash/?c=testCustomer&e=e1" + "&ver=" + knownUserVersion + + "&cver=100" + "&man=" + config.getActionName() + "&queueittoken=" + queueitToken + "&t=" + + URLEncoder.encode(targetUrl, "UTF-8"); UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, "testCustomer", customerKey); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, + "testCustomer", customerKey); assertTrue(result.doRedirect()); Pattern pattern = Pattern.compile("&ts=[^&]*"); @@ -220,41 +248,50 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(redirectUrl.toUpperCase().equals(expectedErrorUrl.toUpperCase())); assertTrue(config.getEventId().equals(result.getEventId())); assertTrue(!conditions.get("isStoreWasCalled")); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookieWasCalled")); } @Test - public void ValidateQueueRequest_NoCookie_ExpiredTimeStampInToken_RedirectToErrorPageWithTimeStampError_DoNotStoreCookie() throws Exception { + public void ValidateQueueRequest_NoCookie_ExpiredTimeStampInToken_RedirectToErrorPageWithTimeStampError_DoNotStoreCookie() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e1"); config.setQueueDomain("testDomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); config.setVersion(100); + config.setActionName("QueueAction"); + config.setCookieDomain("testDomain"); String customerKey = "4e1db821-a825-49da-acd0-5d376f2068db"; - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookie", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -264,14 +301,13 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String String targetUrl = "http://test.test.com?b=h"; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com/error/timestamp/?c=testCustomer&e=e1" - + "&ver=v3-java-" + knownUserVersion - + "&cver=100" - + "&queueittoken=" + queueitToken + String expectedErrorUrl = "https://testDomain.com/error/timestamp/?c=testCustomer&e=e1" + "&ver=" + + knownUserVersion + "&cver=100" + "&man=" + config.getActionName() + "&queueittoken=" + queueitToken + "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, "testCustomer", customerKey); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, + "testCustomer", customerKey); assertTrue(result.doRedirect()); Pattern pattern = Pattern.compile("&ts=[^&]*"); @@ -285,41 +321,50 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(redirectUrl.toUpperCase().equals(expectedErrorUrl.toUpperCase())); assertTrue(config.getEventId().equals(result.getEventId())); assertTrue(!conditions.get("isStoreWasCalled")); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookie")); } @Test - public void ValidateQueueRequest_NoCookie_EventIdMismatch_RedirectToErrorPageWithEventIdMissMatchError_DoNotStoreCookie() throws Exception { + public void ValidateQueueRequest_NoCookie_EventIdMismatch_RedirectToErrorPageWithEventIdMissMatchError_DoNotStoreCookie() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e2"); config.setQueueDomain("testDomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); config.setVersion(10); + config.setActionName("QueueAction"); + config.setCookieDomain("testDomain"); String customerKey = "4e1db821-a825-49da-acd0-5d376f2068db"; - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookie", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -329,14 +374,13 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String String targetUrl = "http://test.test.com?b=h"; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com/error/eventid/?c=testCustomer&e=e2" - + "&ver=v3-java-" + knownUserVersion - + "&cver=10" - + "&queueittoken=" + queueitToken + String expectedErrorUrl = "https://testDomain.com/error/eventid/?c=testCustomer&e=e2" + "&ver=" + + knownUserVersion + "&cver=10" + "&man=" + config.getActionName() + "&queueittoken=" + queueitToken + "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, "testCustomer", customerKey); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, + "testCustomer", customerKey); assertTrue(result.doRedirect()); Pattern pattern = Pattern.compile("&ts=[^&]*"); @@ -350,25 +394,29 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(redirectUrl.toUpperCase().equals(expectedErrorUrl.toUpperCase())); assertTrue(config.getEventId().equals(result.getEventId())); assertTrue(!conditions.get("isStoreWasCalled")); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookie")); } @Test - public void ValidateQueueRequest_NoCookie_ValidToken_ExtendableCookie_DoNotRedirect_StoreExtendableCookie() throws Exception { + public void ValidateQueueRequest_NoCookie_ValidToken_ExtendableCookie_DoNotRedirect_StoreExtendableCookie() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e1"); config.setCookieDomain(".testdomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); + config.setActionName("QueueAction"); String customerKey = "4e1db821-a825-49da-acd0-5d376f2068db"; - final HashMap> callInfo = new HashMap(); - callInfo.put("firstCall", new HashMap()); + final HashMap> callInfo = new HashMap>(); + callInfo.put("firstCall", new HashMap()); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { - HashMap info = new HashMap(); + HashMap info = new HashMap(); info.put("eventId", eventId); info.put("fixedCookieValidityMinutes", fixedCookieValidityMinutes); info.put("cookieDomain", cookieDomain); @@ -378,18 +426,24 @@ public void store(String eventId, String queueId, Integer fixedCookieValidityMin } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + HashMap obj = new HashMap(); + obj.put("eventId", eventId); + obj.put("cookieDomain", cookieDomain); + callInfo.put("cancelQueueCookieWasCalled", obj); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -400,32 +454,37 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String String targetUrl = "http://test.test.com?b=h"; UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, "testCustomer", customerKey); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, + "testCustomer", customerKey); assertTrue(!result.doRedirect()); assertTrue(callInfo.get("firstCall").get("eventId").equals(config.getEventId())); assertTrue(callInfo.get("firstCall").get("fixedCookieValidityMinutes") == null); assertTrue(callInfo.get("firstCall").get("cookieDomain").equals(config.getCookieDomain())); assertTrue(callInfo.get("firstCall").get("redirectType").equals("queue")); assertTrue(callInfo.get("firstCall").get("customerSecretKey").equals(customerKey)); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(callInfo.get("cancelQueueCookieWasCalled") == null); } @Test - public void ValidateQueueRequest_NoCookie_ValidToken_CookieValidityMinuteFromToken_DoNotRedirect_StoreNonExtendableCookie() throws Exception { + public void ValidateQueueRequest_NoCookie_ValidToken_CookieValidityMinuteFromToken_DoNotRedirect_StoreNonExtendableCookie() + throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("eventid"); - config.setCookieDomain(".testdomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(true); + config.setActionName("QueueAction"); + config.setCookieDomain("testDomain"); String customerKey = "secretekeyofuser"; - final HashMap> callInfo = new HashMap(); - callInfo.put("firstCall", new HashMap()); + final HashMap> callInfo = new HashMap>(); + callInfo.put("firstCall", new HashMap()); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { - HashMap info = new HashMap(); + HashMap info = new HashMap(); info.put("eventId", eventId); info.put("fixedCookieValidityMinutes", fixedCookieValidityMinutes); info.put("cookieDomain", cookieDomain); @@ -435,18 +494,24 @@ public void store(String eventId, String queueId, Integer fixedCookieValidityMin } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + HashMap obj = new HashMap(); + obj.put("eventId", eventId); + obj.put("cookieDomain", cookieDomain); + callInfo.put("cancelQueueCookieWasCalled", obj); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; @@ -454,7 +519,8 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String String targetUrl = "http://test.test.com?b=h"; UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, "testCustomer", customerKey); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, queueitToken, config, + "testCustomer", customerKey); assertTrue(!result.doRedirect()); assertTrue(callInfo.get("firstCall").get("eventId").equals(config.getEventId())); assertTrue(callInfo.get("firstCall").get("redirectType").equals("DirectLink")); @@ -462,51 +528,56 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(callInfo.get("firstCall").get("fixedCookieValidityMinutes").equals(3)); assertTrue(callInfo.get("firstCall").get("customerSecretKey").equals(customerKey)); assertTrue(config.getEventId().equals(result.getEventId())); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(callInfo.get("cancelQueueCookieWasCalled") == null); } @Test public void ValidateQueueRequest_NoCookie_WithoutToken_RedirectToQueue() throws Exception { QueueEventConfig config = new QueueEventConfig(); config.setEventId("e1"); - config.setQueueDomain("testDomain.com"); config.setCookieValidityMinute(10); config.setExtendCookieValidity(false); config.setLayoutName("testlayout"); config.setVersion(10); + config.setActionName("QueueAction"); + config.setQueueDomain("testDomain.com"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookie", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; String targetUrl = "http://test.test.com?b=h"; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com?c=testCustomer&e=e1" - + "&ver=v3-java-" + knownUserVersion - + "&cver=10" - + "&l=" + config.getLayoutName() - + "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); + String expectedErrorUrl = "https://testDomain.com/?c=testCustomer&e=e1" + "&ver=" + knownUserVersion + + "&cver=10" + "&man=" + config.getActionName() + "&l=" + config.getLayoutName() + "&t=" + + URLEncoder.encode(targetUrl, "UTF-8"); UserInQueueService testObject = new UserInQueueService(cookieProviderMock); RequestValidationResult result = testObject.validateQueueRequest(targetUrl, "", config, "testCustomer", "key"); @@ -514,6 +585,8 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(result.getRedirectUrl().toUpperCase().equals(expectedErrorUrl.toUpperCase())); assertTrue(!conditions.get("isStoreWasCalled")); assertTrue(config.getEventId().equals(result.getEventId())); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookie")); } @Test @@ -525,38 +598,42 @@ public void ValidateQueueRequest_NoCookie_WithoutToken_RedirectToQueue_NoTargetU config.setExtendCookieValidity(false); config.setLayoutName("testlayout"); config.setVersion(10); + config.setActionName("QueueAction"); + config.setCookieDomain("testDomain"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookie", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com?c=testCustomer&e=e1" - + "&ver=v3-java-" + knownUserVersion - + "&cver=10" - + "&l=" + config.getLayoutName(); + String expectedErrorUrl = "https://testDomain.com/?c=testCustomer&e=e1" + "&ver=" + knownUserVersion + + "&cver=10" + "&man=" + config.getActionName() + "&l=" + config.getLayoutName(); UserInQueueService testObject = new UserInQueueService(cookieProviderMock); RequestValidationResult result = testObject.validateQueueRequest(null, "", config, "testCustomer", "key"); @@ -564,6 +641,8 @@ public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String assertTrue(result.getRedirectUrl().toUpperCase().equals(expectedErrorUrl.toUpperCase())); assertTrue(!conditions.get("isStoreWasCalled")); assertTrue(config.getEventId().equals(result.getEventId())); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookie")); } @Test @@ -575,47 +654,52 @@ public void ValidateQueueRequest_NoCookie_InValidToken() throws Exception { config.setExtendCookieValidity(false); config.setLayoutName("testlayout"); config.setVersion(10); + config.setActionName("QueueAction"); + config.setCookieDomain("testDomain"); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isStoreWasCalled", false); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override public void cancelQueueCookie(String eventId, String cookieDomain) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + conditions.put("cancelQueueCookie", true); } @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { conditions.put("isStoreWasCalled", true); } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { return new StateInfo(false, null, null, null); } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } }; - String targetUrl = "http://test.test.com?b=h"; + String targetUrl = "http://test.test.com/?b=h"; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedErrorUrl = "https://testDomain.com?c=testCustomer&e=e1" - + "&ver=v3-" + knownUserVersion - + "&cver=10" - + "&l=" + config.getLayoutName() - + "&t=" + URLEncoder.encode(targetUrl, "UTF-8"); - UserInQueueService testObject = new UserInQueueService(cookieProviderMock); - RequestValidationResult result = testObject.validateQueueRequest(targetUrl, "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895", config, "testCustomer", "key"); + RequestValidationResult result = testObject.validateQueueRequest(targetUrl, + "ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895", config, "testCustomer", "key"); assertTrue(result.doRedirect()); - assertTrue(result.getRedirectUrl().startsWith("https://testDomain.com/error/hash/?c=testCustomer&e=e1&ver=v3-java-" + knownUserVersion + "&cver=10&l=testlayout&queueittoken=ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895&")); + assertTrue(result.getRedirectUrl().startsWith("https://testDomain.com/error/hash/?c=testCustomer&e=e1&ver=" + + knownUserVersion + "&cver=10&man=" + config.getActionName() + + "&l=testlayout&queueittoken=ts_sasa~cv_adsasa~ce_falwwwse~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895&")); assertTrue(!conditions.get("isStoreWasCalled")); assertTrue(config.getEventId().equals(result.getEventId())); + assertEquals(result.getActionName(), config.getActionName()); + assertTrue(conditions.get("cancelQueueCookie")); } @Test @@ -625,17 +709,20 @@ public void validateCancelRequest() throws Exception { config.setQueueDomain("testDomain.com"); config.setCookieDomain("testdomain"); config.setVersion(10); + config.setActionName("Queue Action (._~-) &!*|'\""); - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); IUserInQueueStateRepository cookieProviderMock = new IUserInQueueStateRepository() { @Override - public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, String redirectType, String customerSecretKey) throws Exception { + public void store(String eventId, String queueId, Integer fixedCookieValidityMinutes, String cookieDomain, + String redirectType, String customerSecretKey) throws Exception { } @Override - public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, boolean validateTime) { + public StateInfo getState(String eventId, int cookieValidityMinutes, String customerSecretKey, + boolean validateTime) { if (!validateTime) { return new StateInfo(true, "queueId", null, "queue"); } else { @@ -644,8 +731,10 @@ public StateInfo getState(String eventId, int cookieValidityMinutes, String cust } @Override - public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, String secretKey) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void reissueQueueCookie(String eventId, int cookieValidityMinutes, String cookieDomain, + String secretKey) { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, + // choose Tools | Templates. } @Override @@ -654,10 +743,9 @@ public void cancelQueueCookie(String eventId, String cookieDomain) { } }; String knownUserVersion = UserInQueueService.SDK_VERSION; - String expectedUrl = "https://testDomain.com/cancel/testCustomer/e1/?c=testCustomer&e=e1" - + "&ver=v3-java-" + knownUserVersion - + "&cver=10" - + "&r=url"; + String expectedMan = "Queue%20Action%20%28._%7E-%29%20%26%21%2A%7C%27%22"; + String expectedUrl = "https://testDomain.com/cancel/testCustomer/e1/?c=testCustomer&e=e1" + "&ver=" + + knownUserVersion + "&cver=10" + "&man=" + expectedMan + "&r=url"; UserInQueueService testObject = new UserInQueueService(cookieProviderMock); RequestValidationResult result = testObject.validateCancelRequest("url", config, "testCustomer", "key"); @@ -665,42 +753,49 @@ public void cancelQueueCookie(String eventId, String cookieDomain) { assertTrue("eventId:e1,cookieDomain:testdomain".equals(conditions.get("cancelQueueCookieWasCalled"))); assertTrue(result.doRedirect()); assertTrue("queueId".equals(result.getQueueId())); - assertTrue(expectedUrl.equals(result.getRedirectUrl())); + String expUrl = expectedUrl.toLowerCase(); + String rdrUrl = result.getRedirectUrl().toLowerCase(); + assertTrue(expUrl.equals(rdrUrl)); assertTrue(config.getEventId().equals(result.getEventId())); + assertEquals(result.getActionName(), config.getActionName()); } @Test public void getIgnoreRequest() throws Exception { UserInQueueService testObject = new UserInQueueService(null); - RequestValidationResult result = testObject.getIgnoreActionResult(); + RequestValidationResult result = testObject.getIgnoreActionResult("TestIgnoreAction"); assertTrue(ActionType.IGNORE_ACTION.equals(result.getActionType())); assertFalse(result.doRedirect()); assertNull(result.getEventId()); assertNull(result.getQueueId()); assertNull(result.getRedirectUrl()); + assertEquals(result.getActionName(), "TestIgnoreAction"); } public static class QueueITTokenGenerator { - public static String generateToken( - Date timeStamp, - String eventId, - boolean extendableCookie, - Integer cookieValidityMinute, - String secretKey, - String redirectType) throws Exception { - ArrayList paramList = new ArrayList(); - paramList.add(QueueParameterHelper.TimeStampKey + QueueParameterHelper.KeyValueSeparatorChar + GetUnixTimestamp(timeStamp)); + public static String generateToken(Date timeStamp, String eventId, boolean extendableCookie, + Integer cookieValidityMinute, String secretKey, String redirectType) { + + ArrayList paramList = new ArrayList(); + + paramList.add(QueueParameterHelper.TimeStampKey + QueueParameterHelper.KeyValueSeparatorChar + + GetUnixTimestamp(timeStamp)); if (cookieValidityMinute != null) { - paramList.add(QueueParameterHelper.CookieValidityMinutesKey + QueueParameterHelper.KeyValueSeparatorChar + cookieValidityMinute); + paramList.add(QueueParameterHelper.CookieValidityMinutesKey + QueueParameterHelper.KeyValueSeparatorChar + + cookieValidityMinute); } paramList.add(QueueParameterHelper.EventIdKey + QueueParameterHelper.KeyValueSeparatorChar + eventId); - paramList.add(QueueParameterHelper.ExtendableCookieKey + QueueParameterHelper.KeyValueSeparatorChar + extendableCookie); - paramList.add(QueueParameterHelper.RedirectTypeKey + QueueParameterHelper.KeyValueSeparatorChar + redirectType); + paramList.add(QueueParameterHelper.ExtendableCookieKey + QueueParameterHelper.KeyValueSeparatorChar + + extendableCookie); + paramList.add( + QueueParameterHelper.RedirectTypeKey + QueueParameterHelper.KeyValueSeparatorChar + redirectType); String tokenWithoutHash = Utils.join(QueueParameterHelper.KeyValueSeparatorGroupChar, paramList); String hash = HashHelper.generateSHA256Hash(secretKey, tokenWithoutHash); - String token = tokenWithoutHash + QueueParameterHelper.KeyValueSeparatorGroupChar + QueueParameterHelper.HashKey + QueueParameterHelper.KeyValueSeparatorChar + hash; + String token = tokenWithoutHash + QueueParameterHelper.KeyValueSeparatorGroupChar + + QueueParameterHelper.HashKey + QueueParameterHelper.KeyValueSeparatorChar + hash; + return token; } diff --git a/SDK/test/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java similarity index 94% rename from SDK/test/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java index 37b8a4d..09f9cb1 100644 --- a/SDK/test/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/UserInQueueStateCookieRepositoryTest.java @@ -15,8 +15,8 @@ public void store_getState_ExtendableCookie_CookieIsSaved() throws Exception { String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; String cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); int cookieValidity = 10; - final HashMap> cookies = new HashMap(); - cookies.put(cookieKey, new HashMap()); + final HashMap> cookies = new HashMap>(); + cookies.put(cookieKey, new HashMap()); ICookieManager cookieManager = new ICookieManager() { @@ -57,7 +57,7 @@ public void store_getState_TamperedCookie_StateIsNotValid() throws Exception { String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; String cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); int cookieValidity = 10; - final HashMap cookies = new HashMap(); + final HashMap cookies = new HashMap(); ICookieManager cookieManager = new ICookieManager() { @@ -91,7 +91,7 @@ public void store_getState_ExpiredCookie_StateIsNotValid_Queue() throws Exceptio String secretKey = "4e1db821-a825-49da-acd0-5d376f2068db"; String cookieDomain = ".test.com"; String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; - final HashMap cookies = new HashMap(); + final HashMap cookies = new HashMap(); ICookieManager cookieManager = new ICookieManager() { @@ -118,7 +118,7 @@ public void store_getState_ExpiredCookie_StateIsNotValid_Idle() throws Exception String secretKey = "4e1db821-a825-49da-acd0-5d376f2068db"; String cookieDomain = ".test.com"; String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; - final HashMap cookies = new HashMap(); + final HashMap cookies = new HashMap(); ICookieManager cookieManager = new ICookieManager() { @@ -145,9 +145,8 @@ public void store_getState_DifferentEventId_StateIsNotValid() throws Exception { String secretKey = "4e1db821-a825-49da-acd0-5d376f2068db"; String cookieDomain = ".test.com"; String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; - String cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - - final HashMap cookies = new HashMap(); + + final HashMap cookies = new HashMap(); ICookieManager cookieManager = new ICookieManager() { @@ -203,9 +202,9 @@ public void cancelQueueCookie_Test() throws Exception { String cookieDomain = "testDomain"; String cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - final HashMap> cookies = new HashMap(); - cookies.put(cookieKey + "1", new HashMap()); - cookies.put(cookieKey + "2", new HashMap()); + final HashMap> cookies = new HashMap>(); + cookies.put(cookieKey + "1", new HashMap()); + cookies.put(cookieKey + "2", new HashMap()); ICookieManager cookieManager = new ICookieManager() { @@ -240,20 +239,18 @@ public String getCookie(String cookieName) { } @Test - public void extendQueueCookie_CookietExist_Test() throws Exception { + public void extendQueueCookie_CookietExist_Test() { String eventId = "event1"; String secretKey = "secretKey"; String queueId = "528f01d4-30f9-4753-95b3-2c8c33966abc"; - String cookieKey = UserInQueueStateCookieRepository.getCookieKey(eventId); - final HashMap cookie = new HashMap(); + final HashMap cookie = new HashMap(); Long issueTime = (System.currentTimeMillis() / 1000L - 120); String hash = HashHelper.generateSHA256Hash(secretKey, eventId + queueId + "3" + "idle" + String.valueOf(issueTime)); final String cookieValue = "EventId=" + eventId + "&QueueId=" + queueId + "&FixedValidityMins=3&RedirectType=idle&IssueTime=" + String.valueOf(issueTime) + "&Hash=" + hash; ICookieManager cookieManager = new ICookieManager() { - public int setCookieCallNumber = 0; boolean isSetCookieCalled = false; @Override @@ -297,7 +294,7 @@ public void extendQueueCookie_CookieDoesNotExist_Test() { String eventId = "event1"; String secretKey = "secretKey"; - final HashMap conditions = new HashMap(); + final HashMap conditions = new HashMap(); conditions.put("isSetCookieCalled", false); ICookieManager cookieManager = new ICookieManager() { @@ -318,7 +315,7 @@ public String getCookie(String cookieName) { } @Test - public void getState_ValidCookieFormat_Extendable_Test() throws Exception { + public void getState_ValidCookieFormat_Extendable_Test() { String eventId = "event1"; String secretKey = "secretKey"; @@ -350,7 +347,7 @@ public String getCookie(String cookieName) { } @Test - public void getState_ValidCookieFormat_NonExtendable_Test() throws Exception { + public void getState_ValidCookieFormat_NonExtendable_Test() { String eventId = "event1"; String secretKey = "secretKey"; @@ -382,7 +379,7 @@ public String getCookie(String cookieName) { } @Test - public void getState_OldCookie_InValid_ExpiredCookie_Extendable_Test() throws Exception { + public void getState_OldCookie_InValid_ExpiredCookie_Extendable_Test() { String eventId = "event1"; String secretKey = "secretKey"; @@ -411,7 +408,7 @@ public String getCookie(String cookieName) { } @Test - public void getState_OldCookie_InValid_ExpiredCookie_NonExtendable_Test() throws Exception { + public void getState_OldCookie_InValid_ExpiredCookie_NonExtendable_Test() { String eventId = "event1"; String secretKey = "secretKey"; String queueId = "f8757c2d-34c2-4639-bef2-1736cdd30bbb"; diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java similarity index 67% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java index 4d53e5c..2e59b48 100644 --- a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java +++ b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/ComparisonOperatorHelperTest.java @@ -26,30 +26,6 @@ public void Evaluate_Contains() { assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.CONTAINS, false, false, "test_dsdsdsdtest1", "*", null)); } - @Test - public void Evaluate_StartsWith() { - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.STARTS_WITH, false, false, "test1_test1_test", "test1", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.STARTS_WITH, false, false, "test1_test1_test", "Test1", null)); - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.STARTS_WITH, false, true, "test1_test1_test", "Test1", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.STARTS_WITH, true, true, "test1_test1_test", "Test1", null)); - } - - @Test - public void Evaluate_EndsWith() { - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ENDS_WITH, false, false, "test1_test1_testshop", "shop", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ENDS_WITH, false, false, "test1_test1_testshop2", "shop", null)); - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ENDS_WITH, false, true, "test1_test1_testshop", "Shop", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.ENDS_WITH, true, true, "test1_test1_testshop", "Shop", null)); - } - - @Test - public void Evaluate_MatchesWith() { - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.MATCHES_WITH, false, false, "test1_test1_testshop", ".*shop.*", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.MATCHES_WITH, false, false, "test1_test1_testshop2", ".*Shop.*", null)); - assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.MATCHES_WITH, false, true, "test1_test1_testshop", ".*Shop.*", null)); - assertFalse(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.MATCHES_WITH, true, true, "test1_test1_testshop", ".*Shop.*", null)); - } - @Test public void Evaluate_EqualsAny() { assertTrue(ComparisonOperatorHelper.evaluate(ComparisonOperatorType.EQUALS_ANY, false, false, "test1", null, new String[]{"test1"})); diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/CookieValidatorHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/CookieValidatorHelperTest.java similarity index 100% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/CookieValidatorHelperTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/CookieValidatorHelperTest.java diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/HttpHeaderHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/HttpHeaderHelperTest.java similarity index 100% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/HttpHeaderHelperTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/HttpHeaderHelperTest.java diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluatorTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluatorTest.java similarity index 100% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluatorTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/IntegrationEvaluatorTest.java diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/UrlValidatorHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/UrlValidatorHelperTest.java similarity index 100% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/UrlValidatorHelperTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/UrlValidatorHelperTest.java diff --git a/SDK/test/queueit/knownuserv3/sdk/integrationconfig/UserAgentValidatorHelperTest.java b/SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/UserAgentValidatorHelperTest.java similarity index 100% rename from SDK/test/queueit/knownuserv3/sdk/integrationconfig/UserAgentValidatorHelperTest.java rename to SDK/src/test/java/queueit/knownuserv3/sdk/integrationconfig/UserAgentValidatorHelperTest.java diff --git a/SDK/src/test/java/queueit/knownuserv3/sdk/resources/hamcrest-core-1.3.jar b/SDK/src/test/java/queueit/knownuserv3/sdk/resources/hamcrest-core-1.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9d5fe16e3dd37ebe79a36f61f5d0e1a69a653a8a GIT binary patch literal 45024 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 UgpPtD2z>DYYp}SJr5?)v0beu;=l}o! literal 0 HcmV?d00001 diff --git a/SDK/src/test/java/queueit/knownuserv3/sdk/resources/javax.servlet-api.jar b/SDK/src/test/java/queueit/knownuserv3/sdk/resources/javax.servlet-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..8161e88b90997cf904154544dfd2f022e46daf6e GIT binary patch literal 86333 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�(326VBVn=kclwd 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 Jdw_Uu1;s+9naEbs3qXDf$X#4OFk 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 literal 0 HcmV?d00001 diff --git a/SDK/src/test/resources/hamcrest-core-1.3.jar b/SDK/src/test/resources/hamcrest-core-1.3.jar new file mode 100644 index 0000000000000000000000000000000000000000..9d5fe16e3dd37ebe79a36f61f5d0e1a69a653a8a GIT binary patch literal 45024 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 UgpPtD2z>DYYp}SJr5?)v0beu;=l}o! literal 0 HcmV?d00001 diff --git a/SDK/src/test/resources/javax.servlet-api.jar b/SDK/src/test/resources/javax.servlet-api.jar new file mode 100644 index 0000000000000000000000000000000000000000..8161e88b90997cf904154544dfd2f022e46daf6e GIT binary patch literal 86333 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�(326VBVn=kclwd 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 Jdw_Uu1;s+9naEbs3qXDf$X#4OFk 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 literal 0 HcmV?d00001 diff --git a/SDK/test/queueit/knownuserv3/sdk/HashHelperTest.java b/SDK/test/queueit/knownuserv3/sdk/HashHelperTest.java deleted file mode 100644 index 5e6496f..0000000 --- a/SDK/test/queueit/knownuserv3/sdk/HashHelperTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package queueit.knownuserv3.sdk; - -import static org.junit.Assert.assertTrue; -import org.junit.Test; - -public class HashHelperTest { - - @Test - public void generateSHA256Hash() throws Exception { - String key = "528f01d4-30f9-4753-95b3-2c8c33966abc"; - String stringToHash = "ts_1480593661~cv_10~ce_false~q_944c1f44-60dd-4e37-aabc-f3e4bb1c8895~c_customerid~e_eventid~rt_disabled"; - - assertTrue(HashHelper.generateSHA256Hash(key, stringToHash).equals("286a17fb82009d8556465b2f0880a8e5e9565b42490669f4b8f1b93b7d6ddd51")); - } -} diff --git a/SDK/test/queueit/knownuserv3/sdk/KnownUserTest.java b/SDK/test/queueit/knownuserv3/sdk/KnownUserTest.java deleted file mode 100644 index afbd31e..0000000 --- a/SDK/test/queueit/knownuserv3/sdk/KnownUserTest.java +++ /dev/null @@ -1,1795 +0,0 @@ -package queueit.knownuserv3.sdk; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.security.Principal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import javax.servlet.AsyncContext; -import javax.servlet.DispatcherType; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import javax.servlet.http.Part; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.Test; -import queueit.knownuserv3.sdk.integrationconfig.CustomerIntegration; -import queueit.knownuserv3.sdk.integrationconfig.IntegrationConfigModel; -import queueit.knownuserv3.sdk.integrationconfig.TriggerModel; -import queueit.knownuserv3.sdk.integrationconfig.TriggerPart; - -public class KnownUserTest { - - class UserInQueueServiceMock implements IUserInQueueService { - - public ArrayList> validateQueueRequestCalls = new ArrayList(); - public ArrayList> validateCancelRequestCalls = new ArrayList(); - public ArrayList> extendQueueCookieCalls = new ArrayList(); - public ArrayList> getIgnoreActionResultCalls = new ArrayList(); - - @Override - public RequestValidationResult validateQueueRequest(String targetUrl, String queueitToken, QueueEventConfig config, String customerId, String secretKey) throws Exception { - ArrayList args = new ArrayList(); - args.add(targetUrl); - args.add(queueitToken); - args.add(config.getCookieDomain() + ":" - + config.getLayoutName() + ":" - + config.getCulture() + ":" - + config.getEventId() + ":" - + config.getQueueDomain() + ":" - + config.getExtendCookieValidity() + ":" - + config.getCookieValidityMinute() + ":" - + config.getVersion()); - args.add(customerId); - args.add(secretKey); - validateQueueRequestCalls.add(args); - - return new RequestValidationResult("Queue", "", "", "", ""); - } - - @Override - public RequestValidationResult validateCancelRequest( - String targetUrl, - CancelEventConfig config, - String customerId, - String secretKey) throws Exception { - - ArrayList args = new ArrayList(); - args.add(targetUrl); - args.add(config.getCookieDomain() + ":" - + config.getEventId() + ":" - + config.getQueueDomain() + ":" - + config.getVersion()); - args.add(customerId); - args.add(secretKey); - validateCancelRequestCalls.add(args); - - return new RequestValidationResult("Cancel", "", "", "", ""); - } - - @Override - public void extendQueueCookie(String eventId, int cookieValidityMinute, String cookieDomain, String secretKey) { - ArrayList args = new ArrayList(); - args.add(eventId); - args.add(Integer.toString(cookieValidityMinute)); - args.add(cookieDomain); - args.add(secretKey); - extendQueueCookieCalls.add(args); - } - - @Override - public RequestValidationResult getIgnoreActionResult() { - getIgnoreActionResultCalls.add(new ArrayList()); - return new RequestValidationResult("Ignore", "", "", "", ""); - } - } - - @Test - public void cancelRequestByLocalConfigTest() throws Exception { - // Arrange - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - HttpServletResponseMock responseMock = new HttpServletResponseMock(); - - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - CancelEventConfig cancelEventConfig = new CancelEventConfig(); - cancelEventConfig.setCookieDomain("cookiedomain"); - cancelEventConfig.setEventId("eventid"); - cancelEventConfig.setQueueDomain("queuedomain"); - cancelEventConfig.setVersion(1); - - // Act - RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, "customerid", requestMock, responseMock, "secretkey"); - - // Assert - assertTrue("url".equals(mock.validateCancelRequestCalls.get(0).get(0))); - assertTrue("cookiedomain:eventid:queuedomain:1".equals(mock.validateCancelRequestCalls.get(0).get(1))); - assertTrue("customerid".equals(mock.validateCancelRequestCalls.get(0).get(2))); - assertTrue("secretkey".equals(mock.validateCancelRequestCalls.get(0).get(3))); - assertFalse(result.isAjaxResult); - } - - @Test - public void CancelRequestByLocalConfig_AjaxCall_Test() throws Exception { - // Arrange - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); - - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - CancelEventConfig cancelEventConfig = new CancelEventConfig(); - cancelEventConfig.setCookieDomain("cookiedomain"); - cancelEventConfig.setEventId("eventid"); - cancelEventConfig.setQueueDomain("queuedomain"); - cancelEventConfig.setVersion(1); - - // Act - RequestValidationResult result = KnownUser.cancelRequestByLocalConfig("url", "queueitToken", cancelEventConfig, "customerid", requestMock, null, "secretkey"); - - // Assert - assertTrue("http://url".equals(mock.validateCancelRequestCalls.get(0).get(0))); - assertTrue("cookiedomain:eventid:queuedomain:1".equals(mock.validateCancelRequestCalls.get(0).get(1))); - assertTrue("customerid".equals(mock.validateCancelRequestCalls.get(0).get(2))); - assertTrue("secretkey".equals(mock.validateCancelRequestCalls.get(0).get(3))); - assertTrue(result.isAjaxResult); - } - - @Test - public void cancelRequestByLocalConfigDebugCookieLoggingTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - CancelEventConfig cancelEventConfig = new CancelEventConfig(); - cancelEventConfig.setCookieDomain("cookiedomain"); - cancelEventConfig.setEventId("eventid"); - cancelEventConfig.setQueueDomain("queuedomain"); - cancelEventConfig.setVersion(1); - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.RequestURL = "requestUrl"; - requestMock.RemoteAddr = "80.35.35.34"; - requestMock.Headers.put("via", "1.1 example.com"); - requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); - requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); - requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); - requestMock.Headers.put("x-forwarded-proto", "https"); - - HttpServletResponseMock responseMock = new HttpServletResponseMock(); - - // Act - String secretKey = "secretkey"; - String queueittoken = QueueITTokenGenerator.generateToken("eventId", secretKey); - - KnownUser.cancelRequestByLocalConfig("url", queueittoken, cancelEventConfig, "customerId", requestMock, responseMock, secretKey); - - // Assert - assertTrue(responseMock.addedCookies.size() == 1); - assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); - String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); - assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); - assertTrue(decodedCookieValue.contains("CancelConfig=EventId:eventid")); - assertTrue(decodedCookieValue.contains("&Version:1")); - assertTrue(decodedCookieValue.contains("&QueueDomain:queuedomain")); - assertTrue(decodedCookieValue.contains("&CookieDomain:cookiedomain")); - assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); - assertTrue(decodedCookieValue.contains("TargetUrl=url")); - assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); - } - - @Test - public void cancelRequestByLocalConfigNullQueueDomainTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - CancelEventConfig cancelEventConfig = new CancelEventConfig(); - cancelEventConfig.setEventId("eventid"); - cancelEventConfig.setCookieDomain("cookieDomain"); - cancelEventConfig.setVersion(12); - - // Act - try { - KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "QueueDomain from cancelConfig can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void cancelRequestByLocalConfigEventIdNullTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - CancelEventConfig cancelEventConfig = new CancelEventConfig(); - cancelEventConfig.setCookieDomain("domain"); - cancelEventConfig.setVersion(12); - - // Act - try { - KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", cancelEventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "EventId from cancelConfig can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void cancelRequestByLocalConfigCancelEventConfigNullTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "cancelConfig can not be null.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void cancelRequestByLocalConfigCustomerIdNullTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", new CancelEventConfig(), null, new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "customerId can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void cancelRequestByLocalConfigSecretKeyNullTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.cancelRequestByLocalConfig("targetUrl", "queueitToken", new CancelEventConfig(), "customerId", new HttpServletRequestMock(), null, null); - } catch (Exception ex) { - exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void CancelRequestByLocalConfigTargetUrlNullTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.cancelRequestByLocalConfig(null, "queueitToken", new CancelEventConfig(), "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "targetUrl can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateCancelRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void extendQueueCookieNullEventIdTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.extendQueueCookie(null, 0, null, null, null, null); - } catch (Exception ex) { - exceptionWasThrown = "eventId can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.extendQueueCookieCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void extendQueueCookieInvalidCookieValidityMinutesTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.extendQueueCookie("eventId", 0, null, null, null, null); - } catch (Exception ex) { - exceptionWasThrown = "cookieValidityMinute should be greater than 0.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.extendQueueCookieCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void extendQueueCookieNullSecretKeyTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.extendQueueCookie("eventId", 20, null, null, null, null); - } catch (Exception ex) { - exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.extendQueueCookieCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void extendQueueCookieTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - // Act - KnownUser.extendQueueCookie("eventId", 20, "cookieDomain", null, null, "secretKey"); - - // Assert - assertTrue("eventId".equals(mock.extendQueueCookieCalls.get(0).get(0))); - assertTrue("20".equals(mock.extendQueueCookieCalls.get(0).get(1))); - assertTrue("cookieDomain".equals(mock.extendQueueCookieCalls.get(0).get(2))); - assertTrue("secretKey".equals(mock.extendQueueCookieCalls.get(0).get(3))); - } - - @Test - public void resolveQueueRequestByLocalConfigNullCustomerIdTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, null, new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "customerId can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigNullSecretKeyTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", new HttpServletRequestMock(), null, null); - } catch (Exception ex) { - exceptionWasThrown = "secretKey can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigNullEventConfigTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", null, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "eventConfig can not be null.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigNullEventIdTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - QueueEventConfig eventConfig = new QueueEventConfig(); - eventConfig.setCookieDomain("cookieDomain"); - eventConfig.setLayoutName("layoutName"); - eventConfig.setCulture("culture"); - //eventConfig.setEventId("eventId"); - eventConfig.setQueueDomain("queueDomain"); - eventConfig.setExtendCookieValidity(true); - eventConfig.setCookieValidityMinute(10); - eventConfig.setVersion(12); - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "EventId from queueConfig can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigNullQueueDomainTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - QueueEventConfig eventConfig = new QueueEventConfig(); - eventConfig.setCookieDomain("cookieDomain"); - eventConfig.setLayoutName("layoutName"); - eventConfig.setCulture("culture"); - eventConfig.setEventId("eventId"); - //eventConfig.setQueueDomain("queueDomain"); - eventConfig.setExtendCookieValidity(true); - eventConfig.setCookieValidityMinute(10); - eventConfig.setVersion(12); - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "QueueDomain from queueConfig can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigInvalidCookieValidityMinuteTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - QueueEventConfig eventConfig = new QueueEventConfig(); - eventConfig.setCookieDomain("cookieDomain"); - eventConfig.setLayoutName("layoutName"); - eventConfig.setCulture("culture"); - eventConfig.setEventId("eventId"); - eventConfig.setQueueDomain("queueDomain"); - eventConfig.setExtendCookieValidity(true); - //eventConfig.setCookieValidityMinute(10); - eventConfig.setVersion(12); - - // Act - try { - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - } catch (Exception ex) { - exceptionWasThrown = "cookieValidityMinute from queueConfig should be greater than 0.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void resolveQueueRequestByLocalConfigTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - QueueEventConfig eventConfig = new QueueEventConfig(); - eventConfig.setCookieDomain("cookieDomain"); - eventConfig.setLayoutName("layoutName"); - eventConfig.setCulture("culture"); - eventConfig.setEventId("eventId"); - eventConfig.setQueueDomain("queueDomain"); - eventConfig.setExtendCookieValidity(true); - eventConfig.setCookieValidityMinute(10); - eventConfig.setVersion(12); - - // Act - RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue("targetUrl".equals(mock.validateQueueRequestCalls.get(0).get(0))); - assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); - assertTrue("cookieDomain:layoutName:culture:eventId:queueDomain:true:10:12".equals(mock.validateQueueRequestCalls.get(0).get(2))); - assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); - assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); - assertFalse(result.isAjaxResult); - } - - @Test - public void resolveQueueRequestByLocalConfigAjaxCallTest() throws Exception { - // Arrange - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); - - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - QueueEventConfig eventConfig = new QueueEventConfig(); - eventConfig.setCookieDomain("cookieDomain"); - eventConfig.setLayoutName("layoutName"); - eventConfig.setCulture("culture"); - eventConfig.setEventId("eventId"); - eventConfig.setQueueDomain("queueDomain"); - eventConfig.setExtendCookieValidity(true); - eventConfig.setCookieValidityMinute(10); - eventConfig.setVersion(12); - - // Act - RequestValidationResult result = KnownUser.resolveQueueRequestByLocalConfig("targetUrl", "queueitToken", eventConfig, "customerId", requestMock, null, "secretKey"); - - // Assert - assertTrue("http://url".equals(mock.validateQueueRequestCalls.get(0).get(0))); - assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); - assertTrue("cookieDomain:layoutName:culture:eventId:queueDomain:true:10:12".equals(mock.validateQueueRequestCalls.get(0).get(2))); - assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); - assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); - assertTrue(result.isAjaxResult); - } - - @Test - public void resolveQueueRequestByLocalConfigDebugCookieLoggingTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - QueueEventConfig queueConfig = new QueueEventConfig(); - queueConfig.setCookieDomain("cookieDomain"); - queueConfig.setLayoutName("layoutName"); - queueConfig.setCulture("culture"); - queueConfig.setEventId("eventId"); - queueConfig.setQueueDomain("queueDomain"); - queueConfig.setExtendCookieValidity(true); - queueConfig.setCookieValidityMinute(10); - queueConfig.setVersion(12); - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.RequestURL = "requestUrl"; - requestMock.RemoteAddr = "80.35.35.34"; - requestMock.Headers.put("via", "1.1 example.com"); - requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); - requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); - requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); - requestMock.Headers.put("x-forwarded-proto", "https"); - - HttpServletResponseMock responseMock = new HttpServletResponseMock(); - - // Act - String secretKey = "secretkey"; - String queueittoken = QueueITTokenGenerator.generateToken("eventId", secretKey); - - KnownUser.resolveQueueRequestByLocalConfig("targetUrl", queueittoken, queueConfig, "customerId", requestMock, responseMock, secretKey); - - // Assert - assertTrue(responseMock.addedCookies.size() == 1); - assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); - String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); - assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); - assertTrue(decodedCookieValue.contains("QueueConfig=EventId:eventId")); - assertTrue(decodedCookieValue.contains("&Version:12")); - assertTrue(decodedCookieValue.contains("&QueueDomain:queueDomain")); - assertTrue(decodedCookieValue.contains("&CookieDomain:cookieDomain")); - assertTrue(decodedCookieValue.contains("&ExtendCookieValidity:true")); - assertTrue(decodedCookieValue.contains("&CookieValidityMinute:10")); - assertTrue(decodedCookieValue.contains("&LayoutName:layoutName")); - assertTrue(decodedCookieValue.contains("&Culture:culture")); - assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); - assertTrue(decodedCookieValue.contains("TargetUrl=targetUrl")); - assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); - } - - @Test - public void validateRequestByIntegrationConfigEmptyCurrentUrlTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.validateRequestByIntegrationConfig("", null, null, null, null, null, null); - } catch (Exception ex) { - exceptionWasThrown = "currentUrlWithoutQueueITToken can not be null or empty.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void validateRequestByIntegrationConfigEmptyIntegrationsConfigTest() { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - boolean exceptionWasThrown = false; - - // Act - try { - KnownUser.validateRequestByIntegrationConfig("currentUrl", "queueitToken", null, null, new HttpServletRequestMock(), null, null); - } catch (Exception ex) { - exceptionWasThrown = "customerIntegrationInfo can not be null.".equals(ex.getMessage()); - } - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(exceptionWasThrown); - } - - @Test - public void validateRequestByIntegrationConfigQueueActionTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart1 = new TriggerPart(); - triggerPart1.Operator = "Contains"; - triggerPart1.ValueToCompare = "event1"; - triggerPart1.UrlPart = "PageUrl"; - triggerPart1.ValidatorType = "UrlValidator"; - triggerPart1.IsNegative = false; - triggerPart1.IsIgnoreCase = true; - - TriggerPart triggerPart2 = new TriggerPart(); - triggerPart2.Operator = "Contains"; - triggerPart2.ValueToCompare = "googlebot"; - triggerPart2.ValidatorType = "UserAgentValidator"; - triggerPart2.IsNegative = false; - triggerPart2.IsIgnoreCase = false; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart1, triggerPart2}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "AllowTParameter"; - config.ForcedTargetUrl = ""; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - HttpServletRequestMock httpContextMock = new HttpServletRequestMock(); - httpContextMock.UserAgent = "googlebot"; - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", httpContextMock, null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.size() == 1); - assertTrue("http://test.com?event1=true".equals(mock.validateQueueRequestCalls.get(0).get(0))); - assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); - assertTrue(".test.com:Christmas Layout by Queue-it:da-DK:event1:knownusertest.queue-it.net:true:20:3".equals(mock.validateQueueRequestCalls.get(0).get(2))); - assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); - assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); - assertFalse(result.isAjaxResult); - } - - @Test - public void validateRequestByIntegrationConfigQueueActionAjaxCallTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart1 = new TriggerPart(); - triggerPart1.Operator = "Contains"; - triggerPart1.ValueToCompare = "event1"; - triggerPart1.UrlPart = "PageUrl"; - triggerPart1.ValidatorType = "UrlValidator"; - triggerPart1.IsNegative = false; - triggerPart1.IsIgnoreCase = true; - - TriggerPart triggerPart2 = new TriggerPart(); - triggerPart2.Operator = "Contains"; - triggerPart2.ValueToCompare = "googlebot"; - triggerPart2.ValidatorType = "UserAgentValidator"; - triggerPart2.IsNegative = false; - triggerPart2.IsIgnoreCase = false; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart1, triggerPart2}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "AllowTParameter"; - config.ForcedTargetUrl = ""; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.UserAgent = "googlebot"; - requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.size() == 1); - assertTrue("http://url".equals(mock.validateQueueRequestCalls.get(0).get(0))); - assertTrue("queueitToken".equals(mock.validateQueueRequestCalls.get(0).get(1))); - assertTrue(".test.com:Christmas Layout by Queue-it:da-DK:event1:knownusertest.queue-it.net:true:20:3".equals(mock.validateQueueRequestCalls.get(0).get(2))); - assertTrue("customerId".equals(mock.validateQueueRequestCalls.get(0).get(3))); - assertTrue("secretKey".equals(mock.validateQueueRequestCalls.get(0).get(4))); - assertTrue(result.isAjaxResult); - } - - @Test - public void validateRequestByIntegrationConfigDebugCookieLoggingTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart1 = new TriggerPart(); - triggerPart1.Operator = "Contains"; - triggerPart1.ValueToCompare = "event1"; - triggerPart1.UrlPart = "PageUrl"; - triggerPart1.ValidatorType = "UrlValidator"; - triggerPart1.IsNegative = false; - triggerPart1.IsIgnoreCase = true; - - TriggerPart triggerPart2 = new TriggerPart(); - triggerPart2.Operator = "Contains"; - triggerPart2.ValueToCompare = "googlebot"; - triggerPart2.ValidatorType = "UserAgentValidator"; - triggerPart2.IsNegative = false; - triggerPart2.IsIgnoreCase = false; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart1, triggerPart2}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "AllowTParameter"; - config.ForcedTargetUrl = ""; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.UserAgent = "googlebot"; - requestMock.RequestURL = "requestUrl"; - - HttpServletResponseMock responseMock = new HttpServletResponseMock(); - - // Act - String secretKey = "secretkey"; - String queueittoken = QueueITTokenGenerator.generateToken("eventId", secretKey); - - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); - - // Assert - assertTrue(responseMock.addedCookies.size() == 1); - assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); - String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); - assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); - assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); - assertTrue(decodedCookieValue.contains("ConfigVersion=3")); - assertTrue(decodedCookieValue.contains("QueueConfig=EventId:event1")); - assertTrue(decodedCookieValue.contains("&Version:3")); - assertTrue(decodedCookieValue.contains("&QueueDomain:knownusertest.queue-it.net")); - assertTrue(decodedCookieValue.contains("&CookieDomain:.test.com")); - assertTrue(decodedCookieValue.contains("&ExtendCookieValidity:true")); - assertTrue(decodedCookieValue.contains("&CookieValidityMinute:20")); - assertTrue(decodedCookieValue.contains("&LayoutName:Christmas Layout by Queue-it")); - assertTrue(decodedCookieValue.contains("&Culture:da-DK")); - assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); - assertTrue(decodedCookieValue.contains("TargetUrl=http://test.com?event1=true")); - assertTrue(decodedCookieValue.contains("MatchedConfig=event1action")); - } - - @Test - public void validateRequestByIntegrationConfigNotMatchTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[0]; - customerIntegration.Version = 3; - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.isEmpty()); - assertTrue(!result.doRedirect()); - } - - @Test - public void validateRequestByIntegrationConfigNotMatchDebugCookieLoggingTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[0]; - customerIntegration.Version = 3; - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.RequestURL = "requestUrl"; - requestMock.RemoteAddr = "80.35.35.34"; - requestMock.Headers.put("via", "1.1 example.com"); - requestMock.Headers.put("forwarded", "for=192.0.2.60;proto=http;by=203.0.113.43"); - requestMock.Headers.put("x-forwarded-for", "129.78.138.66, 129.78.64.103"); - requestMock.Headers.put("x-forwarded-host", "en.wikipedia.org:8080"); - requestMock.Headers.put("x-forwarded-proto", "https"); - - HttpServletResponseMock responseMock = new HttpServletResponseMock(); - - // Act - String secretKey = "secretkey"; - String queueittoken = QueueITTokenGenerator.generateToken("eventId", secretKey); - - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", queueittoken, customerIntegration, "customerId", requestMock, responseMock, secretKey); - - // Assert - assertTrue(responseMock.addedCookies.size() == 1); - assertTrue(responseMock.addedCookies.get(0).getName().equals(KnownUser.QueueITDebugKey)); - String decodedCookieValue = URLDecoder.decode(responseMock.addedCookies.get(0).getValue(), "UTF-8"); - assertTrue(decodedCookieValue.contains("OriginalUrl=requestUrl")); - assertTrue(decodedCookieValue.contains("PureUrl=http://test.com?event1=true")); - assertTrue(decodedCookieValue.contains("ConfigVersion=3")); - assertTrue(decodedCookieValue.contains("QueueitToken=" + queueittoken)); - assertTrue(decodedCookieValue.contains("RequestIP=80.35.35.34")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Via=1.1 example.com")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_Forwarded=for=192.0.2.60;proto=http;by=203.0.113.43")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedFor=129.78.138.66, 129.78.64.103")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedHost=en.wikipedia.org:8080")); - assertTrue(decodedCookieValue.contains("RequestHttpHeader_XForwardedProto=https")); - } - - @Test - public void validateRequestByIntegrationConfigForcedTargeturlTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "ForcedTargetUrl"; - config.ForcedTargetUrl = "http://forcedtargeturl.com"; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - // Act - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.size() == 1); - assertTrue("http://forcedtargeturl.com".equals(mock.validateQueueRequestCalls.get(0).get(0))); - } - - @Test - public void validateRequestByIntegrationConfigForecedTargeturlTest() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "ForecedTargetUrl"; - config.ForcedTargetUrl = "http://forcedtargeturl.com"; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - // Act - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.size() == 1); - assertTrue("http://forcedtargeturl.com".equals(mock.validateQueueRequestCalls.get(0).get(0))); - } - - @Test - public void validateRequestByIntegrationConfigEventTargetUrl() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = ".test.com"; - config.LayoutName = "Christmas Layout by Queue-it"; - config.Culture = "da-DK"; - config.ExtendCookieValidity = true; - config.CookieValidityMinute = 20; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "knownusertest.queue-it.net"; - config.RedirectLogic = "EventTargetUrl"; - config.ActionType = ActionType.QUEUE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - // Act - KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue(mock.validateQueueRequestCalls.size() == 1); - assertTrue("".equals(mock.validateQueueRequestCalls.get(0).get(0))); - } - - @Test - public void validateRequestByIntegrationConfigIgnoreAction() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = "cookiedomain"; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "queuedomain"; - config.ActionType = ActionType.IGNORE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue(mock.getIgnoreActionResultCalls.size() == 1); - assertFalse(result.isAjaxResult); - } - - @Test - public void validateRequestByIntegrationConfigAjaxCallIgnoreAction() throws Exception { - // Arrange - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = "cookiedomain"; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "queuedomain"; - config.ActionType = ActionType.IGNORE_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.Headers.put("x-queueit-ajaxpageurl", "url"); - - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); - - // Assert - assertTrue(mock.getIgnoreActionResultCalls.size() == 1); - assertTrue(result.isAjaxResult); - } - - @Test - public void validateRequestByIntegrationConfigCancelAction() throws Exception { - // Arrange - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = "cookiedomain"; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "queuedomain"; - config.ActionType = ActionType.CANCEL_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", new HttpServletRequestMock(), null, "secretKey"); - - // Assert - assertTrue("http://test.com?event1=true".equals(mock.validateCancelRequestCalls.get(0).get(0))); - assertTrue("cookiedomain:event1:queuedomain:3".equals(mock.validateCancelRequestCalls.get(0).get(1))); - assertTrue("customerId".equals(mock.validateCancelRequestCalls.get(0).get(2))); - assertTrue("secretKey".equals(mock.validateCancelRequestCalls.get(0).get(3))); - assertFalse(result.isAjaxResult); - } - - @Test - public void validateRequestByIntegrationConfigAjaxCallCancelAction() throws Exception { - // Arrange - TriggerPart triggerPart = new TriggerPart(); - triggerPart.Operator = "Contains"; - triggerPart.ValueToCompare = "event1"; - triggerPart.UrlPart = "PageUrl"; - triggerPart.ValidatorType = "UrlValidator"; - triggerPart.IsNegative = false; - triggerPart.IsIgnoreCase = true; - - TriggerModel trigger = new TriggerModel(); - trigger.LogicalOperator = "And"; - trigger.TriggerParts = new TriggerPart[]{triggerPart}; - - IntegrationConfigModel config = new IntegrationConfigModel(); - config.Name = "event1action"; - config.EventId = "event1"; - config.CookieDomain = "cookiedomain"; - config.Triggers = new TriggerModel[]{trigger}; - config.QueueDomain = "queuedomain"; - config.ActionType = ActionType.CANCEL_ACTION; - - CustomerIntegration customerIntegration = new CustomerIntegration(); - customerIntegration.Integrations = new IntegrationConfigModel[]{config}; - customerIntegration.Version = 3; - - HttpServletRequestMock requestMock = new HttpServletRequestMock(); - requestMock.Headers.put("x-queueit-ajaxpageurl", "http%3A%2F%2Furl"); - - UserInQueueServiceMock mock = new UserInQueueServiceMock(); - KnownUser.setUserInQueueService(mock); - - // Act - RequestValidationResult result = KnownUser.validateRequestByIntegrationConfig("http://test.com?event1=true", "queueitToken", customerIntegration, "customerId", requestMock, null, "secretKey"); - - // Assert - assertTrue("http://url".equals(mock.validateCancelRequestCalls.get(0).get(0))); - assertTrue("cookiedomain:event1:queuedomain:3".equals(mock.validateCancelRequestCalls.get(0).get(1))); - assertTrue("customerId".equals(mock.validateCancelRequestCalls.get(0).get(2))); - assertTrue("secretKey".equals(mock.validateCancelRequestCalls.get(0).get(3))); - assertTrue(result.isAjaxResult); - } - - class HttpServletRequestMock implements HttpServletRequest { - - public Cookie[] CookiesValue; - public String UserAgent; - public String RequestURL; - public String QueryString; - public String RemoteAddr; - public HashMap Headers; - - public HttpServletRequestMock() { - this.Headers = new HashMap(); - } - - @Override - public String getAuthType() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Cookie[] getCookies() { - return this.CookiesValue; - } - - @Override - public long getDateHeader(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getHeader(String key) { - if ("User-Agent".equals(key)) { - return this.UserAgent; - } - - String value = (String) this.Headers.get(key); - - if (value == null) { - value = ""; - } - - return value; - } - - @Override - public Enumeration getHeaders(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Enumeration getHeaderNames() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getIntHeader(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getMethod() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getPathInfo() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getPathTranslated() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getContextPath() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getQueryString() { - return this.QueryString; - } - - @Override - public String getRemoteUser() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isUserInRole(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Principal getUserPrincipal() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getRequestedSessionId() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getRequestURI() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public StringBuffer getRequestURL() { - return new StringBuffer(this.RequestURL); - } - - @Override - public String getServletPath() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public HttpSession getSession(boolean bln) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public HttpSession getSession() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isRequestedSessionIdValid() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isRequestedSessionIdFromCookie() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isRequestedSessionIdFromURL() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isRequestedSessionIdFromUrl() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean authenticate(HttpServletResponse hsr) throws IOException, ServletException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void login(String string, String string1) throws ServletException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void logout() throws ServletException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Collection getParts() throws IOException, ServletException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Part getPart(String string) throws IOException, ServletException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Object getAttribute(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Enumeration getAttributeNames() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getCharacterEncoding() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setCharacterEncoding(String string) throws UnsupportedEncodingException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getContentLength() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getContentType() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ServletInputStream getInputStream() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getParameter(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Enumeration getParameterNames() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String[] getParameterValues(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Map getParameterMap() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getProtocol() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getScheme() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getServerName() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getServerPort() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public BufferedReader getReader() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getRemoteAddr() { - return RemoteAddr; - } - - @Override - public String getRemoteHost() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setAttribute(String string, Object o) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void removeAttribute(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Locale getLocale() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Enumeration getLocales() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isSecure() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public RequestDispatcher getRequestDispatcher(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getRealPath(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getRemotePort() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getLocalName() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getLocalAddr() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getLocalPort() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ServletContext getServletContext() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public AsyncContext startAsync() throws IllegalStateException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public AsyncContext startAsync(ServletRequest sr, ServletResponse sr1) throws IllegalStateException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isAsyncStarted() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isAsyncSupported() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public AsyncContext getAsyncContext() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public DispatcherType getDispatcherType() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } - - class HttpServletResponseMock implements HttpServletResponse { - - ArrayList addedCookies = new ArrayList(); - - @Override - public void addCookie(Cookie cookie) { - addedCookies.add(cookie); - } - - @Override - public boolean containsHeader(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String encodeURL(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String encodeRedirectURL(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String encodeUrl(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String encodeRedirectUrl(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void sendError(int i, String string) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void sendError(int i) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void sendRedirect(String string) throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setDateHeader(String string, long l) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void addDateHeader(String string, long l) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setHeader(String string, String string1) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void addHeader(String string, String string1) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setIntHeader(String string, int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void addIntHeader(String string, int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setStatus(int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setStatus(int i, String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getStatus() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getHeader(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Collection getHeaders(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Collection getHeaderNames() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getCharacterEncoding() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public String getContentType() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public ServletOutputStream getOutputStream() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public PrintWriter getWriter() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setCharacterEncoding(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setContentLength(int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setContentType(String string) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setBufferSize(int i) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public int getBufferSize() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void flushBuffer() throws IOException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void resetBuffer() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean isCommitted() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void reset() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public void setLocale(Locale locale) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public Locale getLocale() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - } - - public static class QueueITTokenGenerator { - - public static String generateToken( - String eventId, - String secretKey) throws Exception { - - ArrayList paramList = new ArrayList(); - paramList.add(QueueParameterHelper.EventIdKey + QueueParameterHelper.KeyValueSeparatorChar + eventId); - paramList.add(QueueParameterHelper.RedirectTypeKey + QueueParameterHelper.KeyValueSeparatorChar + "debug"); - - String tokenWithoutHash = Utils.join(QueueParameterHelper.KeyValueSeparatorGroupChar, paramList); - String hash = HashHelper.generateSHA256Hash(secretKey, tokenWithoutHash); - String token = tokenWithoutHash + QueueParameterHelper.KeyValueSeparatorGroupChar + QueueParameterHelper.HashKey + QueueParameterHelper.KeyValueSeparatorChar + hash; - return token; - } - } -}