Skip to content
Merged
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,4 @@ maven-plugin/target/surefire/
/distribution/docker/release-bin/
/docs/router-conf.xsd
.vscode/
/core/derby.log
3 changes: 2 additions & 1 deletion core/src/test/java/com/predic8/membrane/core/UnitTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@

@Suite
@SelectPackages({"com.predic8"})
@ExcludePackages("com.predic8.membrane.integration")
@ExcludeClassNamePatterns({
"com.predic8.membrane.AllTests", // Replaced with package scan
"com.predic8.membrane.core.transport.http.ConnectionTest", // #2180 should fix it
"com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptorIntegrationTest", // Rewrite as UnitTest with sampleSOAPService
"com.predic8.membrane.integration.withinternet.interceptor.RewriteInterceptorIntegrationTest", // Rewrite as UnitTest with sampleSOAPService
"com.predic8.membrane.core.interceptor.tunnel.WebsocketStompTest", // Fails: not standalone; depends on external WS+STOMP setup
"com.predic8.membrane.core.interceptor.oauth2client.OAuth2Resource2InterceptorTest", // Disabled: incomplete setup; AuthorizationService (and other) not configured
"com.predic8.membrane.core.util.MemcachedConnectorTest" // Disabled: not standalone; needs Memcached at 127.0.0.1:11211 (fails with Connection refused)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.predic8.membrane.core.interceptor.session.InMemorySessionManager;
import com.predic8.membrane.core.interceptor.session.SessionManager;

public class InMemB2CResourceTest extends OAuth2ResourceB2CTest {
public class InMemB2CResourceTest extends OAuth2ResourceB2CUnitTest {
@Override
protected SessionManager createSessionManager() {
return new InMemorySessionManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import com.predic8.membrane.core.interceptor.session.SessionManager;

public class JwtB2CResourceTest extends OAuth2ResourceB2CTest {
public class JwtB2CResourceTest extends OAuth2ResourceB2CUnitTest {
@Override
protected SessionManager createSessionManager() {
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2016 predic8 GmbH, www.predic8.com
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.predic8.membrane.core.interceptor.oauth2.client.b2c;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.predic8.membrane.core.interceptor.oauth2.client.BrowserMock;
import com.predic8.membrane.core.interceptor.session.SessionManager;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicBoolean;

public abstract class OAuth2ResourceB2CTestSetup {
protected final Logger LOG = LoggerFactory.getLogger(OAuth2ResourceB2CTestSetup.class);
protected final B2CTestConfig tc = new B2CTestConfig();
protected final ObjectMapper om = new ObjectMapper();
protected final AtomicBoolean didLogIn = new AtomicBoolean();
protected final AtomicBoolean didLogOut = new AtomicBoolean();
protected final BrowserMock browser = new BrowserMock();
protected final MockAuthorizationServer mockAuthorizationServer = new MockAuthorizationServer(tc, () -> didLogIn.set(true), () -> didLogOut.set(true));
protected final B2CMembrane b2cMembrane = new B2CMembrane(tc, createSessionManager());

@BeforeEach
void init() throws Exception {
didLogIn.set(false);
didLogOut.set(false);
mockAuthorizationServer.resetBehavior();
mockAuthorizationServer.init();
b2cMembrane.init();
}

@AfterEach
void done() {
mockAuthorizationServer.stop();
b2cMembrane.stop();
}

protected abstract SessionManager createSessionManager();
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,29 @@
/*
* Copyright 2016 predic8 GmbH, www.predic8.com
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.predic8.membrane.core.interceptor.oauth2.client.b2c;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.predic8.membrane.core.exceptions.*;
import com.predic8.membrane.core.exchange.*;
import com.predic8.membrane.core.http.*;
import com.predic8.membrane.core.interceptor.*;
import com.predic8.membrane.core.interceptor.oauth2.client.*;
import com.predic8.membrane.core.interceptor.session.SessionManager;
import com.predic8.membrane.core.util.*;
import org.jose4j.jwt.*;
import org.jose4j.jwt.consumer.*;
import org.junit.jupiter.api.*;
import org.slf4j.*;
import com.predic8.membrane.core.exceptions.ProblemDetails;
import com.predic8.membrane.core.exchange.Exchange;
import com.predic8.membrane.core.http.Header;
import com.predic8.membrane.core.http.Request;
import com.predic8.membrane.core.http.Response;
import com.predic8.membrane.core.interceptor.AbstractInterceptor;
import com.predic8.membrane.core.interceptor.Outcome;
import com.predic8.membrane.core.util.URI;
import com.predic8.membrane.core.util.URIFactory;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.junit.jupiter.api.Test;

import java.net.URISyntaxException;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.function.Consumer;

import static com.predic8.membrane.core.http.Header.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import static com.predic8.membrane.core.http.Header.SET_COOKIE;
import static com.predic8.membrane.core.http.Request.get;
import static com.predic8.membrane.core.interceptor.oauth2.client.b2c.MockAuthorizationServer.SERVER_PORT;
import static com.predic8.membrane.core.interceptor.oauth2client.rf.OAuth2CallbackRequestHandler.MEMBRANE_MISSING_SESSION_DESCRIPTION;
Expand All @@ -42,30 +32,7 @@
import static com.predic8.membrane.core.util.URLParamUtil.parseQueryString;
import static org.junit.jupiter.api.Assertions.*;

public abstract class OAuth2ResourceB2CTest {
private final Logger LOG = LoggerFactory.getLogger(OAuth2ResourceB2CTest.class);
private final B2CTestConfig tc = new B2CTestConfig();
private final ObjectMapper om = new ObjectMapper();
private final AtomicBoolean didLogIn = new AtomicBoolean();
private final AtomicBoolean didLogOut = new AtomicBoolean();
private final BrowserMock browser = new BrowserMock();
private final MockAuthorizationServer mockAuthorizationServer = new MockAuthorizationServer(tc, () -> didLogIn.set(true), () -> didLogOut.set(true));
private final B2CMembrane b2cMembrane = new B2CMembrane(tc, createSessionManager());

@BeforeEach
void init() throws Exception {
didLogIn.set(false);
didLogOut.set(false);
mockAuthorizationServer.resetBehavior();
mockAuthorizationServer.init();
b2cMembrane.init();
}

@AfterEach
void done() {
mockAuthorizationServer.stop();
b2cMembrane.stop();
}
public abstract class OAuth2ResourceB2CUnitTest extends OAuth2ResourceB2CTestSetup {

@Test
void getOriginalRequest() throws Exception {
Expand All @@ -86,58 +53,6 @@ void postOriginalRequest() throws Exception {
assertEquals("POST", body2.get("method"));
}

// this test also implicitly tests concurrency on oauth2resource
@Test
void useRefreshTokenOnTokenExpiration() throws Exception {
mockAuthorizationServer.expiresIn = 1;

var excCallResource = browser.apply(get(tc.getClientAddress() + "/init"));
var body2 = om.readValue(excCallResource.getResponse().getBodyAsStream(), Map.class);
assertEquals("/init", body2.get("path"));

Set<String> accessTokens = new HashSet<>();
runInParallel((cdl) -> parallelTestWorker(cdl, accessTokens), tc.limit);
synchronized (accessTokens) {
assertEquals(accessTokens.size(), tc.limit);
}
}

private void runInParallel(Consumer<CountDownLatch> job, int threadCount) {
List<Thread> threadList = new ArrayList<>();
CountDownLatch cdl = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
threadList.add(new Thread(() -> job.accept(cdl)));
}
threadList.forEach(Thread::start);
threadList.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}

private void parallelTestWorker(CountDownLatch cdl, Set<String> accessTokens) {
try {
cdl.countDown();
cdl.await();

String uuid = UUID.randomUUID().toString();
var excCallResource2 = browser.apply(get(tc.getClientAddress() + "/api/" + uuid));

var body = om.readValue(excCallResource2.getResponse().getBodyAsStringDecoded(), Map.class);
String path = (String) body.get("path");
assertEquals("/api/" + uuid, path);
synchronized (accessTokens) {
accessTokens.add((String) body.get("accessToken"));
}
} catch (Exception e) {
e.printStackTrace();
}
}


@Test
void stateAttack() throws Exception {
AtomicReference<String> ref = new AtomicReference<>();
Expand Down Expand Up @@ -538,8 +453,6 @@ public void api1and2() throws Exception {
assertTrue(((String)body.get("accessToken")).startsWith("eyJ"));
}

protected abstract SessionManager createSessionManager();

private JwtConsumer createJwtConsumer(String expectedAudience) {
return new JwtConsumerBuilder()
.setRequireExpirationTime()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.predic8.membrane.core.interceptor.session.FakeSyncSessionStoreManager;
import com.predic8.membrane.core.interceptor.session.SessionManager;

public class SyncB2CResourceTest extends OAuth2ResourceB2CTest {
public class SyncB2CResourceTest extends OAuth2ResourceB2CUnitTest {
@Override
protected SessionManager createSessionManager() {
return new FakeSyncSessionStoreManager();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.predic8.membrane.integration;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
IntegrationTestsWithoutInternet.class,
IntegrationTestsWithInternet.class
})
public class IntegrationTests {
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.interceptor.rewrite;
package com.predic8.membrane.integration.withinternet.interceptor;

import com.predic8.membrane.core.*;
import com.predic8.membrane.core.http.Header;
import com.predic8.membrane.core.http.*;
import com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptor;
import com.predic8.membrane.core.interceptor.rewrite.RewriteInterceptor.*;
import com.predic8.membrane.core.proxies.*;
import org.apache.commons.httpclient.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.interceptor.beautifier;
package com.predic8.membrane.integration.withoutinternet.interceptor;

import com.predic8.membrane.*;
import com.predic8.membrane.core.interceptor.beautifier.BeautifierInterceptor;
import com.predic8.membrane.core.interceptor.flow.*;
import com.predic8.membrane.core.openapi.serviceproxy.*;
import org.junit.jupiter.api.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core;
package com.predic8.membrane.integration.withoutinternet.interceptor;

import com.predic8.membrane.core.HttpRouter;
import com.predic8.membrane.core.Router;
import com.predic8.membrane.core.interceptor.flow.*;
import com.predic8.membrane.core.interceptor.log.*;
import com.predic8.membrane.core.openapi.serviceproxy.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.interceptor.rest;
package com.predic8.membrane.integration.withoutinternet.interceptor;

import com.predic8.membrane.core.*;
import com.predic8.membrane.core.interceptor.rest.REST2SOAPInterceptor;
import com.predic8.membrane.core.interceptor.rest.REST2SOAPInterceptor.*;
import com.predic8.membrane.core.interceptor.soap.*;
import com.predic8.membrane.core.proxies.*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.predic8.membrane.core.proxies;
package com.predic8.membrane.integration.withoutinternet.interceptor;

import com.predic8.membrane.core.*;
import com.predic8.membrane.core.interceptor.soap.*;
import com.predic8.membrane.core.proxies.ServiceProxy;
import com.predic8.membrane.core.proxies.ServiceProxyKey;
import org.junit.jupiter.api.*;

import static com.predic8.membrane.core.http.MimeType.*;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.predic8.membrane.integration.withoutinternet.interceptor.oauth2;

import com.predic8.membrane.core.interceptor.session.InMemorySessionManager;
import com.predic8.membrane.core.interceptor.session.SessionManager;

public class InMemB2CResourceIntegrationTest extends OAuth2ResourceB2CIntegrationTest {
@Override
protected SessionManager createSessionManager() {
return new InMemorySessionManager();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.predic8.membrane.integration.withoutinternet.interceptor.oauth2;

import com.predic8.membrane.core.interceptor.session.SessionManager;

public class JwtB2CResourceIntegrationTest extends OAuth2ResourceB2CIntegrationTest {
@Override
protected SessionManager createSessionManager() {
return null;
}
}
Loading