keycloak-aplcache
Changes
audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java 5(+5 -0)
forms/account-api/pom.xml 5(+5 -0)
forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java 13(+13 -0)
Details
diff --git a/audit/api/src/main/java/org/keycloak/audit/Audit.java b/audit/api/src/main/java/org/keycloak/audit/Audit.java
index 682ceb4..4cbd4f7 100644
--- a/audit/api/src/main/java/org/keycloak/audit/Audit.java
+++ b/audit/api/src/main/java/org/keycloak/audit/Audit.java
@@ -20,24 +20,15 @@ public class Audit {
private List<AuditListener> listeners;
private Event event;
- public static Audit create(RealmModel realm, String ipAddress) {
- ProviderFactoryLoader<AuditListenerFactory> loader = ProviderFactoryLoader.load(AuditListenerFactory.class);
-
- List<AuditListener> listeners = null;
- if (realm.getAuditListeners() != null) {
- listeners = new LinkedList<AuditListener>();
-
- for (String id : realm.getAuditListeners()) {
- listeners.add(loader.find(id).create());
- }
- }
+ public Audit(List<AuditListener> listeners, RealmModel realm, String ipAddress) {
+ this.listeners = listeners;
+ this.event = new Event();
- return new Audit(listeners, new Event()).realm(realm).ipAddress(ipAddress);
+ realm(realm);
+ ipAddress(ipAddress);
}
- private Audit(List<AuditListener> listeners, Event event) {
- this.listeners = listeners;
- this.event = event;
+ Audit() {
}
public Audit realm(RealmModel realm) {
@@ -113,7 +104,10 @@ public class Audit {
}
public Audit clone() {
- return new Audit(listeners, event.clone());
+ Audit clone = new Audit();
+ clone.listeners = listeners;
+ clone.event = event.clone();
+ return clone;
}
public Audit reset() {
diff --git a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java b/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
index 75e07c0..339bc64 100644
--- a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
+++ b/audit/api/src/main/java/org/keycloak/audit/EventQuery.java
@@ -7,7 +7,7 @@ import java.util.List;
*/
public interface EventQuery {
- public EventQuery event(String event);
+ public EventQuery event(String... events);
public EventQuery realm(String realmId);
diff --git a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java b/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java
index 420bd67..62322fb 100644
--- a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java
+++ b/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java
@@ -31,4 +31,9 @@ public class JBossLoggingAuditListenerFactory implements AuditListenerFactory {
return ID;
}
+ @Override
+ public boolean lazyLoad() {
+ return false;
+ }
+
}
diff --git a/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java b/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java
index e05ab63..bce26ee 100644
--- a/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java
+++ b/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java
@@ -34,4 +34,9 @@ public class JpaAuditProviderFactory implements AuditProviderFactory {
return ID;
}
+ @Override
+ public boolean lazyLoad() {
+ return true;
+ }
+
}
diff --git a/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java b/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
index f4ec884..b2702d0 100644
--- a/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
+++ b/audit/jpa/src/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java
@@ -36,8 +36,8 @@ public class JpaEventQuery implements EventQuery {
}
@Override
- public EventQuery event(String event) {
- predicates.add(cb.equal(root.get("event"), event));
+ public EventQuery event(String... events) {
+ predicates.add(root.get("event").in(events));
return this;
}
diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java
index 5fb7a83..7d84b26 100644
--- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java
+++ b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java
@@ -47,4 +47,9 @@ public class MongoAuditProviderFactory implements AuditProviderFactory {
return ID;
}
+ @Override
+ public boolean lazyLoad() {
+ return true;
+ }
+
}
diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
index e425455..9ea67b9 100644
--- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
+++ b/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java
@@ -25,8 +25,8 @@ public class MongoEventQuery implements EventQuery {
}
@Override
- public EventQuery event(String event) {
- query.put("event", event);
+ public EventQuery event(String... events) {
+ query.put("event", new BasicDBObject("$in", events));
return this;
}
diff --git a/audit/tests/src/main/java/org/keycloak/audit/tests/AbstractAuditProviderTest.java b/audit/tests/src/main/java/org/keycloak/audit/tests/AbstractAuditProviderTest.java
index c5d1bb7..217dea4 100644
--- a/audit/tests/src/main/java/org/keycloak/audit/tests/AbstractAuditProviderTest.java
+++ b/audit/tests/src/main/java/org/keycloak/audit/tests/AbstractAuditProviderTest.java
@@ -7,6 +7,7 @@ import org.junit.Test;
import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.AuditProviderFactory;
import org.keycloak.audit.Event;
+import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ProviderFactoryLoader;
import java.util.HashMap;
@@ -17,12 +18,12 @@ import java.util.Map;
*/
public abstract class AbstractAuditProviderTest {
- private AuditProviderFactory factory;
+ private ProviderFactory<AuditProvider> factory;
private AuditProvider provider;
@Before
public void before() {
- ProviderFactoryLoader<AuditProviderFactory> loader = ProviderFactoryLoader.load(AuditProviderFactory.class);
+ ProviderFactoryLoader<AuditProvider> loader = ProviderFactoryLoader.create(AuditProviderFactory.class);
factory = loader.find(getProviderId());
factory.init();
@@ -57,6 +58,7 @@ public abstract class AbstractAuditProviderTest {
Assert.assertEquals(4, provider.createQuery().client("clientId").getResultList().size());
Assert.assertEquals(4, provider.createQuery().realm("realmId").getResultList().size());
Assert.assertEquals(4, provider.createQuery().event("event").getResultList().size());
+ Assert.assertEquals(5, provider.createQuery().event("event", "event2").getResultList().size());
Assert.assertEquals(4, provider.createQuery().user("userId").getResultList().size());
Assert.assertEquals(1, provider.createQuery().user("userId").event("event2").getResultList().size());
diff --git a/core/src/main/java/org/keycloak/provider/ProviderFactory.java b/core/src/main/java/org/keycloak/provider/ProviderFactory.java
index 720538d..ca8a19b 100644
--- a/core/src/main/java/org/keycloak/provider/ProviderFactory.java
+++ b/core/src/main/java/org/keycloak/provider/ProviderFactory.java
@@ -13,4 +13,6 @@ public interface ProviderFactory<T extends Provider> {
public String getId();
+ public boolean lazyLoad();
+
}
diff --git a/core/src/main/java/org/keycloak/provider/ProviderFactoryLoader.java b/core/src/main/java/org/keycloak/provider/ProviderFactoryLoader.java
index 51b00dc..fdbb171 100644
--- a/core/src/main/java/org/keycloak/provider/ProviderFactoryLoader.java
+++ b/core/src/main/java/org/keycloak/provider/ProviderFactoryLoader.java
@@ -1,88 +1,100 @@
package org.keycloak.provider;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.Map;
import java.util.ServiceLoader;
+import java.util.Set;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
-public class ProviderFactoryLoader<P extends ProviderFactory> implements Iterable<P> {
+public class ProviderFactoryLoader<T extends Provider> implements Iterable<ProviderFactory<T>> {
- private ServiceLoader<P> serviceLoader;
+ private Map<String, ProviderFactory<T>> factories = new HashMap<String, ProviderFactory<T>>();
- private ProviderFactoryLoader(ServiceLoader<P> serviceLoader) {
- this.serviceLoader = serviceLoader;
+ private ProviderFactoryLoader(ServiceLoader<? extends ProviderFactory> serviceLoader) {
+ for (ProviderFactory p : serviceLoader) {
+ if (!System.getProperties().containsKey(p.getClass().getName() + ".disabled")) {
+ if (p.lazyLoad()) {
+ p = new LazyProviderFactory(p);
+ }
+ factories.put(p.getId(), p);
+ }
+ }
}
- public static <P extends ProviderFactory> ProviderFactoryLoader<P> load(Class<P> service) {
+ public static ProviderFactoryLoader create(Class<? extends ProviderFactory> service) {
return new ProviderFactoryLoader(ServiceLoader.load(service));
}
- public static <P extends ProviderFactory> ProviderFactoryLoader<P> load(Class<P> service, ClassLoader loader) {
+ public static ProviderFactoryLoader create(Class<? extends ProviderFactory> service, ClassLoader loader) {
return new ProviderFactoryLoader(ServiceLoader.load(service, loader));
}
- public P find(String id) {
- Iterator<P> itr = iterator();
- while (itr.hasNext()) {
- P p = itr.next();
- if (p.getId() != null && p.getId().equals(id)) {
- return p;
- }
- }
- return null;
+ public ProviderFactory find(String id) {
+ return factories.get(id);
}
@Override
- public Iterator<P> iterator() {
- return new ProviderFactoryIterator(serviceLoader.iterator());
+ public Iterator<ProviderFactory<T>> iterator() {
+ return factories.values().iterator();
}
- public void close() {
+ public Set<String> providerIds() {
+ return factories.keySet();
+ }
+
+ public void init() {
+ for (ProviderFactory p : factories.values()) {
+ p.init();
+ }
+ }
+ public void close() {
+ for (ProviderFactory p : factories.values()) {
+ p.close();
+ }
}
- private static class ProviderFactoryIterator<P> implements Iterator<P> {
+ private class LazyProviderFactory<T extends Provider> implements ProviderFactory<T> {
- private Iterator<P> itr;
+ private volatile boolean initialized = false;
- private P next;
+ private ProviderFactory<T> factory;
- private ProviderFactoryIterator(Iterator<P> itr) {
- this.itr = itr;
- setNext();
+ private LazyProviderFactory(ProviderFactory<T> factory) {
+ this.factory = factory;
}
@Override
- public boolean hasNext() {
- return next != null;
+ public synchronized T create() {
+ if (!initialized) {
+ factory.init();
+ initialized = true;
+ }
+ return factory.create();
}
@Override
- public P next() {
- P n = next;
- setNext();
- return n;
+ public void init() {
+ // do nothing
}
@Override
- public void remove() {
- throw new UnsupportedOperationException();
+ public void close() {
+ factory.close();
}
- private void setNext() {
- next = null;
- while (itr.hasNext()) {
- if (itr.hasNext()) {
- P n = itr.next();
- if (!System.getProperties().containsKey(n.getClass().getName() + ".disabled")) {
- next = n;
- return;
- }
- }
- }
+ @Override
+ public String getId() {
+ return factory.getId();
}
+ @Override
+ public boolean lazyLoad() {
+ return false;
+ }
}
}
forms/account-api/pom.xml 5(+5 -0)
diff --git a/forms/account-api/pom.xml b/forms/account-api/pom.xml
index e153d52..1ad638a 100755
--- a/forms/account-api/pom.xml
+++ b/forms/account-api/pom.xml
@@ -25,6 +25,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.keycloak</groupId>
+ <artifactId>keycloak-audit-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
</dependency>
diff --git a/forms/account-api/src/main/java/org/keycloak/account/Account.java b/forms/account-api/src/main/java/org/keycloak/account/Account.java
index 060b8a5..3791611 100644
--- a/forms/account-api/src/main/java/org/keycloak/account/Account.java
+++ b/forms/account-api/src/main/java/org/keycloak/account/Account.java
@@ -1,10 +1,12 @@
package org.keycloak.account;
+import org.keycloak.audit.Event;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
+import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -27,4 +29,6 @@ public interface Account {
public Account setReferrer(String[] referrer);
+ public Account setEvents(List<Event> events);
+
}
diff --git a/forms/account-api/src/main/java/org/keycloak/account/AccountPages.java b/forms/account-api/src/main/java/org/keycloak/account/AccountPages.java
index a3e60d2..ceeca40 100644
--- a/forms/account-api/src/main/java/org/keycloak/account/AccountPages.java
+++ b/forms/account-api/src/main/java/org/keycloak/account/AccountPages.java
@@ -5,6 +5,6 @@ package org.keycloak.account;
*/
public enum AccountPages {
- ACCOUNT, PASSWORD, TOTP, SOCIAL;
+ ACCOUNT, PASSWORD, TOTP, SOCIAL, LOG;
}
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
index 143aa1c..6074ad1 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccount.java
@@ -5,10 +5,12 @@ import org.keycloak.account.Account;
import org.keycloak.account.AccountPages;
import org.keycloak.account.freemarker.model.AccountBean;
import org.keycloak.account.freemarker.model.AccountSocialBean;
+import org.keycloak.account.freemarker.model.LogBean;
import org.keycloak.account.freemarker.model.MessageBean;
import org.keycloak.account.freemarker.model.ReferrerBean;
import org.keycloak.account.freemarker.model.TotpBean;
import org.keycloak.account.freemarker.model.UrlBean;
+import org.keycloak.audit.Event;
import org.keycloak.freemarker.FreeMarkerException;
import org.keycloak.freemarker.FreeMarkerUtil;
import org.keycloak.freemarker.Theme;
@@ -23,6 +25,7 @@ import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -37,6 +40,7 @@ public class FreeMarkerAccount implements Account {
private Response.Status status = Response.Status.OK;
private RealmModel realm;
private String[] referrer;
+ private List<Event> events;
public static enum MessageType {SUCCESS, WARNING, ERROR}
@@ -102,6 +106,8 @@ public class FreeMarkerAccount implements Account {
case SOCIAL:
attributes.put("social", new AccountSocialBean(realm, user, uriInfo.getBaseUri()));
break;
+ case LOG:
+ attributes.put("log", new LogBean(events));
}
try {
@@ -157,4 +163,11 @@ public class FreeMarkerAccount implements Account {
this.referrer = referrer;
return this;
}
+
+ @Override
+ public Account setEvents(List<Event> events) {
+ this.events = events;
+ return this;
+ }
+
}
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/LogBean.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/LogBean.java
new file mode 100644
index 0000000..f138f8d
--- /dev/null
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/model/LogBean.java
@@ -0,0 +1,53 @@
+package org.keycloak.account.freemarker.model;
+
+import org.keycloak.audit.Event;
+
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class LogBean {
+
+ private List<EventBean> events;
+
+ public LogBean(List<Event> events) {
+ this.events = new LinkedList<EventBean>();
+ for (Event e : events) {
+ this.events.add(new EventBean(e));
+ }
+ }
+
+ public List<EventBean> getEvents() {
+ return events;
+ }
+
+ public static class EventBean {
+
+ private Event event;
+
+ public EventBean(Event event) {
+ this.event = event;
+ }
+
+ public Date getDate() {
+ return new Date(event.getTime());
+ }
+
+ public String getEvent() {
+ return event.getEvent().replace('_', ' ');
+ }
+
+ public String getClient() {
+ return event.getClientId();
+ }
+
+ public String getIpAddress() {
+ return event.getIpAddress();
+ }
+
+ }
+
+}
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/Templates.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/Templates.java
index 5a63ef5..f9d051c 100644
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/Templates.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/Templates.java
@@ -17,6 +17,8 @@ public class Templates {
return "totp.ftl";
case SOCIAL:
return "social.ftl";
+ case LOG:
+ return "log.ftl";
default:
throw new IllegalArgumentException();
}
diff --git a/forms/common-themes/src/main/resources/theme/account/base/log.ftl b/forms/common-themes/src/main/resources/theme/account/base/log.ftl
new file mode 100644
index 0000000..3f3c917
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/account/base/log.ftl
@@ -0,0 +1,28 @@
+<#import "template.ftl" as layout>
+<@layout.mainLayout active='social' bodyClass='social'; section>
+
+ <div class="row">
+ <div class="col-md-10">
+ <h2>Social Accounts</h2>
+ </div>
+ </div>
+
+ <table>
+ <th>
+ <td>${event.date}</td>
+ <td>${event.event}</td>
+ <td>${event.ipAddress}</td>
+ <td>${event.clientId}</td>
+ </th>
+
+ <#list log.events as event>
+ <tr>
+ <td>${event.date}</td>
+ <td>${event.event}</td>
+ <td>${event.ipAddress}</td>
+ <td>${event.clientId}</td
+ </tr>
+ </#list>
+ </table>
+
+</@layout.mainLayout>
\ No newline at end of file
diff --git a/model/api/src/main/java/org/keycloak/models/Config.java b/model/api/src/main/java/org/keycloak/models/Config.java
index fccf84f..6c53c61 100644
--- a/model/api/src/main/java/org/keycloak/models/Config.java
+++ b/model/api/src/main/java/org/keycloak/models/Config.java
@@ -12,6 +12,8 @@ public class Config {
public static final String MODEL_PROVIDER_KEY = "keycloak.model";
+ public static final String MODEL_AUDIT_KEY = "keycloak.audit";
+
public static final String THEME_BASE_KEY = "keycloak.theme.base";
public static final String THEME_BASE_DEFAULT = "base";
public static final String THEME_DEFAULT_KEY = "keycloak.theme.default";
@@ -27,6 +29,14 @@ public class Config {
System.setProperty(ADMIN_REALM_KEY, realm);
}
+ public static String getAuditProvider() {
+ return System.getProperty(MODEL_PROVIDER_KEY);
+ }
+
+ public static void setAuditProvider(String provider) {
+ System.setProperty(MODEL_PROVIDER_KEY, provider);
+ }
+
public static String getModelProvider() {
return System.getProperty(MODEL_PROVIDER_KEY);
}
diff --git a/services/src/main/java/org/keycloak/services/DefaultProviderSession.java b/services/src/main/java/org/keycloak/services/DefaultProviderSession.java
new file mode 100755
index 0000000..748055b
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/DefaultProviderSession.java
@@ -0,0 +1,57 @@
+package org.keycloak.services;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class DefaultProviderSession implements ProviderSession {
+ private ProviderSessionFactory factory;
+ private Map<Integer, Provider> providers = new HashMap<Integer, Provider>();
+
+ public DefaultProviderSession(ProviderSessionFactory factory) {
+ this.factory = factory;
+ }
+
+ public <T extends Provider> T getProvider(Class<T> clazz) {
+ Integer hash = clazz.hashCode();
+ T provider = (T) providers.get(hash);
+ if (provider == null) {
+ ProviderFactory<T> providerFactory = factory.getProviderFactory(clazz);
+ if (providerFactory != null) {
+ provider = providerFactory.create();
+ providers.put(hash, provider);
+ }
+ }
+ return provider;
+ }
+
+ public <T extends Provider> T getProvider(Class<T> clazz, String id) {
+ Integer hash = clazz.hashCode() + id.hashCode();
+ T provider = (T) providers.get(hash);
+ if (provider == null) {
+ ProviderFactory<T> providerFactory = factory.getProviderFactory(clazz, id);
+ if (providerFactory != null) {
+ provider = providerFactory.create();
+ providers.put(hash, provider);
+ }
+ }
+ return provider;
+ }
+
+ public <T extends Provider> Set<String> listProviderIds(Class<T> clazz) {
+ return factory.providerIds(clazz);
+ }
+
+ public void close() {
+ for (Provider p : providers.values()) {
+ p.close();
+ }
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/DefaultProviderSessionFactory.java b/services/src/main/java/org/keycloak/services/DefaultProviderSessionFactory.java
new file mode 100755
index 0000000..c6b5943
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/DefaultProviderSessionFactory.java
@@ -0,0 +1,65 @@
+package org.keycloak.services;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.ProviderFactoryLoader;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class DefaultProviderSessionFactory implements ProviderSessionFactory {
+
+ private Map<Class<? extends Provider>, ProviderFactoryLoader> loaders = new HashMap<Class<? extends Provider>, ProviderFactoryLoader>();
+ private Map<Class<? extends Provider>, String> defaultFactories = new HashMap<Class<? extends Provider>, String>();
+
+ public ProviderSession createSession() {
+ return new DefaultProviderSession(this);
+ }
+
+ public void close() {
+ for (ProviderFactoryLoader loader : loaders.values()) {
+ loader.close();
+ }
+ }
+
+ public <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz) {
+ String id = defaultFactories.get(clazz);
+ if (id == null) {
+ return null;
+ }
+ return getProviderFactory(clazz, id);
+ }
+
+ public <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id) {
+ ProviderFactoryLoader loader = getLoader(clazz);
+ return loader != null ? loader.find(id) : null;
+ }
+
+ public Set<String> providerIds(Class<? extends Provider> clazz) {
+ ProviderFactoryLoader loader = getLoader(clazz);
+ return loader != null ? loader.providerIds() : null;
+ }
+
+ public void registerLoader(Class<? extends Provider> clazz, ProviderFactoryLoader loader) {
+ loaders.put(clazz, loader);
+
+ }
+
+ public void registerLoader(Class<? extends Provider> clazz, ProviderFactoryLoader loader, String defaultProvider) {
+ loaders.put(clazz, loader);
+ defaultFactories.put(clazz, defaultProvider);
+
+ }
+
+ public void init() {
+ for (ProviderFactoryLoader l : loaders.values()) {
+ l.init();
+ }
+ }
+
+ private <T extends Provider> ProviderFactoryLoader getLoader(Class<T> clazz) {
+ return loaders.get(clazz);
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
index 3f859c2..54338ca 100755
--- a/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
+++ b/services/src/main/java/org/keycloak/services/filters/KeycloakSessionServletFilter.java
@@ -4,6 +4,8 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.KeycloakTransaction;
+import org.keycloak.services.ProviderSession;
+import org.keycloak.services.ProviderSessionFactory;
import org.keycloak.util.KeycloakRegistry;
import javax.servlet.Filter;
@@ -26,6 +28,11 @@ public class KeycloakSessionServletFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+ ProviderSessionFactory providerSessionFactory = (ProviderSessionFactory) servletRequest.getServletContext().getAttribute(ProviderSessionFactory.class.getName());
+ ProviderSession providerSession = providerSessionFactory.createSession();
+
+ ResteasyProviderFactory.pushContext(ProviderSession.class, providerSession);
+
KeycloakRegistry registry = (KeycloakRegistry)servletRequest.getServletContext().getAttribute(KeycloakRegistry.class.getName());
ResteasyProviderFactory.pushContext(KeycloakRegistry.class, registry);
KeycloakSessionFactory factory = registry.getService(KeycloakSessionFactory.class);
@@ -53,6 +60,7 @@ public class KeycloakSessionServletFilter implements Filter {
throw ex;
} finally {
session.close();
+ providerSession.close();
ResteasyProviderFactory.clearContextData();
}
diff --git a/services/src/main/java/org/keycloak/services/ProviderSession.java b/services/src/main/java/org/keycloak/services/ProviderSession.java
new file mode 100755
index 0000000..100dc54
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/ProviderSession.java
@@ -0,0 +1,20 @@
+package org.keycloak.services;
+
+import org.keycloak.provider.Provider;
+
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface ProviderSession {
+
+ <T extends Provider> T getProvider(Class<T> clazz);
+
+ <T extends Provider> T getProvider(Class<T> clazz, String id);
+
+ <T extends Provider> Set<String> listProviderIds(Class<T> clazz);
+
+ void close();
+
+}
diff --git a/services/src/main/java/org/keycloak/services/ProviderSessionFactory.java b/services/src/main/java/org/keycloak/services/ProviderSessionFactory.java
new file mode 100755
index 0000000..a1c5707
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/ProviderSessionFactory.java
@@ -0,0 +1,28 @@
+package org.keycloak.services;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.ProviderFactoryLoader;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public interface ProviderSessionFactory {
+
+ ProviderSession createSession();
+
+ void close();
+
+ <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz);
+
+ <T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id);
+
+ Set<String> providerIds(Class<? extends Provider> clazz);
+
+ void init();
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index b937674..8bc6269 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -28,13 +28,22 @@ import org.keycloak.account.Account;
import org.keycloak.account.AccountLoader;
import org.keycloak.account.AccountPages;
import org.keycloak.audit.Audit;
+import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.Details;
+import org.keycloak.audit.Event;
import org.keycloak.audit.Events;
import org.keycloak.jaxrs.JaxrsOAuthClient;
-import org.keycloak.models.*;
+import org.keycloak.models.AccountRoles;
+import org.keycloak.models.ApplicationModel;
+import org.keycloak.models.ClientModel;
+import org.keycloak.models.Constants;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.SocialLinkModel;
+import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserModel;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.services.managers.AccessCodeEntry;
+import org.keycloak.services.ProviderSession;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.Auth;
import org.keycloak.services.managers.ModelToRepresentation;
@@ -51,8 +60,23 @@ import org.keycloak.spi.authentication.AuthProviderStatus;
import org.keycloak.spi.authentication.AuthenticationProviderException;
import org.keycloak.spi.authentication.AuthenticationProviderManager;
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
+import javax.ws.rs.BadRequestException;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.ForbiddenException;
+import javax.ws.rs.GET;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.NewCookie;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Variant;
import java.net.URI;
import java.util.List;
import java.util.UUID;
@@ -77,10 +101,15 @@ public class AccountService {
@Context
private UriInfo uriInfo;
+ @Context
+ private ProviderSession providers;
+
private final AppAuthManager authManager;
private final ApplicationModel application;
private Audit audit;
private final SocialRequestManager socialRequestManager;
+ private Account account;
+ private Auth auth;
public AccountService(RealmModel realm, ApplicationModel application, TokenManager tokenManager, SocialRequestManager socialRequestManager, Audit audit) {
this.realm = realm;
@@ -90,6 +119,15 @@ public class AccountService {
this.socialRequestManager = socialRequestManager;
}
+ public void init() {
+ account = AccountLoader.load().createAccount(uriInfo).setRealm(realm);
+
+ auth = authManager.authenticate(realm, headers);
+ if (auth != null) {
+ account.setUser(auth.getUser());
+ }
+ }
+
public static UriBuilder accountServiceBaseUrl(UriInfo uriInfo) {
UriBuilder base = uriInfo.getBaseUriBuilder().path(RealmsResource.class).path(RealmsResource.class, "getAccountService");
return base;
@@ -97,16 +135,13 @@ public class AccountService {
private Response forwardToPage(String path, AccountPages page) {
- Auth auth = getAuth(false);
if (auth != null) {
try {
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
} catch (ForbiddenException e) {
return Flows.forms(realm, request, uriInfo).setError("No access").createErrorPage();
}
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
-
String[] referrer = getReferrer();
if (referrer != null) {
account.setReferrer(referrer);
@@ -131,8 +166,7 @@ public class AccountService {
if (types.contains(MediaType.WILDCARD_TYPE) || (types.contains(MediaType.TEXT_HTML_TYPE))) {
return forwardToPage(null, AccountPages.ACCOUNT);
} else if (types.contains(MediaType.APPLICATION_JSON_TYPE)) {
- Auth auth = getAuth(true);
- requireOneOf(auth, AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
+ requireOneOf(AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_PROFILE);
return Cors.add(request, Response.ok(ModelToRepresentation.toRepresentation(auth.getUser()))).auth().allowedOrigins(auth.getClient()).build();
} else {
@@ -158,17 +192,23 @@ public class AccountService {
return forwardToPage("social", AccountPages.SOCIAL);
}
+ @Path("log")
+ @GET
+ public Response logPage() {
+ AuditProvider audit = providers.getProvider(AuditProvider.class);
+ List<Event> events = audit.createQuery().user(auth.getUser().getId()).maxResults(20).getResultList();
+ account.setEvents(events);
+ return forwardToPage("log", AccountPages.LOG);
+ }
+
@Path("/")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processAccountUpdate(final MultivaluedMap<String, String> formData) {
- Auth auth = getAuth(true);
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
-
String error = Validation.validateUpdateProfileForm(formData);
if (error != null) {
return account.setError(error).createResponse(AccountPages.ACCOUNT);
@@ -196,15 +236,13 @@ public class AccountService {
@Path("totp-remove")
@GET
public Response processTotpRemove() {
- Auth auth = getAuth(true);
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
user.setTotp(false);
audit.event(Events.REMOVE_TOTP).client(auth.getClient()).user(auth.getUser()).success();
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
return account.setSuccess("successTotpRemoved").createResponse(AccountPages.TOTP);
}
@@ -212,16 +250,13 @@ public class AccountService {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processTotpUpdate(final MultivaluedMap<String, String> formData) {
- Auth auth = getAuth(true);
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
String totp = formData.getFirst("totp");
String totpSecret = formData.getFirst("totpSecret");
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
-
if (Validation.isEmpty(totp)) {
return account.setError(Messages.MISSING_TOTP).createResponse(AccountPages.TOTP);
} else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) {
@@ -244,13 +279,10 @@ public class AccountService {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processPasswordUpdate(final MultivaluedMap<String, String> formData) {
- Auth auth = getAuth(true);
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
-
String password = formData.getFirst("password");
String passwordNew = formData.getFirst("password-new");
String passwordConfirm = formData.getFirst("password-confirm");
@@ -286,12 +318,9 @@ public class AccountService {
@GET
public Response processSocialUpdate(@QueryParam("action") String action,
@QueryParam("provider_id") String providerId) {
- Auth auth = getAuth(true);
- require(auth, AccountRoles.MANAGE_ACCOUNT);
+ require(AccountRoles.MANAGE_ACCOUNT);
UserModel user = auth.getUser();
- Account account = AccountLoader.load().createAccount(uriInfo).setRealm(realm).setUser(auth.getUser());
-
if (Validation.isEmpty(providerId)) {
return account.setError(Messages.MISSING_SOCIAL_PROVIDER).createResponse(AccountPages.SOCIAL);
}
@@ -426,14 +455,6 @@ public class AccountService {
return oauth.redirect(uriInfo, accountUri.toString());
}
- private Auth getAuth(boolean error) {
- Auth auth = authManager.authenticate(realm, headers);
- if (auth == null && error) {
- throw new ForbiddenException();
- }
- return auth;
- }
-
private String[] getReferrer() {
String referrer = uriInfo.getQueryParameters().getFirst("referrer");
if (referrer == null) {
@@ -467,13 +488,21 @@ public class AccountService {
return null;
}
- public void require(Auth auth, String role) {
+ public void require(String role) {
+ if (auth == null) {
+ throw new ForbiddenException();
+ }
+
if (!auth.hasAppRole(application.getName(), role)) {
throw new ForbiddenException();
}
}
- public void requireOneOf(Auth auth, String... roles) {
+ public void requireOneOf(String... roles) {
+ if (auth == null) {
+ throw new ForbiddenException();
+ }
+
if (!auth.hasOneOfAppRole(application.getName(), roles)) {
throw new ForbiddenException();
}
diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
index 977d7e9..31cc1e8 100755
--- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
+++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java
@@ -2,8 +2,16 @@ package org.keycloak.services.resources;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.SkeletonKeyContextResolver;
+import org.keycloak.audit.AuditListener;
+import org.keycloak.audit.AuditListenerFactory;
+import org.keycloak.audit.AuditProvider;
+import org.keycloak.audit.AuditProviderFactory;
+import org.keycloak.models.Config;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.ModelProvider;
+import org.keycloak.provider.ProviderFactoryLoader;
+import org.keycloak.services.DefaultProviderSessionFactory;
+import org.keycloak.services.ProviderSessionFactory;
import org.keycloak.util.KeycloakRegistry;
import org.keycloak.services.managers.ApplianceBootstrap;
import org.keycloak.services.managers.SocialRequestManager;
@@ -41,6 +49,8 @@ public class KeycloakApplication extends Application {
context.setAttribute(KeycloakRegistry.class.getName(), registry);
//classes.add(KeycloakSessionCleanupFilter.class);
+ context.setAttribute(ProviderSessionFactory.class.getName(), createProviderSessionFactory());
+
TokenManager tokenManager = new TokenManager();
SocialRequestManager socialRequestManager = new SocialRequestManager();
@@ -84,6 +94,15 @@ public class KeycloakApplication extends Application {
throw new RuntimeException("Model provider not found");
}
+ public static DefaultProviderSessionFactory createProviderSessionFactory() {
+ DefaultProviderSessionFactory factory = new DefaultProviderSessionFactory();
+
+ factory.registerLoader(AuditProvider.class, ProviderFactoryLoader.create(AuditProviderFactory.class), Config.getAuditProvider());
+ factory.registerLoader(AuditListener.class, ProviderFactoryLoader.create(AuditListenerFactory.class));
+
+ return factory;
+ }
+
public KeycloakSessionFactory getFactory() {
return factory;
}
diff --git a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
index 4601559..cb11ed5 100755
--- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java
@@ -2,10 +2,14 @@ package org.keycloak.services.resources;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.audit.Audit;
+import org.keycloak.audit.AuditListener;
+import org.keycloak.audit.AuditProvider;
import org.keycloak.models.ApplicationModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
+import org.keycloak.services.ClientConnection;
+import org.keycloak.services.ProviderSession;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.SocialRequestManager;
import org.keycloak.services.managers.TokenManager;
@@ -19,6 +23,8 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
+import java.util.LinkedList;
+import java.util.List;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -41,7 +47,10 @@ public class RealmsResource {
protected KeycloakSession session;
@Context
- protected HttpServletRequest servletRequest;
+ protected ProviderSession providers;
+
+ @Context
+ protected ClientConnection clientConnection;
protected TokenManager tokenManager;
protected SocialRequestManager socialRequestManager;
@@ -59,7 +68,7 @@ public class RealmsResource {
public TokenService getTokenService(final @PathParam("realm") String name) {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = locateRealm(name, realmManager);
- Audit audit = Audit.create(realm, servletRequest.getRemoteAddr());
+ Audit audit = createAudit(realm);
TokenService tokenService = new TokenService(realm, tokenManager, audit);
resourceContext.initResource(tokenService);
return tokenService;
@@ -84,10 +93,10 @@ public class RealmsResource {
throw new NotFoundException();
}
- Audit audit = Audit.create(realm, servletRequest.getRemoteAddr());
-
+ Audit audit = createAudit(realm);
AccountService accountService = new AccountService(realm, application, tokenManager, socialRequestManager, audit);
resourceContext.initResource(accountService);
+ accountService.init();
return accountService;
}
@@ -100,4 +109,24 @@ public class RealmsResource {
return realmResource;
}
+ private Audit createAudit(RealmModel realm) {
+ List<AuditListener> listeners = new LinkedList<AuditListener>();
+
+ AuditProvider auditProvider = providers.getProvider(AuditProvider.class);
+ if (auditProvider != null) {
+ listeners.add(auditProvider);
+ }
+
+ if (realm.getAuditListeners() != null) {
+ for (String id : realm.getAuditListeners()) {
+ AuditListener listener = providers.getProvider(AuditListener.class, id);
+ if (listener != null) {
+ listeners.add(listener);
+ }
+ }
+ }
+
+ return new Audit(listeners, realm, clientConnection.getRemoteAddr());
+ }
+
}
diff --git a/services/src/main/java/org/keycloak/services/resources/SocialResource.java b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
index 3d5bfa5..c06fc3d 100755
--- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java
@@ -25,6 +25,8 @@ import org.jboss.resteasy.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.keycloak.OAuth2Constants;
import org.keycloak.audit.Audit;
+import org.keycloak.audit.AuditListener;
+import org.keycloak.audit.AuditProvider;
import org.keycloak.audit.Details;
import org.keycloak.audit.Errors;
import org.keycloak.audit.Events;
@@ -36,6 +38,8 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.SocialLinkModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
+import org.keycloak.services.ClientConnection;
+import org.keycloak.services.ProviderSession;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.managers.SocialRequestManager;
@@ -67,6 +71,7 @@ import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import java.net.URISyntaxException;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -95,7 +100,10 @@ public class SocialResource {
protected KeycloakSession session;
@Context
- protected HttpServletRequest servletRequest;
+ protected ProviderSession providers;
+
+ @Context
+ protected ClientConnection clientConnection;
private SocialRequestManager socialRequestManager;
@@ -121,7 +129,7 @@ public class SocialResource {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.getRealmByName(realmName);
- Audit audit = Audit.create(realm, servletRequest.getRemoteAddr())
+ Audit audit = createAudit(realm)
.event(Events.LOGIN)
.detail(Details.RESPONSE_TYPE, "code")
.detail(Details.AUTH_METHOD, "social");
@@ -260,7 +268,7 @@ public class SocialResource {
RealmManager realmManager = new RealmManager(session);
RealmModel realm = realmManager.getRealmByName(realmName);
- Audit audit = Audit.create(realm, servletRequest.getRemoteAddr())
+ Audit audit = createAudit(realm)
.event(Events.LOGIN).client(clientId)
.detail(Details.REDIRECT_URI, redirectUri)
.detail(Details.RESPONSE_TYPE, "code")
@@ -327,4 +335,24 @@ public class SocialResource {
return queryParams;
}
+ private Audit createAudit(RealmModel realm) {
+ List<AuditListener> listeners = new LinkedList<AuditListener>();
+
+ AuditProvider auditProvider = providers.getProvider(AuditProvider.class);
+ if (auditProvider != null) {
+ listeners.add(auditProvider);
+ }
+
+ if (realm.getAuditListeners() != null) {
+ for (String id : realm.getAuditListeners()) {
+ AuditListener listener = providers.getProvider(AuditListener.class, id);
+ if (listener != null) {
+ listeners.add(listener);
+ }
+ }
+ }
+
+ return new Audit(listeners, realm, clientConnection.getRemoteAddr());
+ }
+
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
index 5a582e9..9f45a03 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java
@@ -34,8 +34,6 @@ import java.util.concurrent.TimeUnit;
*/
public class AssertEvents implements TestRule, AuditListenerFactory {
- private static final Logger log = Logger.getLogger(AssertEvents.class);
-
public static String DEFAULT_CLIENT_ID = "test-app";
public static String DEFAULT_REDIRECT_URI = "http://localhost:8081/app/auth";
public static String DEFAULT_IP_ADDRESS = "127.0.0.1";
@@ -59,6 +57,11 @@ public class AssertEvents implements TestRule, AuditListenerFactory {
}
@Override
+ public boolean lazyLoad() {
+ return false;
+ }
+
+ @Override
public Statement apply(final Statement base, org.junit.runner.Description description) {
return new Statement() {
@Override