diff --git a/pom.xml b/pom.xml
index f33ec63..2133628 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,8 +53,8 @@
- 5.5.0
- 6.0.0-RC1
+ 5.6.0
+ 6.0.0-RC7
17
diff --git a/src/main/java/org/pac4j/javalin/CallbackHandler.java b/src/main/java/org/pac4j/javalin/CallbackHandler.java
index 7975ce5..d3827f6 100644
--- a/src/main/java/org/pac4j/javalin/CallbackHandler.java
+++ b/src/main/java/org/pac4j/javalin/CallbackHandler.java
@@ -3,14 +3,9 @@
import io.javalin.http.Context;
import io.javalin.http.Handler;
import org.jetbrains.annotations.NotNull;
+import org.pac4j.core.adapter.FrameworkAdapter;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.session.SessionStore;
-import org.pac4j.core.context.session.SessionStoreFactory;
-import org.pac4j.core.engine.CallbackLogic;
-import org.pac4j.core.engine.DefaultCallbackLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
-import org.pac4j.core.util.FindBest;
-import org.pac4j.jee.context.session.JEESessionStoreFactory;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import static org.pac4j.core.util.CommonHelper.assertNotNull;
@@ -36,19 +31,15 @@ public CallbackHandler(Config config, String defaultUrl, Boolean renewSession) {
@Override
public void handle(@NotNull Context javalinCtx) {
- final SessionStoreFactory sessionStoreFactory = FindBest.sessionStoreFactory(null, config, JEESessionStoreFactory.INSTANCE);
- final SessionStore sessionStore = sessionStoreFactory.newSessionStore(javalinCtx);
- final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JavalinHttpActionAdapter.INSTANCE);
- final CallbackLogic bestCallbackLogic = FindBest.callbackLogic(null, config, DefaultCallbackLogic.INSTANCE);
-
- JavalinWebContext context = new JavalinWebContext(javalinCtx);
- bestCallbackLogic.perform(context,
- sessionStore,
+ FrameworkAdapter.INSTANCE.applyDefaultSettingsIfUndefined(config);
+
+ config.getCallbackLogic().perform(
this.config,
- bestAdapter,
this.defaultUrl,
this.renewSession,
- config.getClients().getClients().get(0).getName()
+ config.getClients().getClients().get(0).getName(),
+ new JEEFrameworkParameters(javalinCtx.req(), javalinCtx.res())
);
+
}
}
diff --git a/src/main/java/org/pac4j/javalin/JavalinHttpActionAdapter.java b/src/main/java/org/pac4j/javalin/JavalinHttpActionAdapter.java
index e6d7762..0f22aac 100644
--- a/src/main/java/org/pac4j/javalin/JavalinHttpActionAdapter.java
+++ b/src/main/java/org/pac4j/javalin/JavalinHttpActionAdapter.java
@@ -2,7 +2,6 @@
import io.javalin.http.BadRequestResponse;
import io.javalin.http.ForbiddenResponse;
-import io.javalin.http.HttpStatus;
import io.javalin.http.RedirectResponse;
import io.javalin.http.UnauthorizedResponse;
import org.pac4j.core.context.HttpConstants;
@@ -12,6 +11,10 @@
import org.pac4j.core.exception.http.WithLocationAction;
import org.pac4j.core.http.adapter.HttpActionAdapter;
import org.pac4j.core.util.CommonHelper;
+import org.pac4j.jee.context.JEEContext;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
/**
* @author Maximilian Hippler
@@ -24,10 +27,10 @@ public class JavalinHttpActionAdapter implements HttpActionAdapter {
public Void adapt(HttpAction action, WebContext webContext) {
CommonHelper.assertNotNull("action", action);
CommonHelper.assertNotNull("context", webContext);
- if (webContext instanceof JavalinWebContext == false) {
- throw new RuntimeException("not a Javalin web context, but " + webContext.getClass().getName());
+ if (webContext instanceof JEEContext == false) {
+ throw new RuntimeException("not a JEEContext, but " + webContext.getClass().getName());
}
- JavalinWebContext context = (JavalinWebContext) webContext;
+ JEEContext context = (JEEContext) webContext;
final int code = action.getCode();
if (code == HttpConstants.UNAUTHORIZED) {
@@ -37,14 +40,22 @@ public Void adapt(HttpAction action, WebContext webContext) {
} else if (code == HttpConstants.BAD_REQUEST) {
throw new BadRequestResponse();
} else if (action instanceof WithContentAction){
- context.getJavalinCtx().status(action.getCode());
- context.getJavalinCtx().result(((WithContentAction) action).getContent());
+ context.getNativeResponse().setStatus(action.getCode());
+ String responseData = ((WithContentAction) action).getContent();
+ context.getNativeResponse().setContentLength(responseData.length());
+ try {
+ context.getNativeResponse().getOutputStream().write(responseData.getBytes(StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
return null;
} else if (action instanceof WithLocationAction) {
- context.getJavalinCtx().redirect(((WithLocationAction) action).getLocation(), HttpStatus.forStatus(action.getCode()));
+ context.getNativeResponse().setStatus(action.getCode());
+ String location = ((WithLocationAction) action).getLocation();
+ context.getNativeResponse().setHeader("Location", location);
throw new RedirectResponse();
} else {
- context.getJavalinCtx().status(action.getCode());
+ context.getNativeResponse().setStatus(action.getCode());
return null;
}
}
diff --git a/src/main/java/org/pac4j/javalin/JavalinWebContext.java b/src/main/java/org/pac4j/javalin/JavalinWebContext.java
deleted file mode 100644
index 2dfe9ac..0000000
--- a/src/main/java/org/pac4j/javalin/JavalinWebContext.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.pac4j.javalin;
-
-import io.javalin.http.Context;
-import org.pac4j.jee.context.JEEContext;
-
-/**
- * @author Maximilian Hippler
- * @since 3.0.0
- */
-public class JavalinWebContext extends JEEContext {
- private final Context javalinCtx;
-
- public JavalinWebContext(Context javalinCtx) {
- super(javalinCtx.req(), javalinCtx.res());
- this.javalinCtx = javalinCtx;
- }
-
- public Context getJavalinCtx() {
- return javalinCtx;
- }
-
- @Override
- public String getPath() {
- return javalinCtx.path();
- }
-}
diff --git a/src/main/java/org/pac4j/javalin/LogoutHandler.java b/src/main/java/org/pac4j/javalin/LogoutHandler.java
index a445388..dcd1ec9 100644
--- a/src/main/java/org/pac4j/javalin/LogoutHandler.java
+++ b/src/main/java/org/pac4j/javalin/LogoutHandler.java
@@ -3,14 +3,9 @@
import io.javalin.http.Context;
import io.javalin.http.Handler;
import org.jetbrains.annotations.NotNull;
+import org.pac4j.core.adapter.FrameworkAdapter;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.session.SessionStore;
-import org.pac4j.core.context.session.SessionStoreFactory;
-import org.pac4j.core.engine.DefaultLogoutLogic;
-import org.pac4j.core.engine.LogoutLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
-import org.pac4j.core.util.FindBest;
-import org.pac4j.jee.context.session.JEESessionStoreFactory;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import static org.pac4j.core.util.CommonHelper.assertNotNull;
@@ -39,21 +34,16 @@ public LogoutHandler(Config config, String defaultUrl, String logoutUrlPattern)
@Override
public void handle(@NotNull Context javalinCtx) {
- final SessionStoreFactory sessionStoreFactory = FindBest.sessionStoreFactory(null, config, JEESessionStoreFactory.INSTANCE);
- final SessionStore sessionStore = sessionStoreFactory.newSessionStore(javalinCtx);
- final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JavalinHttpActionAdapter.INSTANCE);
- final LogoutLogic bestLogic = FindBest.logoutLogic(null, config, DefaultLogoutLogic.INSTANCE);
-
- bestLogic.perform(
- new JavalinWebContext(javalinCtx),
- sessionStore,
+ FrameworkAdapter.INSTANCE.applyDefaultSettingsIfUndefined(config);
+
+ config.getLogoutLogic().perform(
this.config,
- bestAdapter,
this.defaultUrl,
this.logoutUrlPattern,
this.localLogout,
this.destroySession,
- this.centralLogout
+ this.centralLogout,
+ new JEEFrameworkParameters(javalinCtx.req(), javalinCtx.res())
);
}
}
diff --git a/src/main/java/org/pac4j/javalin/SecurityHandler.java b/src/main/java/org/pac4j/javalin/SecurityHandler.java
index 8217d08..b2a883d 100644
--- a/src/main/java/org/pac4j/javalin/SecurityHandler.java
+++ b/src/main/java/org/pac4j/javalin/SecurityHandler.java
@@ -4,14 +4,9 @@
import io.javalin.http.Handler;
import io.javalin.http.servlet.JavalinServletContext;
import org.jetbrains.annotations.NotNull;
+import org.pac4j.core.adapter.FrameworkAdapter;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.session.SessionStore;
-import org.pac4j.core.context.session.SessionStoreFactory;
-import org.pac4j.core.engine.DefaultSecurityLogic;
-import org.pac4j.core.engine.SecurityLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
-import org.pac4j.core.util.FindBest;
-import org.pac4j.jee.context.session.JEESessionStoreFactory;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import static org.pac4j.core.util.CommonHelper.assertNotNull;
@@ -41,21 +36,15 @@ public SecurityHandler(Config config, String clients, String authorizers, String
@Override
public void handle(@NotNull Context javalinCtx) {
- final SessionStoreFactory sessionStoreFactory = FindBest.sessionStoreFactory(null, config, JEESessionStoreFactory.INSTANCE);
- final SessionStore sessionStore = sessionStoreFactory.newSessionStore(javalinCtx);
- final HttpActionAdapter bestAdapter = FindBest.httpActionAdapter(null, config, JavalinHttpActionAdapter.INSTANCE);
- final SecurityLogic bestLogic = FindBest.securityLogic(null, config, DefaultSecurityLogic.INSTANCE);
+ FrameworkAdapter.INSTANCE.applyDefaultSettingsIfUndefined(config);
- JavalinWebContext context = new JavalinWebContext(javalinCtx);
- Object result = bestLogic.perform(
- context,
- sessionStore,
+ Object result = config.getSecurityLogic().perform(
this.config,
- (ctx, store, profiles, parameters) -> AUTH_GRANTED,
- bestAdapter,
+ (ctx, store, profiles) -> AUTH_GRANTED,
this.clients,
this.authorizers,
- this.matchers
+ this.matchers,
+ new JEEFrameworkParameters(javalinCtx.req(), javalinCtx.res())
);
if (result != AUTH_GRANTED) {
((JavalinServletContext) javalinCtx).getTasks().clear(); // Used to throw UnauthorizedResponse
diff --git a/src/test/java/org/pac4j/javalin/CallbackHandlerTest.java b/src/test/java/org/pac4j/javalin/CallbackHandlerTest.java
index 9a7b119..6736338 100644
--- a/src/test/java/org/pac4j/javalin/CallbackHandlerTest.java
+++ b/src/test/java/org/pac4j/javalin/CallbackHandlerTest.java
@@ -6,143 +6,60 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.WebContext;
-import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.engine.CallbackLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
import org.pac4j.http.client.indirect.FormClient;
-import org.pac4j.jee.context.session.JEESessionStore;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
public class CallbackHandlerTest {
- private final TestCallbackLogic testCallbackLogic = new TestCallbackLogic();
+ private final CallbackLogic callbackLogic = mock(CallbackLogic.class);
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse res = mock(HttpServletResponse.class);
private final Context ctx = mock(Context.class);
private final FormClient formClient = new FormClient();
private final Config config = new Config(formClient);
- private final CallbackHandler handler = new CallbackHandler(config, "DefaultClient");
@BeforeEach
public void setCallbackLogic() {
- config.setCallbackLogic(testCallbackLogic);
+ config.setCallbackLogic(callbackLogic);
formClient.setCallbackUrl("http://example.org/callbackUrl");
when(ctx.res()).thenReturn(res);
when(ctx.req()).thenReturn(req);
}
@Test
- public void testDefaultSessionStore() {
+ public void testDefaultUrlIsNull() {
+ CallbackHandler handler = new CallbackHandler(config);
handler.handle(ctx);
- assertThat(testCallbackLogic.sessionStore).isEqualTo(JEESessionStore.INSTANCE);
- assertThat(testCallbackLogic.webContext).isExactlyInstanceOf(JavalinWebContext.class);
- assertThat(testCallbackLogic.config).isSameAs(config);
+ verify(callbackLogic).perform(eq(config), isNull(), any(), eq("FormClient"), any());
}
@Test
- public void testCustomSessionStore() {
- final SessionStore mockSessionStore = mock(SessionStore.class);
- config.setSessionStoreFactory(parameters -> mockSessionStore);
-
+ public void testDefaultUrl() {
+ CallbackHandler handler = new CallbackHandler(config, "/my-url");
handler.handle(ctx);
- assertThat(testCallbackLogic.sessionStore).isNotEqualTo(JEESessionStore.INSTANCE);
- assertThat(testCallbackLogic.sessionStore).isEqualTo(mockSessionStore);
+ verify(callbackLogic).perform(eq(config), eq("/my-url"), any(), any(), any());
}
@Test
- public void testDefaultAdapter() {
- handler.handle(ctx);
-
- assertThat(testCallbackLogic.httpActionAdapter).isEqualTo(JavalinHttpActionAdapter.INSTANCE);
- }
-
- @Test
- public void testCustomAdapter() {
- HttpActionAdapter actionAdapter = new JavalinHttpActionAdapter();
- config.setHttpActionAdapter(actionAdapter);
+ public void testRenewSession() {
+ CallbackHandler handler = new CallbackHandler(config, "/my-url", true);
handler.handle(ctx);
- assertThat(testCallbackLogic.httpActionAdapter).isNotEqualTo(JavalinHttpActionAdapter.INSTANCE);
- assertThat(testCallbackLogic.httpActionAdapter).isEqualTo(actionAdapter);
+ verify(callbackLogic).perform(eq(config), any(), eq(true), any(), any());
}
@Test
- public void testCustomClientName() {
- formClient.setName("my-name");
-
- handler.handle(ctx);
+ public void testRenewSessionFalse() {
+ CallbackHandler handler = new CallbackHandler(config, "/my-url", false);
- assertThat(testCallbackLogic.defaultClient).isEqualTo("my-name");
- }
-
- @Test
- public void testCustomDefaultUrl() {
- final Config config = new Config(formClient);
- config.setCallbackLogic(testCallbackLogic);
- final CallbackHandler handler = new CallbackHandler(config, "http://example.org", true);
-
- handler.handle(ctx);
-
- assertThat(testCallbackLogic.defaultUrl).isEqualTo("http://example.org");
- }
-
- @Test
- public void testDefaultRenewSession() {
handler.handle(ctx);
- assertThat(testCallbackLogic.renewSession).isNull();
- }
-
- @Test
- public void testCustomRenewSessionTrue() {
- final Config config = new Config(formClient);
- config.setCallbackLogic(testCallbackLogic);
- final CallbackHandler handler = new CallbackHandler(config, "http://example.org", true);
-
- handler.handle(ctx);
-
- assertThat(testCallbackLogic.renewSession).isTrue();
- }
-
- @Test
- public void testCustomRenewSessionFalse() {
- final Config config = new Config(formClient);
- config.setCallbackLogic(testCallbackLogic);
- final CallbackHandler handler = new CallbackHandler(config, "http://example.org", false);
-
- handler.handle(ctx);
-
- assertThat(testCallbackLogic.renewSession).isFalse();
- }
-
- public static class TestCallbackLogic implements CallbackLogic {
-
- private WebContext webContext;
- private SessionStore sessionStore;
- private Config config;
- private HttpActionAdapter httpActionAdapter;
- private String defaultUrl;
- private Boolean renewSession;
- private String defaultClient;
-
- @Override
- public Object perform(WebContext webContext, SessionStore sessionStore, Config config,
- HttpActionAdapter httpActionAdapter, String defaultUrl, Boolean renewSession, String defaultClient) {
- this.webContext = webContext;
- this.sessionStore = sessionStore;
- this.config = config;
- this.httpActionAdapter = httpActionAdapter;
- this.defaultUrl = defaultUrl;
- this.renewSession = renewSession;
- this.defaultClient = defaultClient;
- return null;
- }
+ verify(callbackLogic).perform(eq(config), any(), eq(false), any(), any());
}
}
diff --git a/src/test/java/org/pac4j/javalin/JavalinHttpActionAdapterTest.java b/src/test/java/org/pac4j/javalin/JavalinHttpActionAdapterTest.java
index 928c099..4a541b6 100644
--- a/src/test/java/org/pac4j/javalin/JavalinHttpActionAdapterTest.java
+++ b/src/test/java/org/pac4j/javalin/JavalinHttpActionAdapterTest.java
@@ -3,9 +3,9 @@
import io.javalin.http.BadRequestResponse;
import io.javalin.http.Context;
import io.javalin.http.ForbiddenResponse;
-import io.javalin.http.HttpStatus;
import io.javalin.http.RedirectResponse;
import io.javalin.http.UnauthorizedResponse;
+import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
@@ -19,25 +19,24 @@
import org.pac4j.core.exception.http.UnauthorizedAction;
import org.pac4j.jee.context.JEEContext;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
-import static org.mockito.Mockito.when;
-@SuppressWarnings("PMD.TooManyStaticImports")
class JavalinHttpActionAdapterTest {
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse res = mock(HttpServletResponse.class);
private final Context ctx = mock(Context.class);
- private JavalinWebContext context;
+ private final JEEContext context = new JEEContext(req, res);
@BeforeEach
public void setupMocks() {
when(ctx.res()).thenReturn(res);
when(ctx.req()).thenReturn(req);
- context = new JavalinWebContext(ctx);
}
@Test
@@ -53,20 +52,17 @@ public void testContextNotNull() {
}
@Test
- public void testContextNoJavalinWebContext() {
- final JEEContext jeeContext = new JEEContext(req, res);
- assertThatThrownBy(() -> JavalinHttpActionAdapter.INSTANCE.adapt(new OkAction(""), jeeContext))
- .hasMessageContaining("not a Javalin web context");
- }
+ public void testAdapterWithContentAction() throws IOException {
+ ServletOutputStream sos = mock(ServletOutputStream.class);
+ when(res.getOutputStream()).thenReturn(sos);
- @Test
- public void testAdapterWithContentAction() {
JavalinHttpActionAdapter.INSTANCE.adapt(new OkAction("my-content"), context);
- verify(ctx).status(200);
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
- verify(ctx).result(captor.capture());
- assertThat(captor.getValue()).isEqualTo("my-content");
+ verify(res).setStatus(eq(200));
+ ArgumentCaptor captor = ArgumentCaptor.forClass(byte[].class);
+ verify(sos).write(captor.capture());
+ byte[] value = captor.getValue();
+ assertThat(new String(value, StandardCharsets.UTF_8)).isEqualTo("my-content");
}
@Test
@@ -74,9 +70,8 @@ public void testAdapterWithLocationAction() {
assertThatThrownBy(() -> JavalinHttpActionAdapter.INSTANCE.adapt(new FoundAction("/redirect"), context))
.isExactlyInstanceOf(RedirectResponse.class);
- ArgumentCaptor captor = ArgumentCaptor.forClass(String.class);
- verify(ctx).redirect(captor.capture(), eq(HttpStatus.FOUND));
- assertThat(captor.getValue()).isEqualTo("/redirect");
+ verify(res).setStatus(eq(302));
+ verify(res).setHeader(eq("Location"), eq("/redirect"));
}
@Test
@@ -101,6 +96,6 @@ public void testAdapterBadRequest() {
public void testAdapterAnyOtherStatus() {
JavalinHttpActionAdapter.INSTANCE.adapt(new HttpAction(123) {}, context);
- verify(ctx).status(123);
+ verify(res).setStatus(eq(123));
}
}
\ No newline at end of file
diff --git a/src/test/java/org/pac4j/javalin/LogoutHandlerTest.java b/src/test/java/org/pac4j/javalin/LogoutHandlerTest.java
index 8d64811..1041fcc 100644
--- a/src/test/java/org/pac4j/javalin/LogoutHandlerTest.java
+++ b/src/test/java/org/pac4j/javalin/LogoutHandlerTest.java
@@ -5,24 +5,21 @@
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.WebContext;
-import org.pac4j.core.context.session.SessionStore;
+import org.pac4j.core.context.FrameworkParameters;
import org.pac4j.core.engine.LogoutLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
import org.pac4j.http.client.indirect.FormClient;
-import org.pac4j.jee.context.session.JEESessionStore;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
public class LogoutHandlerTest {
- private final TestLogoutLogic logoutLogic = new TestLogoutLogic();
- private final FormClient formClient = new FormClient();
- private final Config config = new Config(formClient);
- private final LogoutHandler handler = new LogoutHandler(config);
+ private final LogoutLogic logoutLogic = mock(LogoutLogic.class);
+ private final Config config = new Config(new FormClient());
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse res = mock(HttpServletResponse.class);
private final Context ctx = mock(Context.class);
@@ -35,144 +32,95 @@ public void setCallbackLogic() {
}
@Test
- public void testDefaultSessionStore() {
+ public void testCustomLogoutLogic() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.handle(ctx);
- assertThat(logoutLogic.sessionStore).isSameAs(JEESessionStore.INSTANCE);
+ verify(logoutLogic).perform(any(), any(), any(), any(), any(), any(), any());
}
@Test
- public void testCustomSessionStore() {
- final SessionStore mockSessionStore = mock(SessionStore.class);
- config.setSessionStoreFactory(parameters -> mockSessionStore);
-
- handler.handle(ctx);
-
- assertThat(logoutLogic.sessionStore).isSameAs(mockSessionStore);
- }
-
- @Test
- public void testDefaultHttpActionAdapter() {
+ public void testDefaultUrl() {
+ LogoutHandler handler = new LogoutHandler(config, "https://example.org");
handler.handle(ctx);
- assertThat(logoutLogic.httpActionAdapter).isSameAs(JavalinHttpActionAdapter.INSTANCE);
+ verify(logoutLogic).perform(any(), eq("https://example.org"), any(), any(), any(), any(), any());
}
@Test
- public void testCustomHttpActionAdapter() {
- final JavalinHttpActionAdapter adapter = new JavalinHttpActionAdapter();
- config.setHttpActionAdapter(adapter);
-
- handler.handle(ctx);
-
- assertThat(logoutLogic.httpActionAdapter).isSameAs(adapter);
- }
-
- @Test
- public void testCustomDefaultUrl() {
- LogoutHandler handler = new LogoutHandler(config, "http://example.org");
-
- handler.handle(ctx);
-
- assertThat(logoutLogic.defaultUrl).isEqualTo("http://example.org");
- }
-
- @Test
- public void testCustomLogoutUrlPattern() {
- final String logoutUrlPattern = "http://example.org/logout/*";
- LogoutHandler handler = new LogoutHandler(config, "http://example.org", logoutUrlPattern);
-
+ public void testLogoutUrlPattern() {
+ LogoutHandler handler = new LogoutHandler(config, "https://example.org", "/logout");
handler.handle(ctx);
- assertThat(logoutLogic.logoutUrlPattern).isEqualTo(logoutUrlPattern);
- }
-
- @Test
- public void testLocalLogoutDefault() {
- handler.handle(ctx);
- assertThat(logoutLogic.localLogout).isNull();
+ verify(logoutLogic).perform(any(), eq("https://example.org"), eq("/logout"), any(), any(), any(), any());
}
@Test
public void testLocalLogoutTrue() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.localLogout = true;
handler.handle(ctx);
- assertThat(logoutLogic.localLogout).isTrue();
+
+ verify(logoutLogic).perform(any(), any(), any(), eq(true), any(), any(), any());
}
@Test
public void testLocalLogoutFalse() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.localLogout = false;
handler.handle(ctx);
- assertThat(logoutLogic.localLogout).isFalse();
- }
- @Test
- public void testDestroySessionDefault() {
- handler.handle(ctx);
- assertThat(logoutLogic.destroySession).isNull();
+ verify(logoutLogic).perform(any(), any(), any(), eq(false), any(), any(), any());
}
@Test
- public void testDestroySessionTrue() {
+ public void testDestroySession() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.destroySession = true;
handler.handle(ctx);
- assertThat(logoutLogic.destroySession).isTrue();
+
+ verify(logoutLogic).perform(any(), any(), any(),any(), eq(true), any(), any());
}
@Test
public void testDestroySessionFalse() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.destroySession = false;
handler.handle(ctx);
- assertThat(logoutLogic.destroySession).isFalse();
- }
- @Test
- public void testCentralLogoutDefault() {
- handler.handle(ctx);
- assertThat(logoutLogic.centralLogout).isNull();
+ verify(logoutLogic).perform(any(), any(), any(),any(), eq(false), any(), any());
}
@Test
- public void testCentralLogoutTrue() {
+ public void testCentralLogout() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.centralLogout = true;
handler.handle(ctx);
- assertThat(logoutLogic.centralLogout).isTrue();
+
+ verify(logoutLogic).perform(any(), any(), any(),any(), any(), eq(true), any());
}
@Test
public void testCentralLogoutFalse() {
+ LogoutHandler handler = new LogoutHandler(config);
handler.centralLogout = false;
handler.handle(ctx);
- assertThat(logoutLogic.centralLogout).isFalse();
+
+ verify(logoutLogic).perform(any(), any(), any(),any(), any(), eq(false), any());
}
- public static class TestLogoutLogic implements LogoutLogic {
-
- private WebContext context;
- private SessionStore sessionStore;
- private Config config;
- private HttpActionAdapter httpActionAdapter;
- private String defaultUrl;
- private String logoutUrlPattern;
- private Boolean localLogout;
- private Boolean destroySession;
- private Boolean centralLogout;
-
- @Override
- public Object perform(WebContext context, SessionStore sessionStore, Config config, HttpActionAdapter httpActionAdapter,
- String defaultUrl, String logoutUrlPattern,
- Boolean localLogout, Boolean destroySession, Boolean centralLogout) {
- this.context = context;
- this.sessionStore = sessionStore;
- this.config = config;
- this.httpActionAdapter = httpActionAdapter;
- this.defaultUrl = defaultUrl;
- this.logoutUrlPattern = logoutUrlPattern;
- this.localLogout = localLogout;
- this.destroySession = destroySession;
- this.centralLogout = centralLogout;
- return null;
- }
+ @Test
+ public void testContext() {
+ LogoutHandler handler = new LogoutHandler(config);
+ handler.handle(ctx);
+
+ ArgumentCaptor captor = ArgumentCaptor.forClass(FrameworkParameters.class);
+ verify(logoutLogic).perform(any(), any(), any(), any(), any(), any(), captor.capture());
+ FrameworkParameters parameters = captor.getValue();
+ assertThat(parameters).isExactlyInstanceOf(JEEFrameworkParameters.class);
+
+ JEEFrameworkParameters jeeFrameworkParameters = (JEEFrameworkParameters) parameters;
+ assertThat(jeeFrameworkParameters.getRequest()).isSameAs(req);
+ assertThat(jeeFrameworkParameters.getResponse()).isSameAs(res);
}
}
diff --git a/src/test/java/org/pac4j/javalin/SecurityHandlerTest.java b/src/test/java/org/pac4j/javalin/SecurityHandlerTest.java
index 38ef16d..33d1e37 100644
--- a/src/test/java/org/pac4j/javalin/SecurityHandlerTest.java
+++ b/src/test/java/org/pac4j/javalin/SecurityHandlerTest.java
@@ -1,134 +1,70 @@
package org.pac4j.javalin;
-import io.javalin.http.Context;
-import io.javalin.http.UnauthorizedResponse;
+import io.javalin.http.servlet.JavalinServletContext;
+import io.javalin.http.servlet.Task;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.pac4j.core.config.Config;
-import org.pac4j.core.context.WebContext;
-import org.pac4j.core.context.session.SessionStore;
-import org.pac4j.core.engine.SecurityGrantedAccessAdapter;
import org.pac4j.core.engine.SecurityLogic;
-import org.pac4j.core.http.adapter.HttpActionAdapter;
import org.pac4j.http.client.indirect.FormClient;
-import org.pac4j.jee.context.session.JEESessionStore;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import java.util.Deque;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
public class SecurityHandlerTest {
- private final TestSecurityLogic securityLogic = new TestSecurityLogic();
- private final FormClient formClient = new FormClient();
- private final Config config = new Config(formClient);
- private final SecurityHandler handler = new SecurityHandler(config, "my-clients");
+ private final SecurityLogic securityLogic = mock(SecurityLogic.class);
+ private final Config config = new Config(new FormClient());
private final HttpServletRequest req = mock(HttpServletRequest.class);
private final HttpServletResponse res = mock(HttpServletResponse.class);
- private final Context ctx = mock(Context.class);
+ private final JavalinServletContext ctx = mock(JavalinServletContext.class);
+ private final Deque deque = mock(Deque.class);
@BeforeEach
public void setCallbackLogic() {
config.setSecurityLogic(securityLogic);
when(ctx.res()).thenReturn(res);
when(ctx.req()).thenReturn(req);
+ when(ctx.getTasks()).thenReturn(deque);
+ when(securityLogic.perform(eq(config), any(), any(), any(), any(), any())).thenReturn("AUTH_GRANTED");
}
@Test
- public void testSessionStoreDefault() {
- handler.handle(ctx);
-
- assertThat(securityLogic.sessionStore).isSameAs(JEESessionStore.INSTANCE);
- }
-
- @Test
- public void testSessionStoreCustom() {
- final SessionStore mockSessionStore = mock(SessionStore.class);
- config.setSessionStoreFactory(parameters -> mockSessionStore);
-
- handler.handle(ctx);
-
- assertThat(securityLogic.sessionStore).isSameAs(mockSessionStore);
- }
-
- @Test
- public void testHttpAdapterDefault() {
- handler.handle(ctx);
-
- assertThat(securityLogic.httpActionAdapter).isSameAs(JavalinHttpActionAdapter.INSTANCE);
- }
-
- @Test
- public void testHttpAdapterCustom() {
- final JavalinHttpActionAdapter adapter = new JavalinHttpActionAdapter();
- config.setHttpActionAdapter(adapter);
-
- handler.handle(ctx);
-
- assertThat(securityLogic.httpActionAdapter).isSameAs(adapter);
- }
-
- @Test
- public void testClients() {
+ public void testCustomSecurityLogic() {
+ SecurityHandler handler = new SecurityHandler(config, "my-clients");
handler.handle(ctx);
- assertThat(securityLogic.clients).isEqualTo("my-clients");
+ verify(securityLogic).perform(eq(config), any(), eq("my-clients"), any(), any(), any());
}
@Test
public void testCustomAuthorizers() {
- handler.authorizers = "my-authorizers";
-
+ SecurityHandler handler = new SecurityHandler(config, "my-clients", "my-authorizers");
handler.handle(ctx);
- assertThat(securityLogic.authorizers).isEqualTo("my-authorizers");
+ verify(securityLogic).perform(eq(config), any(), any(), eq("my-authorizers"), any(), any());
}
@Test
public void testCustomMatchers() {
- handler.matchers = "my-matchers";
-
+ SecurityHandler handler = new SecurityHandler(config, "my-clients", "my-authorizers", "my-matchers");
handler.handle(ctx);
- assertThat(securityLogic.matchers).isEqualTo("my-matchers");
+ verify(securityLogic).perform(eq(config), any(), any(), eq("my-authorizers"), eq("my-matchers"), any());
}
@Test
- @Disabled("Waiting for the Javalin project to remove the final keyword on JavalinServletContext")
- public void testResultNotGranted() {
- securityLogic.result = "WHATEVER";
-
- assertThatThrownBy(() -> handler.handle(ctx)).isExactlyInstanceOf(UnauthorizedResponse.class);
- }
+ public void clearTasksWhenAuthNotGranted() {
+ when(securityLogic.perform(eq(config), any(), any(), any(), any(), any())).thenReturn("AUTH_DENIED");
- private static final class TestSecurityLogic implements SecurityLogic {
-
- private String result = "AUTH_GRANTED";
- private WebContext context;
- private SessionStore sessionStore;
- private Config config;
- private SecurityGrantedAccessAdapter securityGrantedAccessAdapter;
- private HttpActionAdapter httpActionAdapter;
- private String clients;
- private String authorizers;
- private String matchers;
-
- @Override
- public Object perform(WebContext context, SessionStore sessionStore, Config config, SecurityGrantedAccessAdapter securityGrantedAccessAdapter, HttpActionAdapter httpActionAdapter, String clients, String authorizers, String matchers, Object... parameters) {
- this.context = context;
- this.sessionStore = sessionStore;
- this.config = config;
- this.securityGrantedAccessAdapter = securityGrantedAccessAdapter;
- this.httpActionAdapter = httpActionAdapter;
- this.clients = clients;
- this.authorizers = authorizers;
- this.matchers = matchers;
+ SecurityHandler handler = new SecurityHandler(config, "my-clients");
+ handler.handle(ctx);
- return result;
- }
+ verify(ctx).getTasks();
+ verify(deque).clear();
}
}
diff --git a/src/test/java/org/pac4j/javalin/example/ExampleConfigFactory.java b/src/test/java/org/pac4j/javalin/example/ExampleConfigFactory.java
index 6f5c8d6..15a2dd4 100644
--- a/src/test/java/org/pac4j/javalin/example/ExampleConfigFactory.java
+++ b/src/test/java/org/pac4j/javalin/example/ExampleConfigFactory.java
@@ -11,12 +11,15 @@
import org.pac4j.core.credentials.authenticator.Authenticator;
import org.pac4j.core.matching.matcher.PathMatcher;
import org.pac4j.core.profile.CommonProfile;
+import org.pac4j.core.profile.factory.ProfileManagerFactory;
import org.pac4j.core.util.CommonHelper;
import org.pac4j.http.client.direct.DirectBasicAuthClient;
import org.pac4j.http.client.direct.HeaderClient;
import org.pac4j.http.client.direct.ParameterClient;
import org.pac4j.http.client.indirect.FormClient;
import org.pac4j.http.client.indirect.IndirectBasicAuthClient;
+import org.pac4j.jee.context.JEEContextFactory;
+import org.pac4j.jee.context.session.JEESessionStoreFactory;
import org.pac4j.jwt.config.signature.SecretSignatureConfiguration;
import org.pac4j.jwt.credentials.authenticator.JwtAuthenticator;
import org.pac4j.oauth.client.FacebookClient;
@@ -44,7 +47,7 @@ public Config build(Object... parameters) {
oidcConfiguration.setUseNonce(true);
oidcConfiguration.addCustomParam("prompt", "consent");
OidcClient oidcClient = new OidcClient(oidcConfiguration);
- oidcClient.setAuthorizationGenerator((ctx, sessionStore, profile) -> {
+ oidcClient.setAuthorizationGenerator((ctx, profile) -> {
profile.addRole("ROLE_ADMIN");
return Optional.of(profile);
});
@@ -80,7 +83,7 @@ public Config build(Object... parameters) {
// basic auth
DirectBasicAuthClient directBasicAuthClient = new DirectBasicAuthClient(trivialUserPassAuthenticator);
- HeaderClient headerClient = new HeaderClient("Authorization", (Authenticator) (credentials, ctx, sessionStore) -> {
+ HeaderClient headerClient = new HeaderClient("Authorization", (Authenticator) (ctx, credentials) -> {
String token = ((TokenCredentials) credentials).getToken();
if (CommonHelper.isNotBlank(token)) {
CommonProfile profile = new CommonProfile();
@@ -110,6 +113,9 @@ public Config build(Object... parameters) {
config.addAuthorizer("custom", new CustomAuthorizer());
config.addMatcher("excludedPath", new PathMatcher().excludeRegex("^/facebook/notprotected$"));
config.setHttpActionAdapter(new ExampleHttpActionAdapter());
+ config.setWebContextFactory(JEEContextFactory.INSTANCE);
+ config.setSessionStoreFactory(JEESessionStoreFactory.INSTANCE);
+ config.setProfileManagerFactory(ProfileManagerFactory.DEFAULT);
return config;
}
}
diff --git a/src/test/java/org/pac4j/javalin/example/JavalinPac4jExample.java b/src/test/java/org/pac4j/javalin/example/JavalinPac4jExample.java
index e70534f..e758a8a 100644
--- a/src/test/java/org/pac4j/javalin/example/JavalinPac4jExample.java
+++ b/src/test/java/org/pac4j/javalin/example/JavalinPac4jExample.java
@@ -5,6 +5,8 @@
import io.javalin.rendering.template.JavalinVelocity;
import org.pac4j.core.client.Client;
import org.pac4j.core.config.Config;
+import org.pac4j.core.context.CallContext;
+import org.pac4j.core.context.WebContext;
import org.pac4j.core.exception.http.HttpAction;
import org.pac4j.core.profile.CommonProfile;
import org.pac4j.core.profile.ProfileManager;
@@ -12,9 +14,10 @@
import org.pac4j.http.client.indirect.FormClient;
import org.pac4j.javalin.CallbackHandler;
import org.pac4j.javalin.JavalinHttpActionAdapter;
-import org.pac4j.javalin.JavalinWebContext;
import org.pac4j.javalin.LogoutHandler;
import org.pac4j.javalin.SecurityHandler;
+import org.pac4j.jee.context.JEEContext;
+import org.pac4j.jee.context.JEEFrameworkParameters;
import org.pac4j.jee.context.session.JEESessionStore;
import org.pac4j.jwt.config.signature.SecretSignatureConfiguration;
import org.pac4j.jwt.profile.JwtGenerator;
@@ -35,7 +38,7 @@ public class JavalinPac4jExample {
public static void main(String[] args) {
- Config config = new ExampleConfigFactory(JWT_SALT).build();
+ final Config config = new ExampleConfigFactory(JWT_SALT).build();
CallbackHandler callback = new CallbackHandler(config, null, true);
SecurityHandler facebookSecurityHandler = new SecurityHandler(config, "FacebookClient", "", "excludedPath");
@@ -43,48 +46,48 @@ public static void main(String[] args) {
Javalin.create()
.routes(() -> {
- get("/", JavalinPac4jExample::index);
+ get("/", ctx -> index(ctx, config));
get("/callback", callback);
post("/callback", callback);
before("/facebook", facebookSecurityHandler);
- get("/facebook", JavalinPac4jExample::protectedPage);
+ get("/facebook", ctx -> protectedPage(ctx, config));
before("/facebook/*", facebookSecurityHandler);
- get("/facebook/notprotected", JavalinPac4jExample::protectedPage); // excluded in ExampleConfigFactory
+ get("/facebook/notprotected", ctx -> protectedPage(ctx, config)); // excluded in ExampleConfigFactory
before("/facebookadmin", new SecurityHandler(config, "FacebookClient", "admin"));
- get("/facebookadmin", JavalinPac4jExample::protectedPage);
+ get("/facebookadmin", ctx -> protectedPage(ctx, config));
before("/facebookcustom", new SecurityHandler(config, "FacebookClient", "custom"));
- get("/facebookcustom", JavalinPac4jExample::protectedPage);
+ get("/facebookcustom", ctx -> protectedPage(ctx, config));
before("/twitter", new SecurityHandler(config, "TwitterClient,FacebookClient"));
- get("/twitter", JavalinPac4jExample::protectedPage);
+ get("/twitter", ctx -> protectedPage(ctx, config));
before("/form", new SecurityHandler(config, "FormClient"));
- get("/form", JavalinPac4jExample::protectedPage);
+ get("/form", ctx -> protectedPage(ctx, config));
before("/basicauth", new SecurityHandler(config, "IndirectBasicAuthClient"));
- get("/basicauth", JavalinPac4jExample::protectedPage);
+ get("/basicauth", ctx -> protectedPage(ctx, config));
before("/cas", new SecurityHandler(config, "CasClient"));
- get("/cas", JavalinPac4jExample::protectedPage);
+ get("/cas", ctx -> protectedPage(ctx, config));
before("/saml2", new SecurityHandler(config, "SAML2Client"));
- get("/saml2", JavalinPac4jExample::protectedPage);
+ get("/saml2", ctx -> protectedPage(ctx, config));
before("/oidc", new SecurityHandler(config, "OidcClient"));
- get("/oidc", JavalinPac4jExample::protectedPage);
+ get("/oidc", ctx -> protectedPage(ctx, config));
before("/protected", new SecurityHandler(config, null));
- get("/protected", JavalinPac4jExample::protectedPage);
+ get("/protected", ctx -> protectedPage(ctx, config));
before("/dba", new SecurityHandler(config, "DirectBasicAuthClient,ParameterClient"));
- get("/dba", JavalinPac4jExample::protectedPage);
+ get("/dba", ctx -> protectedPage(ctx, config));
before("/rest-jwt", new SecurityHandler(config, "ParameterClient"));
- get("/rest-jwt", JavalinPac4jExample::protectedPage);
+ get("/rest-jwt", ctx -> protectedPage(ctx, config));
get("/jwt", JavalinPac4jExample::jwt);
@@ -95,14 +98,13 @@ public static void main(String[] args) {
before("/body", new SecurityHandler(config, "HeaderClient"));
post("/body", ctx -> {
logger.debug("Body: " + ctx.body());
- ctx.result("done: " + getProfiles(ctx));
+ ctx.result("done: " + getProfiles(ctx, config));
});
}).exception(Exception.class, (e, ctx) -> {
logger.error("Unexpected exception", e);
ctx.result(e.toString());
}).start(8080);
-
}
private static LogoutHandler centralLogoutHandler(Config config) {
@@ -121,13 +123,12 @@ private static LogoutHandler localLogoutHandler(Config config) {
return localLogout;
}
- private static void index(Context ctx) {
- ctx.render("/templates/index.vm", model("profiles", getProfiles(ctx)));
+ private static void index(Context ctx, Config config) {
+ ctx.render("/templates/index.vm", model("profiles", getProfiles(ctx, config)));
}
private static void jwt(Context ctx) {
- JavalinWebContext context = new JavalinWebContext(ctx);
- ProfileManager manager = new ProfileManager(context, JEESessionStore.INSTANCE);
+ ProfileManager manager = new ProfileManager(new JEEContext(ctx.req(), ctx.res()), JEESessionStore.INSTANCE);
Optional profile = manager.getProfile(CommonProfile.class);
String token = "";
if (profile.isPresent()) {
@@ -145,18 +146,20 @@ private static void form(Context ctx, Config config) {
ctx.render("/templates/loginForm.vm", model("callbackUrl", formClient.getCallbackUrl() + "?client_name=FormClient"));
}
- private static void protectedPage(Context ctx) {
- ctx.render("/templates/protectedPage.vm", model("profiles", getProfiles(ctx)));
+ private static void protectedPage(Context ctx, Config config) {
+ ctx.render("/templates/protectedPage.vm", model("profiles", getProfiles(ctx, config)));
}
- private static List getProfiles(Context ctx) {
- return new ProfileManager(new JavalinWebContext(ctx), JEESessionStore.INSTANCE).getProfiles();
+ private static List getProfiles(Context ctx, Config config) {
+ JEEFrameworkParameters parameters = new JEEFrameworkParameters(ctx.req(), ctx.res());
+ return config.getProfileManagerFactory().apply(
+ config.getWebContextFactory().newContext(parameters),
+ config.getSessionStoreFactory().newSessionStore(parameters)
+ ).getProfiles();
}
private static void forceLogin(Context ctx, Config config) {
- JavalinWebContext context = new JavalinWebContext(ctx);
-
-
+ WebContext context = config.getWebContextFactory().newContext(new JEEFrameworkParameters(ctx.req(), ctx.res()));
String clientName = context.getRequestParameter("FormClient").orElse(null);
if(clientName == null) throw new IllegalStateException("Client name not found");
@@ -165,7 +168,7 @@ private static void forceLogin(Context ctx, Config config) {
HttpAction action;
try {
- action = (HttpAction) client.getRedirectionAction(context, JEESessionStore.INSTANCE).get();
+ action = client.getRedirectionAction(new CallContext(context, JEESessionStore.INSTANCE)).get();
} catch (HttpAction e) {
action = e;
}
diff --git a/src/test/java/org/pac4j/javalin/example/TrivialUserPassAuthenticator.java b/src/test/java/org/pac4j/javalin/example/TrivialUserPassAuthenticator.java
index 6ba32bb..9154b4b 100644
--- a/src/test/java/org/pac4j/javalin/example/TrivialUserPassAuthenticator.java
+++ b/src/test/java/org/pac4j/javalin/example/TrivialUserPassAuthenticator.java
@@ -1,7 +1,6 @@
package org.pac4j.javalin.example;
-import org.pac4j.core.context.WebContext;
-import org.pac4j.core.context.session.SessionStore;
+import org.pac4j.core.context.CallContext;
import org.pac4j.core.credentials.Credentials;
import org.pac4j.core.credentials.UsernamePasswordCredentials;
import org.pac4j.core.credentials.authenticator.Authenticator;
@@ -20,7 +19,7 @@ public TrivialUserPassAuthenticator(String testUsername, String testPassword) {
}
@Override
- public Optional validate(Credentials creds, WebContext context, SessionStore sessionStore) {
+ public Optional validate(CallContext ctx, Credentials creds) {
if (creds instanceof UsernamePasswordCredentials == false) {
throw new CredentialsException("not a username password credential");
}
diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml
index d986a6e..a60d113 100644
--- a/src/test/resources/logback.xml
+++ b/src/test/resources/logback.xml
@@ -4,6 +4,10 @@
JAVALIN PAC4J EXAMPLE %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+