diff --git a/audit/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/audit/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi deleted file mode 100644 index 2a1aeb8ea4..0000000000 --- a/audit/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi +++ /dev/null @@ -1,2 +0,0 @@ -org.keycloak.audit.AuditProviderSpi -org.keycloak.audit.AuditListenerSpi \ No newline at end of file diff --git a/audit/email/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory b/audit/email/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory deleted file mode 100644 index bdc9c2e834..0000000000 --- a/audit/email/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.audit.email.EmailAuditListenerFactory \ No newline at end of file diff --git a/audit/jboss-logging/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory b/audit/jboss-logging/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory deleted file mode 100644 index 2370355264..0000000000 --- a/audit/jboss-logging/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.audit.log.JBossLoggingAuditListenerFactory \ No newline at end of file diff --git a/audit/jpa/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory b/audit/jpa/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory deleted file mode 100644 index e04a02866c..0000000000 --- a/audit/jpa/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.audit.jpa.JpaAuditProviderFactory \ No newline at end of file diff --git a/audit/mongo/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory b/audit/mongo/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory deleted file mode 100644 index ea4454d2fc..0000000000 --- a/audit/mongo/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.audit.mongo.MongoAuditProviderFactory \ No newline at end of file diff --git a/connections/jpa/src/main/resources/META-INF/persistence.xml b/connections/jpa/src/main/resources/META-INF/persistence.xml index dde200e23a..ec843ec9da 100755 --- a/connections/jpa/src/main/resources/META-INF/persistence.xml +++ b/connections/jpa/src/main/resources/META-INF/persistence.xml @@ -25,7 +25,7 @@ org.keycloak.models.sessions.jpa.entities.UsernameLoginFailureEntity - org.keycloak.audit.jpa.EventEntity + org.keycloak.events.jpa.EventEntity true diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmAuditRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmAuditRepresentation.java deleted file mode 100755 index 9a4d019f01..0000000000 --- a/core/src/main/java/org/keycloak/representations/idm/RealmAuditRepresentation.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.keycloak.representations.idm; - -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class RealmAuditRepresentation { - protected boolean auditEnabled; - protected Long auditExpiration; - protected List auditListeners; - - public boolean isAuditEnabled() { - return auditEnabled; - } - - public void setAuditEnabled(boolean auditEnabled) { - this.auditEnabled = auditEnabled; - } - - public Long getAuditExpiration() { - return auditExpiration; - } - - public void setAuditExpiration(Long auditExpiration) { - this.auditExpiration = auditExpiration; - } - - public List getAuditListeners() { - return auditListeners; - } - - public void setAuditListeners(List auditListeners) { - this.auditListeners = auditListeners; - } -} diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java new file mode 100755 index 0000000000..acadc95246 --- /dev/null +++ b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java @@ -0,0 +1,37 @@ +package org.keycloak.representations.idm; + +import java.util.List; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class RealmEventsConfigRepresentation { + protected boolean eventsEnabled; + protected Long eventsExpiration; + protected List eventsListeners; + + public boolean isEventsEnabled() { + return eventsEnabled; + } + + public void setEventsEnabled(boolean eventsEnabled) { + this.eventsEnabled = eventsEnabled; + } + + public Long getEventsExpiration() { + return eventsExpiration; + } + + public void setEventsExpiration(Long eventsExpiration) { + this.eventsExpiration = eventsExpiration; + } + + public List getEventsListeners() { + return eventsListeners; + } + + public void setEventsListeners(List eventsListeners) { + this.eventsListeners = eventsListeners; + } +} diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index dad5eac635..f192ecfb02 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -60,9 +60,9 @@ public class RealmRepresentation { protected String accountTheme; protected String adminTheme; protected String emailTheme; - protected boolean auditEnabled; - protected long auditExpiration; - protected List auditListeners; + protected boolean eventsEnabled; + protected long eventsExpiration; + protected List eventsListeners; public String getId() { return id; @@ -436,28 +436,28 @@ public class RealmRepresentation { this.failureFactor = failureFactor; } - public boolean isAuditEnabled() { - return auditEnabled; + public boolean isEventsEnabled() { + return eventsEnabled; } - public void setAuditEnabled(boolean auditEnabled) { - this.auditEnabled = auditEnabled; + public void setEventsEnabled(boolean eventsEnabled) { + this.eventsEnabled = eventsEnabled; } - public long getAuditExpiration() { - return auditExpiration; + public long getEventsExpiration() { + return eventsExpiration; } - public void setAuditExpiration(long auditExpiration) { - this.auditExpiration = auditExpiration; + public void setEventsExpiration(long eventsExpiration) { + this.eventsExpiration = eventsExpiration; } - public List getAuditListeners() { - return auditListeners; + public List getEventsListeners() { + return eventsListeners; } - public void setAuditListeners(List auditListeners) { - this.auditListeners = auditListeners; + public void setEventsListeners(List eventsListeners) { + this.eventsListeners = eventsListeners; } public List getUserFederationProviders() { diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml index 32c72603cf..918d644261 100755 --- a/dependencies/server-all/pom.xml +++ b/dependencies/server-all/pom.xml @@ -48,17 +48,17 @@ org.keycloak - keycloak-audit-jpa + keycloak-events-jpa ${project.version} org.keycloak - keycloak-audit-jboss-logging + keycloak-events-jboss-logging ${project.version} org.keycloak - keycloak-audit-email + keycloak-events-email ${project.version} @@ -136,7 +136,7 @@ org.keycloak - keycloak-audit-mongo + keycloak-events-mongo ${project.version} diff --git a/dependencies/server-min/pom.xml b/dependencies/server-min/pom.xml index 2fcda5de47..36d6a73dde 100755 --- a/dependencies/server-min/pom.xml +++ b/dependencies/server-min/pom.xml @@ -50,17 +50,17 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} org.keycloak - keycloak-audit-jpa + keycloak-events-jpa ${project.version} org.keycloak - keycloak-audit-jboss-logging + keycloak-events-jboss-logging ${project.version} diff --git a/docbook/reference/en/en-US/master.xml b/docbook/reference/en/en-US/master.xml index d5878a5e1e..befdf486b7 100755 --- a/docbook/reference/en/en-US/master.xml +++ b/docbook/reference/en/en-US/master.xml @@ -26,7 +26,7 @@ - + @@ -115,7 +115,7 @@ This one is short &CORS; &Timeouts; &AdminApi; - &Audit; + &Events; &UserFederation; &ExportImport; &ServerCache; diff --git a/docbook/reference/en/en-US/modules/audit.xml b/docbook/reference/en/en-US/modules/events.xml similarity index 59% rename from docbook/reference/en/en-US/modules/audit.xml rename to docbook/reference/en/en-US/modules/events.xml index 0136a916c1..e580448d62 100755 --- a/docbook/reference/en/en-US/modules/audit.xml +++ b/docbook/reference/en/en-US/modules/events.xml @@ -1,13 +1,13 @@ - - Audit + + Events - Keycloak provides an Audit SPI that makes it possible to register listeners for events in the system. There are two - interfaces that can be implemented, the first is a pure listener, the second is a provider which listens for events - as well as providing a query over persisted events. If a realm has a audit provider registered it's possible to - view events for the realm through the admin console and account management. + Keycloak provides an Events SPI that makes it possible to register listeners for user related events, for example + user logins. There are two interfaces that can be implemented, the first is a pure listener, the second is a events + store which listens for events, but is also required to store events. An events store provides a way for the admin + and account management consoles to view events.
- Events + Event types Login events: @@ -19,7 +19,7 @@ - Account events + Account events: Social Link - An account has been linked to a social provider Remove Social Link - A social provider has been removed from an account @@ -38,14 +38,14 @@
- Audit Listener + Event Listener - Keycloak comes with an Email Audit Listener and a JBogg Logging Audit Listener. The Email Audit Listener - sends an email to the users account when an event occurs. The JBoss Logging Audit Listener writes to a log + Keycloak comes with an Email Event Listener and a JBogg Logging Event Listener. The Email Event Listener + sends an email to the users account when an event occurs. The JBoss Logging Event Listener writes to a log file when an events occurs. - The Email Audit Listener only supports the following events at the moment: + The Email Event Listener only supports the following events at the moment: Login Error Update Password @@ -55,7 +55,7 @@ You can exclude one or more events by editing standalone/configuration/keycloak-server.json and adding for example:
- Audit Provider + Event Store - Audit Providers listen for events and is expected to persist the events to make it possible to query for them + Event Store listen for events and is expected to persist the events to make it possible to query for them later. This is used by the admin console and account management to view events. Keycloak includes providers - to persist audit events to JPA and Mongo. For production you will most likely want to use a separate database - for audit events. You may even want to use a RDBMS for your model, and Mongo for your audit. + to persist events to JPA and Mongo. You can specify events to include or exclude by editing standalone/configuration/keycloak-server.json, and adding for example:
- Configure Audit Settings for Realm + Configure Events Settings for Realm - To enable audit for a realm you firstly need to make sure you have a audit provider registered for Keycloak. - By default the JPA audit provider is registered. Once you've done that open the admin console, select the - realm you're configuring, select Audit. Then click on Config. - You can enable audit for your realm by toggling Enabled to ON. You can also set - an expiration on audit events. This will deleted events from the database that are older than the specified + To enable persisting of events for a realm you first need to make sure you have a event store provider registered for Keycloak. + By default the JPA event store provider is registered. Once you've done that open the admin console, select the + realm you're configuring, select Events. Then click on Config. + You can enable storing events for your realm by toggling Save Events to ON. You can also set + an expiration on events. This will periodically delete events from the database that are older than the specified time. - To configure listeners for a realm on the same page as above add one or more audit listeners to the - Audit Listeners select box. This will allow you to enable any registered Audit Listeners with the + To configure listeners for a realm on the same page as above add one or more event listeners to the + Listeners select box. This will allow you to enable any registered event listeners with the realm.
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml index 9223b9ffdd..a1a8bd6695 100755 --- a/docbook/reference/en/en-US/modules/server-installation.xml +++ b/docbook/reference/en/en-US/modules/server-installation.xml @@ -329,7 +329,7 @@ keycloak-war-dist-all-1.0-rc-2-SNAPSHOT/ in your favourite editor, then change: - keycloak-audit-parent + keycloak-events-parent org.keycloak 1.0-rc-2-SNAPSHOT 4.0.0 - keycloak-audit-api - Keycloak Audit API + keycloak-events-api + Keycloak Events API diff --git a/audit/api/src/main/java/org/keycloak/audit/Details.java b/events/api/src/main/java/org/keycloak/events/Details.java similarity index 96% rename from audit/api/src/main/java/org/keycloak/audit/Details.java rename to events/api/src/main/java/org/keycloak/events/Details.java index fdb344816e..50921dd892 100755 --- a/audit/api/src/main/java/org/keycloak/audit/Details.java +++ b/events/api/src/main/java/org/keycloak/events/Details.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; /** * @author Stian Thorgersen diff --git a/audit/api/src/main/java/org/keycloak/audit/Errors.java b/events/api/src/main/java/org/keycloak/events/Errors.java similarity index 97% rename from audit/api/src/main/java/org/keycloak/audit/Errors.java rename to events/api/src/main/java/org/keycloak/events/Errors.java index d6a5be2396..a6932ec0ad 100755 --- a/audit/api/src/main/java/org/keycloak/audit/Errors.java +++ b/events/api/src/main/java/org/keycloak/events/Errors.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; /** * @author Stian Thorgersen diff --git a/audit/api/src/main/java/org/keycloak/audit/Event.java b/events/api/src/main/java/org/keycloak/events/Event.java similarity index 90% rename from audit/api/src/main/java/org/keycloak/audit/Event.java rename to events/api/src/main/java/org/keycloak/events/Event.java index 3a72fd1b3d..0099e8305b 100644 --- a/audit/api/src/main/java/org/keycloak/audit/Event.java +++ b/events/api/src/main/java/org/keycloak/events/Event.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; import java.util.HashMap; import java.util.Map; @@ -10,7 +10,7 @@ public class Event { private long time; - private EventType event; + private EventType type; private String realmId; @@ -34,12 +34,12 @@ public class Event { this.time = time; } - public EventType getEvent() { - return event; + public EventType getType() { + return type; } - public void setEvent(EventType event) { - this.event = event; + public void setType(EventType type) { + this.type = type; } public String getRealmId() { @@ -101,7 +101,7 @@ public class Event { public Event clone() { Event clone = new Event(); clone.time = time; - clone.event = event; + clone.type = type; clone.realmId = realmId; clone.clientId = clientId; clone.userId = userId; diff --git a/audit/api/src/main/java/org/keycloak/audit/Audit.java b/events/api/src/main/java/org/keycloak/events/EventBuilder.java similarity index 65% rename from audit/api/src/main/java/org/keycloak/audit/Audit.java rename to events/api/src/main/java/org/keycloak/events/EventBuilder.java index 985fefa38d..8ab685777e 100644 --- a/audit/api/src/main/java/org/keycloak/audit/Audit.java +++ b/events/api/src/main/java/org/keycloak/events/EventBuilder.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.jboss.logging.Logger; import org.keycloak.models.ClientModel; @@ -12,14 +12,14 @@ import java.util.List; /** * @author Stian Thorgersen */ -public class Audit { +public class EventBuilder { - private static final Logger log = Logger.getLogger(Audit.class); + private static final Logger log = Logger.getLogger(EventBuilder.class); - private List listeners; + private List listeners; private Event event; - public Audit(List listeners, RealmModel realm, String ipAddress) { + public EventBuilder(List listeners, RealmModel realm, String ipAddress) { this.listeners = listeners; this.event = new Event(); @@ -27,60 +27,60 @@ public class Audit { ipAddress(ipAddress); } - Audit() { + EventBuilder() { } - public Audit realm(RealmModel realm) { + public EventBuilder realm(RealmModel realm) { event.setRealmId(realm.getId()); return this; } - public Audit realm(String realmId) { + public EventBuilder realm(String realmId) { event.setRealmId(realmId); return this; } - public Audit client(ClientModel client) { + public EventBuilder client(ClientModel client) { event.setClientId(client.getClientId()); return this; } - public Audit client(String clientId) { + public EventBuilder client(String clientId) { event.setClientId(clientId); return this; } - public Audit user(UserModel user) { + public EventBuilder user(UserModel user) { event.setUserId(user.getId()); return this; } - public Audit user(String userId) { + public EventBuilder user(String userId) { event.setUserId(userId); return this; } - public Audit session(UserSessionModel session) { + public EventBuilder session(UserSessionModel session) { event.setSessionId(session.getId()); return this; } - public Audit session(String sessionId) { + public EventBuilder session(String sessionId) { event.setSessionId(sessionId); return this; } - public Audit ipAddress(String ipAddress) { + public EventBuilder ipAddress(String ipAddress) { event.setIpAddress(ipAddress); return this; } - public Audit event(EventType e) { - event.setEvent(e); + public EventBuilder event(EventType e) { + event.setType(e); return this; } - public Audit detail(String key, String value) { + public EventBuilder detail(String key, String value) { if (value == null || value.equals("")) { return this; } @@ -92,7 +92,7 @@ public class Audit { return this; } - public Audit removeDetail(String key) { + public EventBuilder removeDetail(String key) { if (event.getDetails() != null) { event.getDetails().remove(key); } @@ -108,19 +108,19 @@ public class Audit { } public void error(String error) { - event.setEvent(EventType.valueOf(event.getEvent().name() + "_ERROR")); + event.setType(EventType.valueOf(event.getType().name() + "_ERROR")); event.setError(error); send(); } - public Audit clone() { - Audit clone = new Audit(); + public EventBuilder clone() { + EventBuilder clone = new EventBuilder(); clone.listeners = listeners; clone.event = event.clone(); return clone; } - public Audit reset() { + public EventBuilder reset() { Event old = event; event = new Event(); @@ -136,11 +136,11 @@ public class Audit { event.setTime(System.currentTimeMillis()); if (listeners != null) { - for (AuditListener l : listeners) { + for (EventListenerProvider l : listeners) { try { l.onEvent(event); } catch (Throwable t) { - log.error("Failed to send event to " + l, t); + log.error("Failed to send type to " + l, t); } } } diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditListener.java b/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java similarity index 64% rename from audit/api/src/main/java/org/keycloak/audit/AuditListener.java rename to events/api/src/main/java/org/keycloak/events/EventListenerProvider.java index 1425379d8f..01ab302575 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditListener.java +++ b/events/api/src/main/java/org/keycloak/events/EventListenerProvider.java @@ -1,11 +1,11 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.keycloak.provider.Provider; /** * @author Stian Thorgersen */ -public interface AuditListener extends Provider { +public interface EventListenerProvider extends Provider { public void onEvent(Event event); diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditListenerFactory.java b/events/api/src/main/java/org/keycloak/events/EventListenerProviderFactory.java similarity index 50% rename from audit/api/src/main/java/org/keycloak/audit/AuditListenerFactory.java rename to events/api/src/main/java/org/keycloak/events/EventListenerProviderFactory.java index 6ffeb20abd..968ae34ba1 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditListenerFactory.java +++ b/events/api/src/main/java/org/keycloak/events/EventListenerProviderFactory.java @@ -1,10 +1,10 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.keycloak.provider.ProviderFactory; /** * @author Stian Thorgersen */ -public interface AuditListenerFactory extends ProviderFactory { +public interface EventListenerProviderFactory extends ProviderFactory { } diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditProviderSpi.java b/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java similarity index 67% rename from audit/api/src/main/java/org/keycloak/audit/AuditProviderSpi.java rename to events/api/src/main/java/org/keycloak/events/EventListenerSpi.java index 249f7eab01..70cdea4385 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditProviderSpi.java +++ b/events/api/src/main/java/org/keycloak/events/EventListenerSpi.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderFactory; @@ -7,21 +7,21 @@ import org.keycloak.provider.Spi; /** * @author Stian Thorgersen */ -public class AuditProviderSpi implements Spi { +public class EventListenerSpi implements Spi { @Override public String getName() { - return "audit"; + return "eventsListener"; } @Override public Class getProviderClass() { - return AuditProvider.class; + return EventListenerProvider.class; } @Override public Class getProviderFactoryClass() { - return AuditProviderFactory.class; + return EventListenerProviderFactory.class; } } diff --git a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java b/events/api/src/main/java/org/keycloak/events/EventQuery.java similarity index 85% rename from audit/api/src/main/java/org/keycloak/audit/EventQuery.java rename to events/api/src/main/java/org/keycloak/events/EventQuery.java index 56ed79fe57..00d9a4fb93 100644 --- a/audit/api/src/main/java/org/keycloak/audit/EventQuery.java +++ b/events/api/src/main/java/org/keycloak/events/EventQuery.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; import java.util.List; @@ -7,7 +7,7 @@ import java.util.List; */ public interface EventQuery { - public EventQuery event(EventType... events); + public EventQuery type(EventType... types); public EventQuery realm(String realmId); diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditProvider.java b/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java similarity index 71% rename from audit/api/src/main/java/org/keycloak/audit/AuditProvider.java rename to events/api/src/main/java/org/keycloak/events/EventStoreProvider.java index 71e94341cf..c742556f64 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditProvider.java +++ b/events/api/src/main/java/org/keycloak/events/EventStoreProvider.java @@ -1,9 +1,9 @@ -package org.keycloak.audit; +package org.keycloak.events; /** * @author Stian Thorgersen */ -public interface AuditProvider extends AuditListener { +public interface EventStoreProvider extends EventListenerProvider { public EventQuery createQuery(); diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditProviderFactory.java b/events/api/src/main/java/org/keycloak/events/EventStoreProviderFactory.java similarity index 52% rename from audit/api/src/main/java/org/keycloak/audit/AuditProviderFactory.java rename to events/api/src/main/java/org/keycloak/events/EventStoreProviderFactory.java index 8d6331e46c..99e74aeac3 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditProviderFactory.java +++ b/events/api/src/main/java/org/keycloak/events/EventStoreProviderFactory.java @@ -1,10 +1,10 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.keycloak.provider.ProviderFactory; /** * @author Stian Thorgersen */ -public interface AuditProviderFactory extends ProviderFactory { +public interface EventStoreProviderFactory extends ProviderFactory { } diff --git a/audit/api/src/main/java/org/keycloak/audit/AuditListenerSpi.java b/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java similarity index 68% rename from audit/api/src/main/java/org/keycloak/audit/AuditListenerSpi.java rename to events/api/src/main/java/org/keycloak/events/EventStoreSpi.java index e2f0b9cf46..573fc86124 100644 --- a/audit/api/src/main/java/org/keycloak/audit/AuditListenerSpi.java +++ b/events/api/src/main/java/org/keycloak/events/EventStoreSpi.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; import org.keycloak.provider.Provider; import org.keycloak.provider.ProviderFactory; @@ -7,21 +7,21 @@ import org.keycloak.provider.Spi; /** * @author Stian Thorgersen */ -public class AuditListenerSpi implements Spi { +public class EventStoreSpi implements Spi { @Override public String getName() { - return "audit-listener"; + return "eventsStore"; } @Override public Class getProviderClass() { - return AuditListener.class; + return EventStoreProvider.class; } @Override public Class getProviderFactoryClass() { - return AuditListenerFactory.class; + return EventStoreProviderFactory.class; } } diff --git a/audit/api/src/main/java/org/keycloak/audit/EventType.java b/events/api/src/main/java/org/keycloak/events/EventType.java similarity index 96% rename from audit/api/src/main/java/org/keycloak/audit/EventType.java rename to events/api/src/main/java/org/keycloak/events/EventType.java index 0913ef33c9..1e7a2c0730 100755 --- a/audit/api/src/main/java/org/keycloak/audit/EventType.java +++ b/events/api/src/main/java/org/keycloak/events/EventType.java @@ -1,4 +1,4 @@ -package org.keycloak.audit; +package org.keycloak.events; /** * @author Stian Thorgersen diff --git a/events/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/events/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi new file mode 100644 index 0000000000..aeedcfb044 --- /dev/null +++ b/events/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi @@ -0,0 +1,2 @@ +org.keycloak.events.EventListenerSpi +org.keycloak.events.EventStoreSpi \ No newline at end of file diff --git a/audit/email/pom.xml b/events/email/pom.xml similarity index 84% rename from audit/email/pom.xml rename to events/email/pom.xml index 63f2ed5104..1d3193deec 100755 --- a/audit/email/pom.xml +++ b/events/email/pom.xml @@ -1,15 +1,15 @@ - keycloak-audit-parent + keycloak-events-parent org.keycloak 1.0-rc-2-SNAPSHOT 4.0.0 - keycloak-audit-email - Keycloak Audit Email Provider + keycloak-events-email + Keycloak Events Email Provider @@ -27,7 +27,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java similarity index 70% rename from audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java rename to events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java index 67a6eeb511..c0f6116974 100755 --- a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListener.java +++ b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java @@ -1,9 +1,9 @@ -package org.keycloak.audit.email; +package org.keycloak.events.email; import org.jboss.logging.Logger; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.email.EmailException; import org.keycloak.email.EmailProvider; import org.keycloak.models.KeycloakSession; @@ -16,16 +16,16 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class EmailAuditListener implements AuditListener { +public class EmailEventListenerProvider implements EventListenerProvider { - private static final Logger log = Logger.getLogger(EmailAuditListener.class); + private static final Logger log = Logger.getLogger(EmailEventListenerProvider.class); private KeycloakSession session; private RealmProvider model; private EmailProvider emailProvider; private Set includedEvents; - public EmailAuditListener(KeycloakSession session, EmailProvider emailProvider, Set includedEvents) { + public EmailEventListenerProvider(KeycloakSession session, EmailProvider emailProvider, Set includedEvents) { this.session = session; this.model = session.realms(); this.emailProvider = emailProvider; @@ -34,7 +34,7 @@ public class EmailAuditListener implements AuditListener { @Override public void onEvent(Event event) { - if (includedEvents.contains(event.getEvent())) { + if (includedEvents.contains(event.getType())) { if (event.getRealmId() != null && event.getUserId() != null) { RealmModel realm = model.getRealm(event.getRealmId()); UserModel user = session.users().getUserById(event.getUserId(), realm); @@ -42,7 +42,7 @@ public class EmailAuditListener implements AuditListener { try { emailProvider.setRealm(realm).setUser(user).sendEvent(event); } catch (EmailException e) { - log.error("Failed to send event mail", e); + log.error("Failed to send type mail", e); } } } diff --git a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListenerFactory.java b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java similarity index 76% rename from audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListenerFactory.java rename to events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java index baa62eb613..6920bd8226 100644 --- a/audit/email/src/main/java/org/keycloak/audit/email/EmailAuditListenerFactory.java +++ b/events/email/src/main/java/org/keycloak/events/email/EmailEventListenerProviderFactory.java @@ -1,9 +1,9 @@ -package org.keycloak.audit.email; +package org.keycloak.events.email; import org.keycloak.Config; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.AuditListenerFactory; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventListenerProviderFactory; +import org.keycloak.events.EventType; import org.keycloak.email.EmailProvider; import org.keycloak.models.KeycloakSession; @@ -14,7 +14,7 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class EmailAuditListenerFactory implements AuditListenerFactory { +public class EmailEventListenerProviderFactory implements EventListenerProviderFactory { private static final Set SUPPORTED_EVENTS = new HashSet(); static { @@ -24,9 +24,9 @@ public class EmailAuditListenerFactory implements AuditListenerFactory { private Set includedEvents = new HashSet(); @Override - public AuditListener create(KeycloakSession session) { + public EventListenerProvider create(KeycloakSession session) { EmailProvider emailProvider = session.getProvider(EmailProvider.class); - return new EmailAuditListener(session, emailProvider, includedEvents); + return new EmailEventListenerProvider(session, emailProvider, includedEvents); } @Override diff --git a/events/email/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/events/email/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory new file mode 100644 index 0000000000..31448f3ad3 --- /dev/null +++ b/events/email/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory @@ -0,0 +1 @@ +org.keycloak.events.email.EmailEventListenerProviderFactory \ No newline at end of file diff --git a/audit/jboss-logging/pom.xml b/events/jboss-logging/pom.xml similarity index 81% rename from audit/jboss-logging/pom.xml rename to events/jboss-logging/pom.xml index a2cfe93ec5..f693738f78 100755 --- a/audit/jboss-logging/pom.xml +++ b/events/jboss-logging/pom.xml @@ -1,15 +1,15 @@ - keycloak-audit-parent + keycloak-events-parent org.keycloak 1.0-rc-2-SNAPSHOT 4.0.0 - keycloak-audit-jboss-logging - Keycloak Audit JBoss Logging Provider + keycloak-events-jboss-logging + Keycloak Events JBoss Logging Provider @@ -32,7 +32,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java similarity index 82% rename from audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java rename to events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java index 691a3221fe..38fc305387 100644 --- a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListener.java +++ b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProvider.java @@ -1,19 +1,19 @@ -package org.keycloak.audit.log; +package org.keycloak.events.log; import org.jboss.logging.Logger; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.Event; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.Event; import java.util.Map; /** * @author Stian Thorgersen */ -public class JBossLoggingAuditListener implements AuditListener { +public class JBossLoggingEventListenerProvider implements EventListenerProvider { private final Logger logger; - public JBossLoggingAuditListener(Logger logger) { + public JBossLoggingEventListenerProvider(Logger logger) { this.logger = logger; } @@ -24,8 +24,8 @@ public class JBossLoggingAuditListener implements AuditListener { if (logger.isEnabled(level)) { StringBuilder sb = new StringBuilder(); - sb.append("event="); - sb.append(event.getEvent()); + sb.append("type="); + sb.append(event.getType()); sb.append(", realmId="); sb.append(event.getRealmId()); sb.append(", clientId="); diff --git a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProviderFactory.java similarity index 56% rename from audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java rename to events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProviderFactory.java index 7acef561fe..1bb4660e22 100644 --- a/audit/jboss-logging/src/main/java/org/keycloak/audit/log/JBossLoggingAuditListenerFactory.java +++ b/events/jboss-logging/src/main/java/org/keycloak/events/log/JBossLoggingEventListenerProviderFactory.java @@ -1,23 +1,23 @@ -package org.keycloak.audit.log; +package org.keycloak.events.log; import org.jboss.logging.Logger; import org.keycloak.Config; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.AuditListenerFactory; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventListenerProviderFactory; import org.keycloak.models.KeycloakSession; /** * @author Stian Thorgersen */ -public class JBossLoggingAuditListenerFactory implements AuditListenerFactory { +public class JBossLoggingEventListenerProviderFactory implements EventListenerProviderFactory { public static final String ID = "jboss-logging"; - private static final Logger logger = Logger.getLogger("org.keycloak.audit"); + private static final Logger logger = Logger.getLogger("org.keycloak.events"); @Override - public AuditListener create(KeycloakSession session) { - return new JBossLoggingAuditListener(logger); + public EventListenerProvider create(KeycloakSession session) { + return new JBossLoggingEventListenerProvider(logger); } @Override diff --git a/events/jboss-logging/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/events/jboss-logging/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory new file mode 100644 index 0000000000..c1ebc1f1a3 --- /dev/null +++ b/events/jboss-logging/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory @@ -0,0 +1 @@ +org.keycloak.events.log.JBossLoggingEventListenerProviderFactory \ No newline at end of file diff --git a/audit/jpa/pom.xml b/events/jpa/pom.xml similarity index 87% rename from audit/jpa/pom.xml rename to events/jpa/pom.xml index 92262ca80c..95d42d0258 100755 --- a/audit/jpa/pom.xml +++ b/events/jpa/pom.xml @@ -1,15 +1,15 @@ - keycloak-audit-parent + keycloak-events-parent org.keycloak 1.0-rc-2-SNAPSHOT 4.0.0 - keycloak-audit-jpa - Keycloak Audit JPA Provider + keycloak-events-jpa + Keycloak Events Store JPA Provider @@ -33,7 +33,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/EventEntity.java b/events/jpa/src/main/java/org/keycloak/events/jpa/EventEntity.java similarity index 91% rename from audit/jpa/src/main/java/org/keycloak/audit/jpa/EventEntity.java rename to events/jpa/src/main/java/org/keycloak/events/jpa/EventEntity.java index b22b576198..b5e16c56e4 100644 --- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/EventEntity.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/EventEntity.java @@ -1,4 +1,4 @@ -package org.keycloak.audit.jpa; +package org.keycloak.events.jpa; import javax.persistence.Column; import javax.persistence.Entity; @@ -19,8 +19,8 @@ public class EventEntity { @Column(name="TIME") private long time; - @Column(name="EVENT") - private String event; + @Column(name="TYPE") + private String type; @Column(name="REALM_ID") private String realmId; @@ -59,12 +59,12 @@ public class EventEntity { this.time = time; } - public String getEvent() { - return event; + public String getType() { + return type; } - public void setEvent(String event) { - this.event = event; + public void setType(String type) { + this.type = type; } public String getRealmId() { diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java similarity index 88% rename from audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java rename to events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java index 16d6b527f1..4c7fbe5e90 100644 --- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaEventQuery.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java @@ -1,8 +1,8 @@ -package org.keycloak.audit.jpa; +package org.keycloak.events.jpa; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; @@ -37,12 +37,12 @@ public class JpaEventQuery implements EventQuery { } @Override - public EventQuery event(EventType... events) { + public EventQuery type(EventType... types) { List eventStrings = new LinkedList(); - for (EventType e : events) { + for (EventType e : types) { eventStrings.add(e.toString()); } - predicates.add(root.get("event").in(eventStrings)); + predicates.add(root.get("type").in(eventStrings)); return this; } @@ -102,7 +102,7 @@ public class JpaEventQuery implements EventQuery { List events = new LinkedList(); for (EventEntity e : query.getResultList()) { - events.add(JpaAuditProvider.convert(e)); + events.add(JpaEventStoreProvider.convert(e)); } return events; diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProvider.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java similarity index 82% rename from audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProvider.java rename to events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java index ee2f7e9ecc..a5547cc524 100644 --- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProvider.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java @@ -1,12 +1,12 @@ -package org.keycloak.audit.jpa; +package org.keycloak.events.jpa; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.jboss.logging.Logger; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import javax.persistence.EntityManager; import javax.persistence.EntityTransaction; @@ -18,18 +18,18 @@ import java.util.UUID; /** * @author Stian Thorgersen */ -public class JpaAuditProvider implements AuditProvider { +public class JpaEventStoreProvider implements EventStoreProvider { private static final ObjectMapper mapper = new ObjectMapper(); private static final TypeReference> mapType = new TypeReference>() { }; - private static final Logger logger = Logger.getLogger(JpaAuditProvider.class); + private static final Logger logger = Logger.getLogger(JpaEventStoreProvider.class); private EntityManager em; private EntityTransaction tx; private Set includedEvents; - public JpaAuditProvider(EntityManager em, Set includedEvents) { + public JpaEventStoreProvider(EntityManager em, Set includedEvents) { this.em = em; this.includedEvents = includedEvents; } @@ -56,7 +56,7 @@ public class JpaAuditProvider implements AuditProvider { @Override public void onEvent(Event event) { - if (includedEvents.contains(event.getEvent())) { + if (includedEvents.contains(event.getType())) { em.persist(convert(event)); } } @@ -69,7 +69,7 @@ public class JpaAuditProvider implements AuditProvider { EventEntity e = new EventEntity(); e.setId(UUID.randomUUID().toString()); e.setTime(o.getTime()); - e.setEvent(o.getEvent().toString()); + e.setType(o.getType().toString()); e.setRealmId(o.getRealmId()); e.setClientId(o.getClientId()); e.setUserId(o.getUserId()); @@ -87,7 +87,7 @@ public class JpaAuditProvider implements AuditProvider { static Event convert(EventEntity o) { Event e = new Event(); e.setTime(o.getTime()); - e.setEvent(EventType.valueOf(o.getEvent())); + e.setType(EventType.valueOf(o.getType())); e.setRealmId(o.getRealmId()); e.setClientId(o.getClientId()); e.setUserId(o.getUserId()); diff --git a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProviderFactory.java similarity index 75% rename from audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java rename to events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProviderFactory.java index c471a7d9fd..b4922079d2 100644 --- a/audit/jpa/src/main/java/org/keycloak/audit/jpa/JpaAuditProviderFactory.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProviderFactory.java @@ -1,9 +1,9 @@ -package org.keycloak.audit.jpa; +package org.keycloak.events.jpa; import org.keycloak.Config; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.AuditProviderFactory; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.EventStoreProviderFactory; +import org.keycloak.events.EventType; import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.models.KeycloakSession; @@ -13,16 +13,16 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class JpaAuditProviderFactory implements AuditProviderFactory { +public class JpaEventStoreProviderFactory implements EventStoreProviderFactory { public static final String ID = "jpa"; private Set includedEvents = new HashSet(); @Override - public AuditProvider create(KeycloakSession session) { + public EventStoreProvider create(KeycloakSession session) { JpaConnectionProvider connection = session.getProvider(JpaConnectionProvider.class); - return new JpaAuditProvider(connection.getEntityManager(), includedEvents); + return new JpaEventStoreProvider(connection.getEntityManager(), includedEvents); } @Override diff --git a/events/jpa/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory b/events/jpa/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory new file mode 100644 index 0000000000..d7ae64abee --- /dev/null +++ b/events/jpa/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory @@ -0,0 +1 @@ +org.keycloak.events.jpa.JpaEventStoreProviderFactory \ No newline at end of file diff --git a/audit/mongo/pom.xml b/events/mongo/pom.xml similarity index 84% rename from audit/mongo/pom.xml rename to events/mongo/pom.xml index f6bff6e509..2d69e7b179 100755 --- a/audit/mongo/pom.xml +++ b/events/mongo/pom.xml @@ -1,15 +1,15 @@ - keycloak-audit-parent + keycloak-events-parent org.keycloak 1.0-rc-2-SNAPSHOT 4.0.0 - keycloak-audit-mongo - Keycloak Audit Mongo Provider + keycloak-events-mongo + Keycloak Events Store Mongo Provider @@ -33,7 +33,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java similarity index 83% rename from audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java rename to events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java index 32fc924802..fe08949d88 100755 --- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoEventQuery.java +++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java @@ -1,11 +1,11 @@ -package org.keycloak.audit.mongo; +package org.keycloak.events.mongo; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBCursor; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import java.util.LinkedList; import java.util.List; @@ -26,12 +26,12 @@ public class MongoEventQuery implements EventQuery { } @Override - public EventQuery event(EventType... events) { + public EventQuery type(EventType... types) { List eventStrings = new LinkedList(); - for (EventType e : events) { + for (EventType e : types) { eventStrings.add(e.toString()); } - query.put("event", new BasicDBObject("$in", eventStrings)); + query.put("type", new BasicDBObject("$in", eventStrings)); return this; } @@ -83,7 +83,7 @@ public class MongoEventQuery implements EventQuery { List events = new LinkedList(); while (cur.hasNext()) { - events.add(MongoAuditProvider.convert((BasicDBObject) cur.next())); + events.add(MongoEventStoreProvider.convert((BasicDBObject) cur.next())); } return events; diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProvider.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java similarity index 74% rename from audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProvider.java rename to events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java index 5fcdc41330..58388b5e28 100644 --- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProvider.java +++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java @@ -1,12 +1,12 @@ -package org.keycloak.audit.mongo; +package org.keycloak.events.mongo; import com.mongodb.BasicDBObject; import com.mongodb.DBCollection; import com.mongodb.DBObject; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import java.util.HashMap; import java.util.Map; @@ -15,29 +15,29 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class MongoAuditProvider implements AuditProvider { +public class MongoEventStoreProvider implements EventStoreProvider { - private DBCollection audit; + private DBCollection events; private Set includedEvents; - public MongoAuditProvider(DBCollection audit, Set includedEvents) { - this.audit = audit; + public MongoEventStoreProvider(DBCollection events, Set includedEvents) { + this.events = events; this.includedEvents = includedEvents; } @Override public EventQuery createQuery() { - return new MongoEventQuery(audit); + return new MongoEventQuery(events); } @Override public void clear() { - audit.remove(new BasicDBObject()); + events.remove(new BasicDBObject()); } @Override public void clear(String realmId) { - audit.remove(new BasicDBObject("realmId", realmId)); + events.remove(new BasicDBObject("realmId", realmId)); } @Override @@ -45,13 +45,13 @@ public class MongoAuditProvider implements AuditProvider { BasicDBObject q = new BasicDBObject(); q.put("realmId", realmId); q.put("time", new BasicDBObject("$lt", olderThan)); - audit.remove(q); + events.remove(q); } @Override public void onEvent(Event event) { - if (includedEvents.contains(event.getEvent())) { - audit.insert(convert(event)); + if (includedEvents.contains(event.getType())) { + events.insert(convert(event)); } } @@ -62,7 +62,7 @@ public class MongoAuditProvider implements AuditProvider { static DBObject convert(Event o) { BasicDBObject e = new BasicDBObject(); e.put("time", o.getTime()); - e.put("event", o.getEvent().toString()); + e.put("type", o.getType().toString()); e.put("realmId", o.getRealmId()); e.put("clientId", o.getClientId()); e.put("userId", o.getUserId()); @@ -84,7 +84,7 @@ public class MongoAuditProvider implements AuditProvider { static Event convert(BasicDBObject o) { Event e = new Event(); e.setTime(o.getLong("time")); - e.setEvent(EventType.valueOf(o.getString("event"))); + e.setType(EventType.valueOf(o.getString("type"))); e.setRealmId(o.getString("realmId")); e.setClientId(o.getString("clientId")); e.setUserId(o.getString("userId")); diff --git a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java similarity index 77% rename from audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java rename to events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java index 79f4f5dd63..80ac5add32 100644 --- a/audit/mongo/src/main/java/org/keycloak/audit/mongo/MongoAuditProviderFactory.java +++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProviderFactory.java @@ -1,12 +1,12 @@ -package org.keycloak.audit.mongo; +package org.keycloak.events.mongo; import com.mongodb.DBCollection; import com.mongodb.WriteConcern; import org.jboss.logging.Logger; import org.keycloak.Config; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.AuditProviderFactory; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.EventStoreProviderFactory; +import org.keycloak.events.EventType; import org.keycloak.connections.mongo.MongoConnectionProvider; import org.keycloak.models.KeycloakSession; @@ -16,22 +16,22 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class MongoAuditProviderFactory implements AuditProviderFactory { +public class MongoEventStoreProviderFactory implements EventStoreProviderFactory { - protected static final Logger logger = Logger.getLogger(MongoAuditProviderFactory.class); + protected static final Logger logger = Logger.getLogger(MongoEventStoreProviderFactory.class); public static final String ID = "mongo"; private Set includedEvents = new HashSet(); @Override - public AuditProvider create(KeycloakSession session) { + public EventStoreProvider create(KeycloakSession session) { MongoConnectionProvider connection = session.getProvider(MongoConnectionProvider.class); - DBCollection collection = connection.getDB().getCollection("audit"); + DBCollection collection = connection.getDB().getCollection("events"); collection.setWriteConcern(WriteConcern.UNACKNOWLEDGED); - return new MongoAuditProvider(collection, includedEvents); + return new MongoEventStoreProvider(collection, includedEvents); } @Override diff --git a/events/mongo/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory b/events/mongo/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory new file mode 100644 index 0000000000..8e3a9e1ff2 --- /dev/null +++ b/events/mongo/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory @@ -0,0 +1 @@ +org.keycloak.events.mongo.MongoEventStoreProviderFactory \ No newline at end of file diff --git a/audit/pom.xml b/events/pom.xml similarity index 87% rename from audit/pom.xml rename to events/pom.xml index e9760dcf3f..1a00866602 100755 --- a/audit/pom.xml +++ b/events/pom.xml @@ -7,12 +7,12 @@ ../pom.xml - Audit Parent + Events Parent 4.0.0 org.keycloak - keycloak-audit-parent + keycloak-events-parent pom diff --git a/examples/providers/audit-listener-sysout/README.md b/examples/providers/audit-listener-sysout/README.md deleted file mode 100644 index ac89c52e21..0000000000 --- a/examples/providers/audit-listener-sysout/README.md +++ /dev/null @@ -1,4 +0,0 @@ -Example Audit Listener that prints events to System.out -======================================================= - -To deploy copy target/audit-listener-sysout-example.jar to standalone/deployments/auth-server.war/WEB-INF/lib. Then start (or restart) the server. Once started open the admin console, select your realm, then click on Audit, followed by config. Click on Audit Listeners select box, then pick sysout from the dropdown. After this try to logout and login again to see events printed to System.out. diff --git a/examples/providers/audit-listener-sysout/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory b/examples/providers/audit-listener-sysout/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory deleted file mode 100644 index 635efe7181..0000000000 --- a/examples/providers/audit-listener-sysout/src/main/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.examples.providers.audit.SysoutAuditListenerFactory \ No newline at end of file diff --git a/examples/providers/audit-provider-mem/README.md b/examples/providers/audit-provider-mem/README.md deleted file mode 100644 index d91dc7f29b..0000000000 --- a/examples/providers/audit-provider-mem/README.md +++ /dev/null @@ -1,16 +0,0 @@ -Example Audit Provider that stores events in a List -=================================================== - -To deploy copy target/audit-provider-mem-example.jar to standalone/deployments/auth-server.war/WEB-INF/lib. Then edit standalone/configuration/keycloak-server.json, change: - - "audit": { - "provider": "jpa" - } - -to: - - "audit": { - "provider": "in-mem" - } - -Then start (or restart)the server. Once started open the admin console, select your realm, then click on Audit, followed by config. Set the toggle for Enabled to ON. After this try to logout and login again then open the Audit tab again in the admin console to view events from the in-mem provider. diff --git a/examples/providers/audit-provider-mem/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory b/examples/providers/audit-provider-mem/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory deleted file mode 100644 index 5f03c5747f..0000000000 --- a/examples/providers/audit-provider-mem/src/main/resources/META-INF/services/org.keycloak.audit.AuditProviderFactory +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.examples.providers.audit.MemAuditProviderFactory \ No newline at end of file diff --git a/examples/providers/event-listener-sysout/README.md b/examples/providers/event-listener-sysout/README.md new file mode 100644 index 0000000000..1d762d73b1 --- /dev/null +++ b/examples/providers/event-listener-sysout/README.md @@ -0,0 +1,4 @@ +Example Event Listener that prints events to System.out +======================================================= + +To deploy copy target/event-listener-sysout-example.jar to standalone/deployments/auth-server.war/WEB-INF/lib. Then start (or restart) the server. Once started open the admin console, select your realm, then click on Events, followed by config. Click on Listeners select box, then pick sysout from the dropdown. After this try to logout and login again to see events printed to System.out. diff --git a/examples/providers/audit-listener-sysout/pom.xml b/examples/providers/event-listener-sysout/pom.xml similarity index 83% rename from examples/providers/audit-listener-sysout/pom.xml rename to examples/providers/event-listener-sysout/pom.xml index 5a3f0cb747..cc546d444e 100755 --- a/examples/providers/audit-listener-sysout/pom.xml +++ b/examples/providers/event-listener-sysout/pom.xml @@ -6,11 +6,11 @@ 1.0-rc-2-SNAPSHOT ../pom.xml - Audit Listener System.out Example + Event Listener System.out Example 4.0.0 - audit-listener-sysout-example + event-listener-sysout-example jar @@ -26,13 +26,13 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} - audit-listener-sysout-example + event-listener-sysout-example org.apache.maven.plugins diff --git a/examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListener.java b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java similarity index 80% rename from examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListener.java rename to examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java index 402b2b9d6e..f0ed12078b 100644 --- a/examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListener.java +++ b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProvider.java @@ -1,8 +1,8 @@ -package org.keycloak.examples.providers.audit; +package org.keycloak.examples.providers.events; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import java.util.Map; import java.util.Set; @@ -10,18 +10,18 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class SysoutAuditListener implements AuditListener { +public class SysoutEventListenerProvider implements EventListenerProvider { private Set excludedEvents; - public SysoutAuditListener(Set excludedEvents) { + public SysoutEventListenerProvider(Set excludedEvents) { this.excludedEvents = excludedEvents; } @Override public void onEvent(Event event) { // Ignore excluded events - if (excludedEvents != null && excludedEvents.contains(event.getEvent())) { + if (excludedEvents != null && excludedEvents.contains(event.getType())) { return; } else { System.out.println("EVENT: " + toString(event)); @@ -31,8 +31,8 @@ public class SysoutAuditListener implements AuditListener { private String toString(Event event) { StringBuilder sb = new StringBuilder(); - sb.append("event="); - sb.append(event.getEvent()); + sb.append("type="); + sb.append(event.getType()); sb.append(", realmId="); sb.append(event.getRealmId()); sb.append(", clientId="); diff --git a/examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListenerFactory.java b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java similarity index 63% rename from examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListenerFactory.java rename to examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java index 368446c6b4..600ddf0db2 100644 --- a/examples/providers/audit-listener-sysout/src/main/java/org/keycloak/examples/providers/audit/SysoutAuditListenerFactory.java +++ b/examples/providers/event-listener-sysout/src/main/java/org/keycloak/examples/providers/events/SysoutEventListenerProviderFactory.java @@ -1,9 +1,9 @@ -package org.keycloak.examples.providers.audit; +package org.keycloak.examples.providers.events; import org.keycloak.Config; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.AuditListenerFactory; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventListenerProviderFactory; +import org.keycloak.events.EventType; import org.keycloak.models.KeycloakSession; import java.util.HashSet; @@ -12,13 +12,13 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class SysoutAuditListenerFactory implements AuditListenerFactory { +public class SysoutEventListenerProviderFactory implements EventListenerProviderFactory { private Set excludedEvents; @Override - public AuditListener create(KeycloakSession session) { - return new SysoutAuditListener(excludedEvents); + public EventListenerProvider create(KeycloakSession session) { + return new SysoutEventListenerProvider(excludedEvents); } @Override diff --git a/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory b/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory new file mode 100644 index 0000000000..636ed4ec85 --- /dev/null +++ b/examples/providers/event-listener-sysout/src/main/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory @@ -0,0 +1 @@ +org.keycloak.examples.providers.events.SysoutEventListenerProviderFactory \ No newline at end of file diff --git a/examples/providers/event-store-mem/README.md b/examples/providers/event-store-mem/README.md new file mode 100644 index 0000000000..d7d6249065 --- /dev/null +++ b/examples/providers/event-store-mem/README.md @@ -0,0 +1,16 @@ +Example Event Store that stores events in memory +================================================ + +To deploy copy target/event-store-mem-example.jar to standalone/deployments/auth-server.war/WEB-INF/lib. Then edit standalone/configuration/keycloak-server.json, change: + + "event-store": { + "provider": "jpa" + } + +to: + + "event-store": { + "provider": "in-mem" + } + +Then start (or restart)the server. Once started open the admin console, select your realm, then click on Events, followed by config. Set the toggle for Enabled to ON. After this try to logout and login again then open the Events tab again in the admin console to view events from the in-mem provider. diff --git a/examples/providers/audit-provider-mem/pom.xml b/examples/providers/event-store-mem/pom.xml similarity index 84% rename from examples/providers/audit-provider-mem/pom.xml rename to examples/providers/event-store-mem/pom.xml index d9b26d8e52..447e806dad 100755 --- a/examples/providers/audit-provider-mem/pom.xml +++ b/examples/providers/event-store-mem/pom.xml @@ -6,11 +6,11 @@ 1.0-rc-2-SNAPSHOT ../pom.xml - Audit Provider In-Mem Example + Event Store In-Mem Example 4.0.0 - audit-provider-mem-example + event-store-mem-example jar @@ -26,13 +26,13 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} - audit-provider-mem-example + event-store-mem-example org.apache.maven.plugins diff --git a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemEventQuery.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java similarity index 89% rename from examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemEventQuery.java rename to examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java index a8b98e289d..06038c75ff 100644 --- a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemEventQuery.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java @@ -1,8 +1,8 @@ -package org.keycloak.examples.providers.audit; +package org.keycloak.examples.providers.events; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import java.util.Collections; import java.util.Iterator; @@ -23,13 +23,13 @@ public class MemEventQuery implements EventQuery { } @Override - public EventQuery event(EventType... events) { + public EventQuery type(EventType... types) { Iterator itr = this.events.iterator(); while (itr.hasNext()) { Event next = itr.next(); boolean include = false; - for (EventType e : events) { - if (next.getEvent().equals(e)) { + for (EventType e : types) { + if (next.getType().equals(e)) { include = true; break; } diff --git a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProvider.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java similarity index 79% rename from examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProvider.java rename to examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java index ddeb1d0448..8a00b7eb19 100644 --- a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProvider.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java @@ -1,9 +1,9 @@ -package org.keycloak.examples.providers.audit; +package org.keycloak.examples.providers.events; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import java.util.Iterator; import java.util.LinkedList; @@ -13,11 +13,11 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class MemAuditProvider implements AuditProvider { +public class MemEventStoreProvider implements EventStoreProvider { private final List events; private final Set excludedEvents; - public MemAuditProvider(List events, Set excludedEvents) { + public MemEventStoreProvider(List events, Set excludedEvents) { this.events = events; this.excludedEvents = excludedEvents; } diff --git a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProviderFactory.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java similarity index 69% rename from examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProviderFactory.java rename to examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java index 948bfbc460..88818ea64e 100644 --- a/examples/providers/audit-provider-mem/src/main/java/org/keycloak/examples/providers/audit/MemAuditProviderFactory.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProviderFactory.java @@ -1,10 +1,10 @@ -package org.keycloak.examples.providers.audit; +package org.keycloak.examples.providers.events; import org.keycloak.Config; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.AuditProviderFactory; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.EventStoreProviderFactory; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.KeycloakSession; import java.util.Collections; @@ -16,15 +16,15 @@ import java.util.Set; /** * @author Stian Thorgersen */ -public class MemAuditProviderFactory implements AuditProviderFactory { +public class MemEventStoreProviderFactory implements EventStoreProviderFactory { private List events; private Set excludedEvents; @Override - public AuditProvider create(KeycloakSession session) { - return new MemAuditProvider(events, excludedEvents); + public EventStoreProvider create(KeycloakSession session) { + return new MemEventStoreProvider(events, excludedEvents); } @Override diff --git a/examples/providers/event-store-mem/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory b/examples/providers/event-store-mem/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory new file mode 100644 index 0000000000..92e783cb58 --- /dev/null +++ b/examples/providers/event-store-mem/src/main/resources/META-INF/services/org.keycloak.events.EventStoreProviderFactory @@ -0,0 +1 @@ +events.MemEventStoreProviderFactory \ No newline at end of file diff --git a/examples/providers/pom.xml b/examples/providers/pom.xml index 36bb293ade..84c00b21d9 100755 --- a/examples/providers/pom.xml +++ b/examples/providers/pom.xml @@ -25,8 +25,8 @@ - audit-listener-sysout - audit-provider-mem + event-listener-sysout + event-store-mem federation-provider diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index a537fd7ab1..14e3a1ef2f 100755 --- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -48,13 +48,13 @@ public class ExportUtils { RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm); // Audit - rep.setAuditEnabled(realm.isAuditEnabled()); - if (realm.getAuditExpiration() != 0) { - rep.setAuditExpiration(realm.getAuditExpiration()); + rep.setEventsEnabled(realm.isEventsEnabled()); + if (realm.getEventsExpiration() != 0) { + rep.setEventsExpiration(realm.getEventsExpiration()); } - if (realm.getAuditListeners() != null) { - rep.setAuditListeners(new LinkedList(realm.getAuditListeners())); + if (realm.getEventsListeners() != null) { + rep.setEventsListeners(new LinkedList(realm.getEventsListeners())); } // Applications diff --git a/forms/account-api/pom.xml b/forms/account-api/pom.xml index 224811888f..f972cb5f45 100755 --- a/forms/account-api/pom.xml +++ b/forms/account-api/pom.xml @@ -28,7 +28,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java b/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java index f021e84777..8a4a487ab5 100644 --- a/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java +++ b/forms/account-api/src/main/java/org/keycloak/account/AccountProvider.java @@ -1,6 +1,6 @@ package org.keycloak.account; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; @@ -37,5 +37,5 @@ public interface AccountProvider extends Provider { AccountProvider setSessions(List sessions); - AccountProvider setFeatures(boolean social, boolean audit, boolean passwordUpdateSupported); + AccountProvider setFeatures(boolean social, boolean events, boolean passwordUpdateSupported); } diff --git a/forms/account-freemarker/pom.xml b/forms/account-freemarker/pom.xml index 9bb7b042f6..c0e4b967db 100755 --- a/forms/account-freemarker/pom.xml +++ b/forms/account-freemarker/pom.xml @@ -52,7 +52,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java index 6ec3416205..552d59ae0a 100755 --- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java +++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java @@ -12,7 +12,7 @@ import org.keycloak.account.freemarker.model.ReferrerBean; import org.keycloak.account.freemarker.model.SessionsBean; import org.keycloak.account.freemarker.model.TotpBean; import org.keycloak.account.freemarker.model.UrlBean; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import org.keycloak.freemarker.BrowserSecurityHeaderSetup; import org.keycloak.freemarker.FreeMarkerException; import org.keycloak.freemarker.FreeMarkerUtil; @@ -47,8 +47,8 @@ public class FreeMarkerAccountProvider implements AccountProvider { private String[] referrer; private List events; private List sessions; - private boolean social; - private boolean audit; + private boolean socialEnabled; + private boolean eventsEnabled; private boolean passwordUpdateSupported; private KeycloakSession session; private FreeMarkerUtil freeMarker; @@ -115,7 +115,7 @@ public class FreeMarkerAccountProvider implements AccountProvider { attributes.put("url", new UrlBean(realm, theme, baseUri, baseQueryUri, uriInfo.getRequestUri())); - attributes.put("features", new FeaturesBean(social, audit, passwordUpdateSupported)); + attributes.put("features", new FeaturesBean(socialEnabled, eventsEnabled, passwordUpdateSupported)); switch (page) { case ACCOUNT: @@ -204,9 +204,9 @@ public class FreeMarkerAccountProvider implements AccountProvider { } @Override - public AccountProvider setFeatures(boolean social, boolean audit, boolean passwordUpdateSupported) { - this.social = social; - this.audit = audit; + public AccountProvider setFeatures(boolean socialEnabled, boolean eventsEnabled, boolean passwordUpdateSupported) { + this.socialEnabled = socialEnabled; + this.eventsEnabled = eventsEnabled; this.passwordUpdateSupported = passwordUpdateSupported; 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 index 31c13a3082..76fc8572f5 100644 --- 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 @@ -1,6 +1,6 @@ package org.keycloak.account.freemarker.model; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import java.util.Date; import java.util.LinkedList; @@ -38,7 +38,7 @@ public class LogBean { } public String getEvent() { - return event.getEvent().toString().toLowerCase().replace("_", " "); + return event.getType().toString().toLowerCase().replace("_", " "); } public String getClient() { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js index 4c434c2a14..c203d39962 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/app.js @@ -197,17 +197,17 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'RealmSMTPSettingsCtrl' }) - .when('/realms/:realm/audit', { - templateUrl : 'partials/realm-audit.html', + .when('/realms/:realm/events', { + templateUrl : 'partials/realm-events.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); } }, - controller : 'RealmAuditEventsCtrl' + controller : 'RealmEventsCtrl' }) - .when('/realms/:realm/audit-settings', { - templateUrl : 'partials/realm-audit-config.html', + .when('/realms/:realm/events-settings', { + templateUrl : 'partials/realm-events-config.html', resolve : { realm : function(RealmLoader) { return RealmLoader(); @@ -215,11 +215,11 @@ module.config([ '$routeProvider', function($routeProvider) { serverInfo : function(ServerInfoLoader) { return ServerInfoLoader(); }, - auditConfig : function(RealmAuditLoader) { - return RealmAuditLoader(); + eventsConfig : function(RealmEventsConfigLoader) { + return RealmEventsConfigLoader(); } }, - controller : 'RealmAuditCtrl' + controller : 'RealmEventsConfigCtrl' }) .when('/create/user/:realm', { templateUrl : 'partials/user-detail.html', diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js index 8ce2c34ba3..969aa9a827 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js @@ -49,8 +49,8 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $ return getAccess('view-users') || this.manageClients; }, - get viewAudit() { - return getAccess('view-audit') || this.manageClients; + get viewEvents() { + return getAccess('view-events') || this.manageClients; }, get manageRealm() { @@ -69,8 +69,8 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $ return getAccess('manage-users'); }, - get manageAudit() { - return getAccess('manage-audit'); + get manageEvents() { + return getAccess('manage-events'); } } @@ -957,26 +957,26 @@ module.controller('RealmSMTPSettingsCtrl', function($scope, Current, Realm, real } }); -module.controller('RealmAuditCtrl', function($scope, auditConfig, RealmAudit, RealmAuditEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) { +module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmEventsConfig, RealmEvents, realm, serverInfo, $location, Notifications, TimeUnit, Dialog) { $scope.realm = realm; - $scope.auditConfig = auditConfig; + $scope.eventsConfig = eventsConfig; - $scope.auditConfig.expirationUnit = TimeUnit.autoUnit(auditConfig.auditExpiration); - $scope.auditConfig.auditExpiration = TimeUnit.toUnit(auditConfig.auditExpiration, $scope.auditConfig.expirationUnit); - $scope.$watch('auditConfig.expirationUnit', function(to, from) { - if ($scope.auditConfig.auditExpiration) { - $scope.auditConfig.auditExpiration = TimeUnit.convert($scope.auditConfig.auditExpiration, from, to); + $scope.eventsConfig.expirationUnit = TimeUnit.autoUnit(eventsConfig.eventsExpiration); + $scope.eventsConfig.eventsExpiration = TimeUnit.toUnit(eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit); + $scope.$watch('eventsConfig.expirationUnit', function(to, from) { + if ($scope.eventsConfig.eventsExpiration) { + $scope.eventsConfig.eventsExpiration = TimeUnit.convert($scope.eventsConfig.eventsExpiration, from, to); } }); - $scope.auditListeners = serverInfo.auditListeners; + $scope.eventListeners = serverInfo.eventListeners; - var oldCopy = angular.copy($scope.auditConfig); + var oldCopy = angular.copy($scope.eventsConfig); $scope.changed = false; - $scope.$watch('auditConfig', function() { - if (!angular.equals($scope.auditConfig, oldCopy)) { + $scope.$watch('eventsConfig', function() { + if (!angular.equals($scope.eventsConfig, oldCopy)) { $scope.changed = true; } }, true); @@ -984,34 +984,34 @@ module.controller('RealmAuditCtrl', function($scope, auditConfig, RealmAudit, Re $scope.save = function() { $scope.changed = false; - var copy = angular.copy($scope.auditConfig) + var copy = angular.copy($scope.eventsConfig) delete copy['expirationUnit']; - copy.auditExpiration = TimeUnit.toSeconds($scope.auditConfig.auditExpiration, $scope.auditConfig.expirationUnit); + copy.eventsExpiration = TimeUnit.toSeconds($scope.eventsConfig.eventsExpiration, $scope.eventsConfig.expirationUnit); - RealmAudit.update({ + RealmEventsConfig.update({ id : realm.realm }, copy, function () { - $location.url("/realms/" + realm.realm + "/audit-settings"); + $location.url("/realms/" + realm.realm + "/events-settings"); Notifications.success("Your changes have been saved to the realm."); }); }; $scope.reset = function() { - $scope.auditConfig = angular.copy(oldCopy); + $scope.eventsConfig = angular.copy(oldCopy); $scope.changed = false; }; - $scope.clearAudit = function() { - Dialog.confirmDelete($scope.realm.realm, 'audit events', function() { - RealmAuditEvents.remove({ id : $scope.realm.realm }, function() { - Notifications.success("The audit events has been cleared."); + $scope.clearEvents = function() { + Dialog.confirmDelete($scope.realm.realm, 'events', function() { + RealmEvents.remove({ id : $scope.realm.realm }, function() { + Notifications.success("The events has been cleared."); }); }); }; }); -module.controller('RealmAuditEventsCtrl', function($scope, RealmAuditEvents, realm) { +module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm) { $scope.realm = realm; $scope.page = 0; @@ -1027,7 +1027,7 @@ module.controller('RealmAuditEventsCtrl', function($scope, RealmAuditEvents, rea delete $scope.query[i]; } } - $scope.events = RealmAuditEvents.query($scope.query); + $scope.events = RealmEvents.query($scope.query); } $scope.firstPage = function() { diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js index 987d8c765c..30785b7c86 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/loaders.js @@ -47,8 +47,8 @@ module.factory('RealmLoader', function(Loader, Realm, $route, $q) { }); }); -module.factory('RealmAuditLoader', function(Loader, RealmAudit, $route, $q) { - return Loader.get(RealmAudit, function() { +module.factory('RealmEventsConfigLoader', function(Loader, RealmEventsConfig, $route, $q) { + return Loader.get(RealmEventsConfig, function() { return { id : $route.current.params.realm } diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js index efed6c785a..e5fbcbfdde 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/services.js @@ -164,8 +164,8 @@ module.factory('Realm', function($resource) { }); }); -module.factory('RealmAudit', function($resource) { - return $resource(authUrl + '/admin/realms/:id/audit', { +module.factory('RealmEventsConfig', function($resource) { + return $resource(authUrl + '/admin/realms/:id/events/config', { id : '@realm' }, { update : { @@ -174,8 +174,8 @@ module.factory('RealmAudit', function($resource) { }); }); -module.factory('RealmAuditEvents', function($resource) { - return $resource(authUrl + '/admin/realms/:id/audit/events', { +module.factory('RealmEvents', function($resource) { + return $resource(authUrl + '/admin/realms/:id/events', { id : '@realm' }); }); diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit-config.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit-config.html deleted file mode 100755 index a436882af7..0000000000 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit-config.html +++ /dev/null @@ -1,65 +0,0 @@ -
-
- - -

-
-

{{realm.realm}} Audit Config

- -
-
-
- -
- -
-
-
- -
- -
-
- -
- -
-
-
- -
-
- -
-
-
-
- -
- - -
- -
-
-
- -
- - -
-
-
-
- diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events-config.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events-config.html new file mode 100755 index 0000000000..1a0e607710 --- /dev/null +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events-config.html @@ -0,0 +1,64 @@ +
+
+ + +

+
+

{{realm.realm}} Events Config

+ +
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+ +
+
+ +
+ +
+ + +
+ +
+ + +
+
+ +
+ + +
+
+
+
+ diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html similarity index 86% rename from forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit.html rename to forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html index e1f1e7a993..9bd6db2ea8 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-audit.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html @@ -2,13 +2,13 @@

-

{{realm.realm}} Audit Log

+

{{realm.realm}} Events

@@ -30,9 +30,9 @@
- +
- +
@@ -70,7 +70,7 @@
- +
{{event.time|date:'shortDate'}}
{{event.time|date:'mediumTime'}}
{{event.event}}{{event.type}} diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html index f34df5f1ec..8415ba23ee 100755 --- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html +++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-menu.html @@ -15,5 +15,5 @@
  • OAuth Clients
  • Sessions and Tokens
  • Security Defenses
  • -
  • Audit
  • +
  • Events
  • \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/tables.css b/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/tables.css index b0a1f83af6..65b34d92d4 100644 --- a/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/tables.css +++ b/forms/common-themes/src/main/resources/theme/admin/keycloak/resources/css/tables.css @@ -64,11 +64,11 @@ table tfoot tr .table-nav span { } -td.audit-success { +td.events-success { background-color: #E4F1E1 !important; } -td.audit-error { +td.events-error { background-color: #F8E7E7 !important; } diff --git a/forms/common-themes/src/main/resources/theme/email/keycloak/event-login_error.ftl b/forms/common-themes/src/main/resources/theme/email/keycloak/event-login_error.ftl index 93e02bea11..c1227aa882 100644 --- a/forms/common-themes/src/main/resources/theme/email/keycloak/event-login_error.ftl +++ b/forms/common-themes/src/main/resources/theme/email/keycloak/event-login_error.ftl @@ -1 +1 @@ -Your password was changed on ${event.date} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file +A failed login attempt was dettected to your account on ${event.date?datetime} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/email/keycloak/event-remove_totp.ftl b/forms/common-themes/src/main/resources/theme/email/keycloak/event-remove_totp.ftl index 0c6a142c7d..c62e174053 100644 --- a/forms/common-themes/src/main/resources/theme/email/keycloak/event-remove_totp.ftl +++ b/forms/common-themes/src/main/resources/theme/email/keycloak/event-remove_totp.ftl @@ -1 +1 @@ -TOTP was removed from your account on ${event.date} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file +TOTP was removed from your account on ${event.date?datetime} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_password.ftl b/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_password.ftl index 8c3a94f76d..696a6e6181 100644 --- a/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_password.ftl +++ b/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_password.ftl @@ -1 +1 @@ -A failed login attempt was dettected to your account on ${event.date} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file +Your password was changed on ${event.date?datetime} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file diff --git a/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_totp.ftl b/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_totp.ftl index a1f153c2ae..531ae662be 100644 --- a/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_totp.ftl +++ b/forms/common-themes/src/main/resources/theme/email/keycloak/event-update_totp.ftl @@ -1 +1 @@ -TOTP was updated for your account on ${event.date} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file +TOTP was updated for your account on ${event.date?datetime} from ${event.ipAddress}. If this was not you, please contact an admin. \ No newline at end of file diff --git a/forms/email-api/pom.xml b/forms/email-api/pom.xml index 30c2929434..ddcc49e9fa 100755 --- a/forms/email-api/pom.xml +++ b/forms/email-api/pom.xml @@ -28,7 +28,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/forms/email-api/src/main/java/org/keycloak/email/EmailProvider.java b/forms/email-api/src/main/java/org/keycloak/email/EmailProvider.java index eb8f3e78dc..1d7aff3275 100644 --- a/forms/email-api/src/main/java/org/keycloak/email/EmailProvider.java +++ b/forms/email-api/src/main/java/org/keycloak/email/EmailProvider.java @@ -1,6 +1,6 @@ package org.keycloak.email; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.provider.Provider; diff --git a/forms/email-freemarker/pom.xml b/forms/email-freemarker/pom.xml index 961faec616..2bcd7f0a57 100755 --- a/forms/email-freemarker/pom.xml +++ b/forms/email-freemarker/pom.xml @@ -34,7 +34,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java index 2e965fec52..7bdd361cbd 100644 --- a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java +++ b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/FreeMarkerEmailProvider.java @@ -1,7 +1,7 @@ package org.keycloak.email.freemarker; import org.jboss.logging.Logger; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import org.keycloak.email.EmailException; import org.keycloak.email.EmailProvider; import org.keycloak.email.freemarker.beans.EventBean; @@ -56,7 +56,7 @@ public class FreeMarkerEmailProvider implements EmailProvider { Map attributes = new HashMap(); attributes.put("event", new EventBean(event)); - send("passwordResetSubject", "event-" + event.getEvent().toString().toLowerCase() + ".ftl", attributes); + send("passwordResetSubject", "event-" + event.getType().toString().toLowerCase() + ".ftl", attributes); } @Override diff --git a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/EventBean.java b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/EventBean.java index efee48d298..22f8b3e59a 100644 --- a/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/EventBean.java +++ b/forms/email-freemarker/src/main/java/org/keycloak/email/freemarker/beans/EventBean.java @@ -1,6 +1,6 @@ package org.keycloak.email.freemarker.beans; -import org.keycloak.audit.Event; +import org.keycloak.events.Event; import java.util.Date; import java.util.LinkedList; @@ -22,7 +22,7 @@ public class EventBean { } public String getEvent() { - return event.getEvent().toString().toLowerCase().replace("_", " "); + return event.getType().toString().toLowerCase().replace("_", " "); } public String getClient() { diff --git a/model/api/src/main/java/org/keycloak/models/AdminRoles.java b/model/api/src/main/java/org/keycloak/models/AdminRoles.java index 8a31eecd31..a9889516a9 100755 --- a/model/api/src/main/java/org/keycloak/models/AdminRoles.java +++ b/model/api/src/main/java/org/keycloak/models/AdminRoles.java @@ -18,14 +18,14 @@ public class AdminRoles { public static String VIEW_USERS = "view-users"; public static String VIEW_APPLICATIONS = "view-applications"; public static String VIEW_CLIENTS = "view-clients"; - public static String VIEW_AUDIT = "view-audit"; + public static String VIEW_EVENTS = "view-events"; public static String MANAGE_REALM = "manage-realm"; public static String MANAGE_USERS = "manage-users"; public static String MANAGE_APPLICATIONS = "manage-applications"; public static String MANAGE_CLIENTS = "manage-clients"; - public static String MANAGE_AUDIT = "manage-audit"; + public static String MANAGE_EVENTS = "manage-events"; - public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_AUDIT, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_AUDIT}; + public static String[] ALL_REALM_ROLES = {VIEW_REALM, VIEW_USERS, VIEW_APPLICATIONS, VIEW_CLIENTS, VIEW_EVENTS, MANAGE_REALM, MANAGE_USERS, MANAGE_APPLICATIONS, MANAGE_CLIENTS, MANAGE_EVENTS}; } diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java index b863e32fc1..d9fbb973b1 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -197,17 +197,17 @@ public interface RealmModel extends RoleContainerModel { boolean removeRoleById(String id); - boolean isAuditEnabled(); + boolean isEventsEnabled(); - void setAuditEnabled(boolean enabled); + void setEventsEnabled(boolean enabled); - long getAuditExpiration(); + long getEventsExpiration(); - void setAuditExpiration(long expiration); + void setEventsExpiration(long expiration); - Set getAuditListeners(); + Set getEventsListeners(); - void setAuditListeners(Set listeners); + void setEventsListeners(Set listeners); ApplicationModel getMasterAdminApp(); diff --git a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java index fdba16a8a3..aa06025022 100755 --- a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java +++ b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java @@ -56,9 +56,9 @@ public class RealmEntity extends AbstractIdentifiableEntity { private Map smtpConfig = new HashMap(); private Map socialConfig = new HashMap(); - private boolean auditEnabled; - private long auditExpiration; - private List auditListeners = new ArrayList(); + private boolean eventsEnabled; + private long eventsExpiration; + private List eventsListeners = new ArrayList(); private String adminAppId; @@ -342,28 +342,28 @@ public class RealmEntity extends AbstractIdentifiableEntity { this.socialConfig = socialConfig; } - public boolean isAuditEnabled() { - return auditEnabled; + public boolean isEventsEnabled() { + return eventsEnabled; } - public void setAuditEnabled(boolean auditEnabled) { - this.auditEnabled = auditEnabled; + public void setEventsEnabled(boolean eventsEnabled) { + this.eventsEnabled = eventsEnabled; } - public long getAuditExpiration() { - return auditExpiration; + public long getEventsExpiration() { + return eventsExpiration; } - public void setAuditExpiration(long auditExpiration) { - this.auditExpiration = auditExpiration; + public void setEventsExpiration(long eventsExpiration) { + this.eventsExpiration = eventsExpiration; } - public List getAuditListeners() { - return auditListeners; + public List getEventsListeners() { + return eventsListeners; } - public void setAuditListeners(List auditListeners) { - this.auditListeners = auditListeners; + public void setEventsListeners(List eventsListeners) { + this.eventsListeners = eventsListeners; } public String getAdminAppId() { diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index 8e34e1545b..069768058e 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -18,7 +18,7 @@ import org.keycloak.representations.idm.ApplicationRepresentation; import org.keycloak.representations.idm.ClaimRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.OAuthClientRepresentation; -import org.keycloak.representations.idm.RealmAuditRepresentation; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.SocialLinkRepresentation; @@ -143,16 +143,16 @@ public class ModelToRepresentation { return rep; } - public static RealmAuditRepresentation toAuditReprensetation(RealmModel realm) { - RealmAuditRepresentation rep = new RealmAuditRepresentation(); - rep.setAuditEnabled(realm.isAuditEnabled()); + public static RealmEventsConfigRepresentation toEventsConfigReprensetation(RealmModel realm) { + RealmEventsConfigRepresentation rep = new RealmEventsConfigRepresentation(); + rep.setEventsEnabled(realm.isEventsEnabled()); - if (realm.getAuditExpiration() != 0) { - rep.setAuditExpiration(realm.getAuditExpiration()); + if (realm.getEventsExpiration() != 0) { + rep.setEventsExpiration(realm.getEventsExpiration()); } - if (realm.getAuditListeners() != null) { - rep.setAuditListeners(new LinkedList(realm.getAuditListeners())); + if (realm.getEventsListeners() != null) { + rep.setEventsListeners(new LinkedList(realm.getEventsListeners())); } return rep; } diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java index fac84105e8..eeeda264e5 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java @@ -694,39 +694,39 @@ public class RealmAdapter implements RealmModel { } @Override - public boolean isAuditEnabled() { - if (updated != null) return updated.isAuditEnabled(); - return cached.isAuditEnabled(); + public boolean isEventsEnabled() { + if (updated != null) return updated.isEventsEnabled(); + return cached.isEventsEnabled(); } @Override - public void setAuditEnabled(boolean enabled) { + public void setEventsEnabled(boolean enabled) { getDelegateForUpdate(); - updated.setAuditEnabled(enabled); + updated.setEventsEnabled(enabled); } @Override - public long getAuditExpiration() { - if (updated != null) return updated.getAuditExpiration(); - return cached.getAuditExpiration(); + public long getEventsExpiration() { + if (updated != null) return updated.getEventsExpiration(); + return cached.getEventsExpiration(); } @Override - public void setAuditExpiration(long expiration) { + public void setEventsExpiration(long expiration) { getDelegateForUpdate(); - updated.setAuditExpiration(expiration); + updated.setEventsExpiration(expiration); } @Override - public Set getAuditListeners() { - if (updated != null) return updated.getAuditListeners(); - return cached.getAuditListeners(); + public Set getEventsListeners() { + if (updated != null) return updated.getEventsListeners(); + return cached.getEventsListeners(); } @Override - public void setAuditListeners(Set listeners) { + public void setEventsListeners(Set listeners) { getDelegateForUpdate(); - updated.setAuditListeners(listeners); + updated.setEventsListeners(listeners); } @Override diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java index a6256b0d5b..04ca84303a 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java @@ -70,9 +70,9 @@ public class CachedRealm { private Map smtpConfig = new HashMap(); private Map socialConfig = new HashMap(); - private boolean auditEnabled; - private long auditExpiration; - private Set auditListeners = new HashSet(); + private boolean eventsEnabled; + private long eventsExpiration; + private Set eventsListeners = new HashSet(); private List defaultRoles = new LinkedList(); private Map realmRoles = new HashMap(); private Map applications = new HashMap(); @@ -126,9 +126,9 @@ public class CachedRealm { socialConfig.putAll(model.getSocialConfig()); browserSecurityHeaders.putAll(model.getBrowserSecurityHeaders()); - auditEnabled = model.isAuditEnabled(); - auditExpiration = model.getAuditExpiration(); - auditListeners.addAll(model.getAuditListeners()); + eventsEnabled = model.isEventsEnabled(); + eventsExpiration = model.getEventsExpiration(); + eventsListeners.addAll(model.getEventsListeners()); defaultRoles.addAll(model.getDefaultRoles()); masterAdminApp = model.getMasterAdminApp().getId(); @@ -313,16 +313,16 @@ public class CachedRealm { return notBefore; } - public boolean isAuditEnabled() { - return auditEnabled; + public boolean isEventsEnabled() { + return eventsEnabled; } - public long getAuditExpiration() { - return auditExpiration; + public long getEventsExpiration() { + return eventsExpiration; } - public Set getAuditListeners() { - return auditListeners; + public Set getEventsListeners() { + return eventsListeners; } public List getUserFederationProviders() { diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index 612d3ec62e..c382ae8d63 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -11,13 +11,11 @@ import org.keycloak.models.RequiredCredentialModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.jpa.entities.ApplicationEntity; -import org.keycloak.models.jpa.entities.AttributeMap; import org.keycloak.models.jpa.entities.OAuthClientEntity; import org.keycloak.models.jpa.entities.RealmAttributeEntity; import org.keycloak.models.jpa.entities.RealmEntity; import org.keycloak.models.jpa.entities.RequiredCredentialEntity; import org.keycloak.models.jpa.entities.RoleEntity; -import org.keycloak.models.jpa.entities.UserAttributeEntity; import org.keycloak.models.jpa.entities.UserFederationProviderEntity; import org.keycloak.models.utils.KeycloakModelUtils; @@ -1047,35 +1045,35 @@ public class RealmAdapter implements RealmModel { } @Override - public boolean isAuditEnabled() { - return realm.isAuditEnabled(); + public boolean isEventsEnabled() { + return realm.isEventsEnabled(); } @Override - public void setAuditEnabled(boolean enabled) { - realm.setAuditEnabled(enabled); + public void setEventsEnabled(boolean enabled) { + realm.setEventsEnabled(enabled); em.flush(); } @Override - public long getAuditExpiration() { - return realm.getAuditExpiration(); + public long getEventsExpiration() { + return realm.getEventsExpiration(); } @Override - public void setAuditExpiration(long expiration) { - realm.setAuditExpiration(expiration); + public void setEventsExpiration(long expiration) { + realm.setEventsExpiration(expiration); em.flush(); } @Override - public Set getAuditListeners() { - return realm.getAuditListeners(); + public Set getEventsListeners() { + return realm.getEventsListeners(); } @Override - public void setAuditListeners(Set listeners) { - realm.setAuditListeners(listeners); + public void setEventsListeners(Set listeners) { + realm.setEventsListeners(listeners); em.flush(); } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java index de46f3716d..8429aac86b 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java @@ -124,15 +124,15 @@ public class RealmEntity { @JoinTable(name="REALM_DEFAULT_ROLES", joinColumns = { @JoinColumn(name="REALM_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")}) protected Collection defaultRoles = new ArrayList(); - @Column(name="AUDIT_ENABLED") - protected boolean auditEnabled; - @Column(name="AUDIT_EXPIRATION") - protected long auditExpiration; + @Column(name="EVENTS_ENABLED") + protected boolean eventsEnabled; + @Column(name="EVENTS_EXPIRATION") + protected long eventsExpiration; @ElementCollection @Column(name="VALUE") - @CollectionTable(name="REALM_AUDIT_LISTENERS", joinColumns={ @JoinColumn(name="REALM_ID") }) - protected Set auditListeners= new HashSet(); + @CollectionTable(name="REALM_EVENTS_LISTENERS", joinColumns={ @JoinColumn(name="REALM_ID") }) + protected Set eventsListeners = new HashSet(); @OneToOne @JoinColumn(name="MASTER_ADMIN_APP") @@ -385,28 +385,28 @@ public class RealmEntity { this.notBefore = notBefore; } - public boolean isAuditEnabled() { - return auditEnabled; + public boolean isEventsEnabled() { + return eventsEnabled; } - public void setAuditEnabled(boolean auditEnabled) { - this.auditEnabled = auditEnabled; + public void setEventsEnabled(boolean eventsEnabled) { + this.eventsEnabled = eventsEnabled; } - public long getAuditExpiration() { - return auditExpiration; + public long getEventsExpiration() { + return eventsExpiration; } - public void setAuditExpiration(long auditExpiration) { - this.auditExpiration = auditExpiration; + public void setEventsExpiration(long eventsExpiration) { + this.eventsExpiration = eventsExpiration; } - public Set getAuditListeners() { - return auditListeners; + public Set getEventsListeners() { + return eventsListeners; } - public void setAuditListeners(Set auditListeners) { - this.auditListeners = auditListeners; + public void setEventsListeners(Set eventsListeners) { + this.eventsListeners = eventsListeners; } public ApplicationEntity getMasterAdminApp() { diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index 0c6eda25a2..8455798201 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -873,38 +873,38 @@ public class RealmAdapter extends AbstractMongoAdapter impleme } @Override - public boolean isAuditEnabled() { - return realm.isAuditEnabled(); + public boolean isEventsEnabled() { + return realm.isEventsEnabled(); } @Override - public void setAuditEnabled(boolean enabled) { - realm.setAuditEnabled(enabled); + public void setEventsEnabled(boolean enabled) { + realm.setEventsEnabled(enabled); updateRealm(); } @Override - public long getAuditExpiration() { - return realm.getAuditExpiration(); + public long getEventsExpiration() { + return realm.getEventsExpiration(); } @Override - public void setAuditExpiration(long expiration) { - realm.setAuditExpiration(expiration); + public void setEventsExpiration(long expiration) { + realm.setEventsExpiration(expiration); updateRealm(); } @Override - public Set getAuditListeners() { - return new HashSet(realm.getAuditListeners()); + public Set getEventsListeners() { + return new HashSet(realm.getEventsListeners()); } @Override - public void setAuditListeners(Set listeners) { + public void setEventsListeners(Set listeners) { if (listeners != null) { - realm.setAuditListeners(new ArrayList(listeners)); + realm.setEventsListeners(new ArrayList(listeners)); } else { - realm.setAuditListeners(Collections.EMPTY_LIST); + realm.setEventsListeners(Collections.EMPTY_LIST); } updateRealm(); } diff --git a/pom.xml b/pom.xml index b78caca039..609a3c8884 100755 --- a/pom.xml +++ b/pom.xml @@ -96,11 +96,11 @@ - audit core core-jaxrs connections dependencies + events model integration picketlink diff --git a/server/src/main/resources/META-INF/keycloak-server.json b/server/src/main/resources/META-INF/keycloak-server.json index 49fc8c5fac..d58d1b2807 100755 --- a/server/src/main/resources/META-INF/keycloak-server.json +++ b/server/src/main/resources/META-INF/keycloak-server.json @@ -3,7 +3,7 @@ "realm": "master" }, - "audit": { + "eventsStore": { "provider": "jpa", "jpa": { "exclude-events": [ "REFRESH_TOKEN" ] diff --git a/services/pom.xml b/services/pom.xml index 4157583fcd..1818194318 100755 --- a/services/pom.xml +++ b/services/pom.xml @@ -39,7 +39,7 @@ org.keycloak - keycloak-audit-api + keycloak-events-api ${project.version} provided diff --git a/services/src/main/java/org/keycloak/services/managers/AuditManager.java b/services/src/main/java/org/keycloak/services/managers/AuditManager.java deleted file mode 100755 index 5aa416775f..0000000000 --- a/services/src/main/java/org/keycloak/services/managers/AuditManager.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.keycloak.services.managers; - -import org.jboss.logging.Logger; -import org.keycloak.ClientConnection; -import org.keycloak.audit.Audit; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.AuditProvider; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; - -import java.util.LinkedList; -import java.util.List; - -/** - * @author Stian Thorgersen - */ -public class AuditManager { - - private Logger log = Logger.getLogger(AuditManager.class); - - private RealmModel realm; - private KeycloakSession session; - private ClientConnection clientConnection; - - public AuditManager(RealmModel realm, KeycloakSession session, ClientConnection clientConnection) { - this.realm = realm; - this.session = session; - this.clientConnection = clientConnection; - } - - public Audit createAudit() { - List listeners = new LinkedList(); - - if (realm.isAuditEnabled()) { - AuditProvider auditProvider = session.getProvider(AuditProvider.class); - if (auditProvider != null) { - listeners.add(auditProvider); - } else { - log.error("Audit enabled, but no audit provider configured"); - } - } - - if (realm.getAuditListeners() != null) { - for (String id : realm.getAuditListeners()) { - AuditListener listener = session.getProvider(AuditListener.class, id); - if (listener != null) { - listeners.add(listener); - } else { - log.error("Audit listener '" + id + "' registered, but not found"); - } - } - } - - return new Audit(listeners, realm, clientConnection.getRemoteAddr()); - } - -} diff --git a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java index 1d1a2838e2..aa202e7db3 100755 --- a/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java +++ b/services/src/main/java/org/keycloak/services/managers/BruteForceProtector.java @@ -185,7 +185,7 @@ public class BruteForceProtector implements Runnable { session.close(); } } catch (Exception e) { - logger.error("Failed processing event", e); + logger.error("Failed processing type", e); } } catch (InterruptedException e) { break; @@ -228,7 +228,7 @@ public class BruteForceProtector implements Runnable { try { FailedLogin event = new FailedLogin(realm.getId(), username, clientConnection.getRemoteAddr()); queue.offer(event); - // wait a minimum of seconds for event to process so that a hacker + // wait a minimum of seconds for type to process so that a hacker // cannot flood with failed logins and overwhelm the queue and not have notBefore updated to block next requests // todo failure HTTP responses should be queued via async HTTP event.latch.await(5, TimeUnit.SECONDS); diff --git a/services/src/main/java/org/keycloak/services/managers/EventsManager.java b/services/src/main/java/org/keycloak/services/managers/EventsManager.java new file mode 100755 index 0000000000..6288546c7a --- /dev/null +++ b/services/src/main/java/org/keycloak/services/managers/EventsManager.java @@ -0,0 +1,57 @@ +package org.keycloak.services.managers; + +import org.jboss.logging.Logger; +import org.keycloak.ClientConnection; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; + +import java.util.LinkedList; +import java.util.List; + +/** + * @author Stian Thorgersen + */ +public class EventsManager { + + private Logger log = Logger.getLogger(EventsManager.class); + + private RealmModel realm; + private KeycloakSession session; + private ClientConnection clientConnection; + + public EventsManager(RealmModel realm, KeycloakSession session, ClientConnection clientConnection) { + this.realm = realm; + this.session = session; + this.clientConnection = clientConnection; + } + + public EventBuilder createEventBuilder() { + List listeners = new LinkedList(); + + if (realm.isEventsEnabled()) { + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + if (eventStore != null) { + listeners.add(eventStore); + } else { + log.error("Events enabled, but no event store provider configured"); + } + } + + if (realm.getEventsListeners() != null) { + for (String id : realm.getEventsListeners()) { + EventListenerProvider listener = session.getProvider(EventListenerProvider.class, id); + if (listener != null) { + listeners.add(listener); + } else { + log.error("Event listener '" + id + "' registered, but provider not found"); + } + } + } + + return new EventBuilder(listeners, realm, clientConnection.getRemoteAddr()); + } + +} diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index 2269c97b76..240d5cb498 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -19,7 +19,7 @@ import org.keycloak.models.UserSessionProvider; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.idm.ApplicationRepresentation; -import org.keycloak.representations.idm.RealmAuditRepresentation; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.timer.TimerProvider; @@ -155,11 +155,11 @@ public class RealmManager { return removed; } - public void updateRealmAudit(RealmAuditRepresentation rep, RealmModel realm) { - realm.setAuditEnabled(rep.isAuditEnabled()); - realm.setAuditExpiration(rep.getAuditExpiration() != null ? rep.getAuditExpiration() : 0); - if (rep.getAuditListeners() != null) { - realm.setAuditListeners(new HashSet(rep.getAuditListeners())); + public void updateRealmEventsConfig(RealmEventsConfigRepresentation rep, RealmModel realm) { + realm.setEventsEnabled(rep.isEventsEnabled()); + realm.setEventsExpiration(rep.getEventsExpiration() != null ? rep.getEventsExpiration() : 0); + if (rep.getEventsListeners() != null) { + realm.setEventsListeners(new HashSet(rep.getEventsListeners())); } } diff --git a/services/src/main/java/org/keycloak/services/managers/TokenManager.java b/services/src/main/java/org/keycloak/services/managers/TokenManager.java index 0fc5834c7f..f88a6cad8f 100755 --- a/services/src/main/java/org/keycloak/services/managers/TokenManager.java +++ b/services/src/main/java/org/keycloak/services/managers/TokenManager.java @@ -3,8 +3,8 @@ package org.keycloak.services.managers; import org.jboss.logging.Logger; import org.keycloak.ClientConnection; import org.keycloak.OAuthErrorException; -import org.keycloak.audit.Audit; -import org.keycloak.audit.Details; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.Details; import org.keycloak.jose.jws.JWSBuilder; import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.crypto.RSAProvider; @@ -63,10 +63,10 @@ public class TokenManager { return new AccessCode(realm, clientSession); } - public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, Audit audit) throws OAuthErrorException { + public AccessToken refreshAccessToken(KeycloakSession session, UriInfo uriInfo, ClientConnection connection, RealmModel realm, ClientModel client, String encodedRefreshToken, EventBuilder event) throws OAuthErrorException { RefreshToken refreshToken = verifyRefreshToken(realm, encodedRefreshToken); - audit.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()); + event.user(refreshToken.getSubject()).session(refreshToken.getSessionState()).detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()); UserModel user = session.users().getUserById(refreshToken.getSubject(), realm); if (user == null) { @@ -290,8 +290,8 @@ public class TokenManager { return encodedToken; } - public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, Audit audit) { - return new AccessTokenResponseBuilder(realm, client, audit); + public AccessTokenResponseBuilder responseBuilder(RealmModel realm, ClientModel client, EventBuilder event) { + return new AccessTokenResponseBuilder(realm, client, event); } public class AccessTokenResponseBuilder { @@ -300,12 +300,12 @@ public class TokenManager { AccessToken accessToken; RefreshToken refreshToken; IDToken idToken; - Audit audit; + EventBuilder event; - public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, Audit audit) { + public AccessTokenResponseBuilder(RealmModel realm, ClientModel client, EventBuilder event) { this.realm = realm; this.client = client; - this.audit = audit; + this.event = event; } public AccessTokenResponseBuilder accessToken(AccessToken accessToken) { @@ -379,14 +379,14 @@ public class TokenManager { public AccessTokenResponse build() { if (accessToken != null) { - audit.detail(Details.TOKEN_ID, accessToken.getId()); + event.detail(Details.TOKEN_ID, accessToken.getId()); } if (refreshToken != null) { - if (audit.getEvent().getDetails().containsKey(Details.REFRESH_TOKEN_ID)) { - audit.detail(Details.UPDATED_REFRESH_TOKEN_ID, refreshToken.getId()); + if (event.getEvent().getDetails().containsKey(Details.REFRESH_TOKEN_ID)) { + event.detail(Details.UPDATED_REFRESH_TOKEN_ID, refreshToken.getId()); } else { - audit.detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()); + event.detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()); } } 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 419e641c44..0900be8cb2 100755 --- a/services/src/main/java/org/keycloak/services/resources/AccountService.java +++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java @@ -28,11 +28,11 @@ import org.keycloak.ClientConnection; import org.keycloak.OAuth2Constants; import org.keycloak.account.AccountPages; import org.keycloak.account.AccountProvider; -import org.keycloak.audit.Audit; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.AccountRoles; import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; @@ -92,18 +92,18 @@ public class AccountService { private static final Logger logger = Logger.getLogger(AccountService.class); - private static final EventType[] AUDIT_EVENTS = {EventType.LOGIN, EventType.LOGOUT, EventType.REGISTER, EventType.REMOVE_SOCIAL_LINK, EventType.REMOVE_TOTP, EventType.SEND_RESET_PASSWORD, + private static final EventType[] LOG_EVENTS = {EventType.LOGIN, EventType.LOGOUT, EventType.REGISTER, EventType.REMOVE_SOCIAL_LINK, EventType.REMOVE_TOTP, EventType.SEND_RESET_PASSWORD, EventType.SEND_VERIFY_EMAIL, EventType.SOCIAL_LINK, EventType.UPDATE_EMAIL, EventType.UPDATE_PASSWORD, EventType.UPDATE_PROFILE, EventType.UPDATE_TOTP, EventType.VERIFY_EMAIL}; - private static final Set AUDIT_DETAILS = new HashSet(); + private static final Set LOG_DETAILS = new HashSet(); static { - AUDIT_DETAILS.add(Details.UPDATED_EMAIL); - AUDIT_DETAILS.add(Details.EMAIL); - AUDIT_DETAILS.add(Details.PREVIOUS_EMAIL); - AUDIT_DETAILS.add(Details.USERNAME); - AUDIT_DETAILS.add(Details.REMEMBER_ME); - AUDIT_DETAILS.add(Details.REGISTER_METHOD); - AUDIT_DETAILS.add(Details.AUTH_METHOD); + LOG_DETAILS.add(Details.UPDATED_EMAIL); + LOG_DETAILS.add(Details.EMAIL); + LOG_DETAILS.add(Details.PREVIOUS_EMAIL); + LOG_DETAILS.add(Details.USERNAME); + LOG_DETAILS.add(Details.REMEMBER_ME); + LOG_DETAILS.add(Details.REGISTER_METHOD); + LOG_DETAILS.add(Details.AUTH_METHOD); } private RealmModel realm; @@ -125,20 +125,20 @@ public class AccountService { private final AppAuthManager authManager; private final ApplicationModel application; - private Audit audit; + private EventBuilder event; private AccountProvider account; private Auth auth; - private AuditProvider auditProvider; + private EventStoreProvider eventStore; - public AccountService(RealmModel realm, ApplicationModel application, Audit audit) { + public AccountService(RealmModel realm, ApplicationModel application, EventBuilder event) { this.realm = realm; this.application = application; - this.audit = audit; + this.event = event; this.authManager = new AppAuthManager(); } public void init() { - auditProvider = session.getProvider(AuditProvider.class); + eventStore = session.getProvider(EventStoreProvider.class); account = session.getProvider(AccountProvider.class).setRealm(realm).setUriInfo(uriInfo); @@ -170,10 +170,10 @@ public class AccountService { } - boolean auditEnabled = auditProvider != null && realm.isAuditEnabled(); + boolean eventsEnabled = eventStore != null && realm.isEventsEnabled(); // todo find out from federation if password is updatable - account.setFeatures(realm.isSocial(), auditEnabled, true); + account.setFeatures(realm.isSocial(), eventsEnabled, true); } public static UriBuilder accountServiceBaseUrl(UriInfo uriInfo) { @@ -282,12 +282,12 @@ public class AccountService { @GET public Response logPage() { if (auth != null) { - List events = auditProvider.createQuery().event(AUDIT_EVENTS).user(auth.getUser().getId()).maxResults(30).getResultList(); + List events = eventStore.createQuery().type(LOG_EVENTS).user(auth.getUser().getId()).maxResults(30).getResultList(); for (Event e : events) { if (e.getDetails() != null) { Iterator> itr = e.getDetails().entrySet().iterator(); while (itr.hasNext()) { - if (!AUDIT_DETAILS.contains(itr.next().getKey())) { + if (!LOG_DETAILS.contains(itr.next().getKey())) { itr.remove(); } } @@ -353,11 +353,11 @@ public class AccountService { user.setEmail(formData.getFirst("email")); - audit.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()).success(); + event.event(EventType.UPDATE_PROFILE).client(auth.getClient()).user(auth.getUser()).success(); if (emailChanged) { user.setEmailVerified(false); - audit.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail).detail(Details.UPDATED_EMAIL, email).success(); + event.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail).detail(Details.UPDATED_EMAIL, email).success(); } setReferrerOnPage(); return account.setSuccess("accountUpdated").createResponse(AccountPages.ACCOUNT); @@ -379,7 +379,7 @@ public class AccountService { UserModel user = auth.getUser(); user.setTotp(false); - audit.event(EventType.REMOVE_TOTP).client(auth.getClient()).user(auth.getUser()).success(); + event.event(EventType.REMOVE_TOTP).client(auth.getClient()).user(auth.getUser()).success(); setReferrerOnPage(); return account.setSuccess("successTotpRemoved").createResponse(AccountPages.TOTP); @@ -455,7 +455,7 @@ public class AccountService { user.setTotp(true); - audit.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success(); + event.event(EventType.UPDATE_TOTP).client(auth.getClient()).user(auth.getUser()).success(); setReferrerOnPage(); return account.setSuccess("successTotp").createResponse(AccountPages.TOTP); @@ -525,7 +525,7 @@ public class AccountService { return account.setError(ape.getMessage()).createResponse(AccountPages.PASSWORD); } - audit.event(EventType.UPDATE_PASSWORD).client(auth.getClient()).user(auth.getUser()).success(); + event.event(EventType.UPDATE_PASSWORD).client(auth.getClient()).user(auth.getUser()).success(); setReferrerOnPage(); return account.setSuccess("accountPasswordUpdated").createResponse(AccountPages.PASSWORD); @@ -588,7 +588,7 @@ public class AccountService { logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername()); - audit.event(EventType.REMOVE_SOCIAL_LINK).client(auth.getClient()).user(auth.getUser()) + event.event(EventType.REMOVE_SOCIAL_LINK).client(auth.getClient()).user(auth.getUser()) .detail(Details.USERNAME, link.getSocialUserId() + "@" + link.getSocialProvider()) .success(); 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 8e925572b1..038a5658cb 100755 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -19,7 +19,7 @@ import org.keycloak.services.managers.UsersSyncManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.TokenManager; import org.keycloak.services.resources.admin.AdminRoot; -import org.keycloak.services.scheduled.ClearExpiredAuditEvents; +import org.keycloak.services.scheduled.ClearExpiredEvents; import org.keycloak.services.scheduled.ClearExpiredUserSessions; import org.keycloak.services.scheduled.ScheduledTaskRunner; import org.keycloak.services.util.JsonConfigProvider; @@ -147,7 +147,7 @@ public class KeycloakApplication extends Application { long interval = Config.scope("scheduled").getLong("interval", 60L) * 1000; TimerProvider timer = sessionFactory.create().getProvider(TimerProvider.class); - timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredAuditEvents()), interval, "ClearExpiredAuditEvents"); + timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredEvents()), interval, "ClearExpiredEvents"); timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredUserSessions()), interval, "ClearExpiredUserSessions"); new UsersSyncManager().bootstrapPeriodic(sessionFactory, timer); } 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 3969224f5b..04491d02a2 100755 --- a/services/src/main/java/org/keycloak/services/resources/RealmsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/RealmsResource.java @@ -6,13 +6,13 @@ import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.ClientConnection; -import org.keycloak.audit.Audit; +import org.keycloak.events.EventBuilder; import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.services.managers.AuditManager; +import org.keycloak.services.managers.EventsManager; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.BruteForceProtector; import org.keycloak.services.managers.RealmManager; @@ -140,9 +140,9 @@ public class RealmsResource { public TokenService getTokenService(final @PathParam("realm") String name) { RealmManager realmManager = new RealmManager(session); RealmModel realm = locateRealm(name, realmManager); - Audit audit = new AuditManager(realm, session, clientConnection).createAudit(); + EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder(); AuthenticationManager authManager = new AuthenticationManager(protector); - TokenService tokenService = new TokenService(realm, tokenManager, audit, authManager); + TokenService tokenService = new TokenService(realm, tokenManager, event, authManager); ResteasyProviderFactory.getInstance().injectProperties(tokenService); //resourceContext.initResource(tokenService); return tokenService; @@ -167,8 +167,8 @@ public class RealmsResource { throw new NotFoundException("account management not enabled"); } - Audit audit = new AuditManager(realm, session, clientConnection).createAudit(); - AccountService accountService = new AccountService(realm, application, audit); + EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder(); + AccountService accountService = new AccountService(realm, application, event); ResteasyProviderFactory.getInstance().injectProperties(accountService); //resourceContext.initResource(accountService); accountService.init(); diff --git a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java index a468f755a0..fcd3c5de6c 100755 --- a/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java +++ b/services/src/main/java/org/keycloak/services/resources/RequiredActionsService.java @@ -25,10 +25,10 @@ import org.jboss.logging.Logger; import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.ClientConnection; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Audit; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.email.EmailException; import org.keycloak.email.EmailProvider; import org.keycloak.login.LoginFormsProvider; @@ -94,12 +94,12 @@ public class RequiredActionsService { private TokenManager tokenManager; - private Audit audit; + private EventBuilder event; - public RequiredActionsService(RealmModel realm, TokenManager tokenManager, Audit audit) { + public RequiredActionsService(RealmModel realm, TokenManager tokenManager, EventBuilder event) { this.realm = realm; this.tokenManager = tokenManager; - this.audit = audit; + this.event = event; } @Path("profile") @@ -113,7 +113,7 @@ public class RequiredActionsService { UserModel user = getUser(accessCode); - initAudit(accessCode); + initEvent(accessCode); String error = Validation.validateUpdateProfileForm(formData); if (error != null) { @@ -131,10 +131,10 @@ public class RequiredActionsService { user.removeRequiredAction(RequiredAction.UPDATE_PROFILE); - audit.clone().event(EventType.UPDATE_PROFILE).success(); + event.clone().event(EventType.UPDATE_PROFILE).success(); if (emailChanged) { user.setEmailVerified(false); - audit.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail).detail(Details.UPDATED_EMAIL, email).success(); + event.clone().event(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, oldEmail).detail(Details.UPDATED_EMAIL, email).success(); } return redirectOauth(user, accessCode); @@ -151,7 +151,7 @@ public class RequiredActionsService { UserModel user = getUser(accessCode); - initAudit(accessCode); + initEvent(accessCode); String totp = formData.getFirst("totp"); String totpSecret = formData.getFirst("totpSecret"); @@ -172,7 +172,7 @@ public class RequiredActionsService { user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP); - audit.clone().event(EventType.UPDATE_TOTP).success(); + event.clone().event(EventType.UPDATE_TOTP).success(); return redirectOauth(user, accessCode); } @@ -188,7 +188,7 @@ public class RequiredActionsService { UserModel user = getUser(accessCode); - initAudit(accessCode); + initEvent(accessCode); String passwordNew = formData.getFirst("password-new"); String passwordConfirm = formData.getFirst("password-confirm"); @@ -208,7 +208,7 @@ public class RequiredActionsService { user.removeRequiredAction(RequiredAction.UPDATE_PASSWORD); - audit.clone().event(EventType.UPDATE_PASSWORD).success(); + event.clone().event(EventType.UPDATE_PASSWORD).success(); // Redirect to account management to login if password reset was initiated by admin if (accessCode.getSessionState() == null) { @@ -230,13 +230,13 @@ public class RequiredActionsService { UserModel user = getUser(accessCode); - initAudit(accessCode); + initEvent(accessCode); user.setEmailVerified(true); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL); - audit.clone().event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); + event.clone().event(EventType.VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); return redirectOauth(user, accessCode); } else { @@ -245,7 +245,7 @@ public class RequiredActionsService { return unauthorized(); } - initAudit(accessCode); + initEvent(accessCode); return Flows.forms(session, realm, null, uriInfo).setAccessCode(accessCode.getCode()).setUser(accessCode.getUser()) .createResponse(RequiredAction.VERIFY_EMAIL); @@ -290,7 +290,7 @@ public class RequiredActionsService { "Login requester not enabled."); } - audit.event(EventType.SEND_RESET_PASSWORD).client(clientId) + event.event(EventType.SEND_RESET_PASSWORD).client(clientId) .detail(Details.REDIRECT_URI, redirect) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.AUTH_METHOD, "form") @@ -302,10 +302,10 @@ public class RequiredActionsService { } if (user == null) { - audit.error(Errors.USER_NOT_FOUND); + event.error(Errors.USER_NOT_FOUND); } else { UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", false); - audit.session(userSession); + event.session(userSession); AccessCode accessCode = tokenManager.createAccessCode(scopeParam, state, redirect, session, realm, client, user, userSession); accessCode.setRequiredAction(RequiredAction.UPDATE_PASSWORD); @@ -319,7 +319,7 @@ public class RequiredActionsService { this.session.getProvider(EmailProvider.class).setRealm(realm).setUser(user).sendPasswordReset(link, expiration); - audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success(); + event.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success(); } catch (EmailException e) { logger.error("Failed to send password reset email", e); return Flows.forms(this.session, realm, client, uriInfo).setError("emailSendError").createErrorPage(); @@ -375,17 +375,17 @@ public class RequiredActionsService { AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection); return Flows.oauth(this.session, realm, request, uriInfo, clientConnection, authManager, tokenManager).redirectError(accessCode.getClient(), "access_denied", accessCode.getState(), accessCode.getRedirectUri()); } - audit.session(userSession); + event.session(userSession); - audit.success(); + event.success(); return Flows.oauth(this.session, realm, request, uriInfo, clientConnection, authManager, tokenManager).redirectAccessCode(accessCode, userSession, accessCode.getState(), accessCode.getRedirectUri()); } } - private void initAudit(AccessCode accessCode) { - audit.event(EventType.LOGIN).client(accessCode.getClient()) + private void initEvent(AccessCode accessCode) { + event.event(EventType.LOGIN).client(accessCode.getClient()) .user(accessCode.getUser()) .session(accessCode.getSessionState()) .detail(Details.CODE_ID, accessCode.getCodeId()) @@ -395,10 +395,10 @@ public class RequiredActionsService { UserSessionModel userSession = accessCode.getSessionState() != null ? session.sessions().getUserSession(realm, accessCode.getSessionState()) : null; if (userSession != null) { - audit.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); - audit.detail(Details.USERNAME, userSession.getLoginUsername()); + event.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); + event.detail(Details.USERNAME, userSession.getLoginUsername()); if (userSession.isRememberMe()) { - audit.detail(Details.REMEMBER_ME, "true"); + event.detail(Details.REMEMBER_ME, "true"); } } } 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 a61c60a266..572b74d92e 100755 --- a/services/src/main/java/org/keycloak/services/resources/SocialResource.java +++ b/services/src/main/java/org/keycloak/services/resources/SocialResource.java @@ -26,12 +26,11 @@ import org.jboss.resteasy.specimpl.MultivaluedMapImpl; import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.ClientConnection; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Audit; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jws.JWSInput; -import org.keycloak.login.LoginFormsProvider; import org.keycloak.models.AccountRoles; import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; @@ -42,13 +41,12 @@ import org.keycloak.models.SocialLinkModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.services.managers.AuditManager; +import org.keycloak.services.managers.EventsManager; import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.TokenManager; import org.keycloak.services.resources.flows.Flows; import org.keycloak.services.resources.flows.OAuthFlows; -import org.keycloak.services.resources.flows.OAuthRedirect; import org.keycloak.services.resources.flows.Urls; import org.keycloak.social.AuthCallback; import org.keycloak.social.SocialAccessDeniedException; @@ -124,7 +122,7 @@ public class SocialResource { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(realmName); - Audit audit = new AuditManager(realm, session, clientConnection).createAudit() + EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder() .event(EventType.LOGIN) .detail(Details.RESPONSE_TYPE, initialRequest.get(OAuth2Constants.RESPONSE_TYPE)) .detail(Details.AUTH_METHOD, authMethod); @@ -133,7 +131,7 @@ public class SocialResource { OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return oauth.forwardToSecurityFailure("Realm not enabled."); } @@ -143,15 +141,15 @@ public class SocialResource { String state = initialRequest.get(OAuth2Constants.STATE); String responseType = initialRequest.get(OAuth2Constants.RESPONSE_TYPE); - audit.client(clientId).detail(Details.REDIRECT_URI, redirectUri); + event.client(clientId).detail(Details.REDIRECT_URI, redirectUri); ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Unknown login requester."); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); return oauth.forwardToSecurityFailure("Login requester not enabled."); } @@ -176,14 +174,14 @@ public class SocialResource { queryParms.putSingle(OAuth2Constants.REDIRECT_URI, redirectUri); queryParms.putSingle(OAuth2Constants.RESPONSE_TYPE, responseType); - audit.error(Errors.REJECTED_BY_USER); + event.error(Errors.REJECTED_BY_USER); return Flows.forms(session, realm, client, uriInfo).setQueryParams(queryParms).setWarning("Access denied").createLogin(); } catch (SocialProviderException e) { logger.error("Failed to process social callback", e); return oauth.forwardToSecurityFailure("Failed to process social callback"); } - audit.detail(Details.USERNAME, socialUser.getId() + "@" + provider.getId()); + event.detail(Details.USERNAME, socialUser.getId() + "@" + provider.getId()); try { SocialLinkModel socialLink = new SocialLinkModel(provider.getId(), socialUser.getId(), socialUser.getUsername()); @@ -194,32 +192,32 @@ public class SocialResource { if (userId != null) { UserModel authenticatedUser = session.users().getUserById(userId, realm); - audit.event(EventType.SOCIAL_LINK).user(userId); + event.event(EventType.SOCIAL_LINK).user(userId); if (user != null) { - audit.error(Errors.SOCIAL_ID_IN_USE); + event.error(Errors.SOCIAL_ID_IN_USE); return oauth.forwardToSecurityFailure("This social account is already linked to other user"); } if (!authenticatedUser.isEnabled()) { - audit.error(Errors.USER_DISABLED); + event.error(Errors.USER_DISABLED); return oauth.forwardToSecurityFailure("User is disabled"); } if (!authenticatedUser.hasRole(realm.getApplicationByName(Constants.ACCOUNT_MANAGEMENT_APP).getRole(AccountRoles.MANAGE_ACCOUNT))) { - audit.error(Errors.NOT_ALLOWED); + event.error(Errors.NOT_ALLOWED); return oauth.forwardToSecurityFailure("Insufficient permissions to link social account"); } if (redirectUri == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return oauth.forwardToSecurityFailure("Unknown redirectUri"); } session.users().addSocialLink(realm, authenticatedUser, socialLink); logger.debugv("Social provider {0} linked with user {1}", provider.getId(), authenticatedUser.getUsername()); - audit.success(); + event.success(); return Response.status(302).location(UriBuilder.fromUri(redirectUri).build()).build(); } @@ -236,26 +234,26 @@ public class SocialResource { session.users().addSocialLink(realm, user, socialLink); - audit.clone().user(user).event(EventType.REGISTER) + event.clone().user(user).event(EventType.REGISTER) .detail(Details.REGISTER_METHOD, "social@" + provider.getId()) .detail(Details.EMAIL, socialUser.getEmail()) .removeDetail("auth_method") .success(); } - audit.user(user); + event.user(user); if (!user.isEnabled()) { - audit.error(Errors.USER_DISABLED); + event.error(Errors.USER_DISABLED); return oauth.forwardToSecurityFailure("Your account is not enabled."); } String username = socialLink.getSocialUserId() + "@" + socialLink.getSocialProvider(); UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), authMethod, false); - audit.session(userSession); + event.session(userSession); - Response response = oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, audit); + Response response = oauth.processAccessCode(scope, state, redirectUri, client, user, userSession, event); if (session.getTransaction().isActive()) { session.getTransaction().commit(); } @@ -275,7 +273,7 @@ public class SocialResource { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName(realmName); - Audit audit = new AuditManager(realm, session, clientConnection).createAudit() + EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder() .event(EventType.LOGIN).client(clientId) .detail(Details.REDIRECT_URI, redirectUri) .detail(Details.RESPONSE_TYPE, "code") @@ -283,23 +281,23 @@ public class SocialResource { SocialProvider provider = SocialLoader.load(providerId); if (provider == null) { - audit.error(Errors.SOCIAL_PROVIDER_NOT_FOUND); + event.error(Errors.SOCIAL_PROVIDER_NOT_FOUND); return Flows.forms(session, realm, null, uriInfo).setError("Social provider not found").createErrorPage(); } ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return Flows.forms(session, realm, null, uriInfo).setError("Unknown login requester.").createErrorPage(); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); return Flows.forms(session, realm, null, uriInfo).setError("Login requester not enabled.").createErrorPage(); } redirectUri = TokenService.verifyRedirectUri(uriInfo, redirectUri, realm, client); if (redirectUri == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return Flows.forms(session, realm, null, uriInfo).setError("Invalid redirect_uri.").createErrorPage(); } diff --git a/services/src/main/java/org/keycloak/services/resources/TokenService.java b/services/src/main/java/org/keycloak/services/resources/TokenService.java index 0907b16495..61e47b44c8 100755 --- a/services/src/main/java/org/keycloak/services/resources/TokenService.java +++ b/services/src/main/java/org/keycloak/services/resources/TokenService.java @@ -13,10 +13,10 @@ import org.keycloak.ClientConnection; import org.keycloak.OAuth2Constants; import org.keycloak.OAuthErrorException; import org.keycloak.RSATokenVerifier; -import org.keycloak.audit.Audit; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.login.LoginFormsProvider; import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; @@ -85,7 +85,7 @@ public class TokenService { protected RealmModel realm; protected TokenManager tokenManager; - private Audit audit; + private EventBuilder event; protected AuthenticationManager authManager; @Context @@ -112,10 +112,10 @@ public class TokenService { private ResourceAdminManager resourceAdminManager = new ResourceAdminManager(); - public TokenService(RealmModel realm, TokenManager tokenManager, Audit audit, AuthenticationManager authManager) { + public TokenService(RealmModel realm, TokenManager tokenManager, EventBuilder event, AuthenticationManager authManager) { this.realm = realm; this.tokenManager = tokenManager; - this.audit = audit; + this.event = event; this.authManager = authManager; } @@ -232,22 +232,22 @@ public class TokenService { return createError("not_enabled", "Direct Grant REST API not enabled", Response.Status.FORBIDDEN); } - audit.event(EventType.LOGIN).detail(Details.AUTH_METHOD, "oauth_credentials").detail(Details.RESPONSE_TYPE, "token"); + event.event(EventType.LOGIN).detail(Details.AUTH_METHOD, "oauth_credentials").detail(Details.RESPONSE_TYPE, "token"); String username = form.getFirst(AuthenticationManager.FORM_USERNAME); if (username == null) { - audit.error(Errors.USERNAME_MISSING); + event.error(Errors.USERNAME_MISSING); throw new UnauthorizedException("No username"); } - audit.detail(Details.USERNAME, username); + event.detail(Details.USERNAME, username); UserModel user = session.users().getUserByUsername(username, realm); - if (user != null) audit.user(user); + if (user != null) event.user(user); - ClientModel client = authorizeClient(authorizationHeader, form, audit); + ClientModel client = authorizeClient(authorizationHeader, form, event); if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return createError("realm_disabled", "Realm is disabled", Response.Status.UNAUTHORIZED); } @@ -262,21 +262,21 @@ public class TokenService { err = new HashMap(); err.put(OAuth2Constants.ERROR, "invalid_grant"); err.put(OAuth2Constants.ERROR_DESCRIPTION, "AccountProvider temporarily disabled"); - audit.error(Errors.USER_TEMPORARILY_DISABLED); + event.error(Errors.USER_TEMPORARILY_DISABLED); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); case ACCOUNT_DISABLED: err = new HashMap(); err.put(OAuth2Constants.ERROR, "invalid_grant"); err.put(OAuth2Constants.ERROR_DESCRIPTION, "AccountProvider disabled"); - audit.error(Errors.USER_DISABLED); + event.error(Errors.USER_DISABLED); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); default: err = new HashMap(); err.put(OAuth2Constants.ERROR, "invalid_grant"); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Invalid user credentials"); - audit.error(Errors.INVALID_USER_CREDENTIALS); + event.error(Errors.INVALID_USER_CREDENTIALS); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -284,15 +284,15 @@ public class TokenService { String scope = form.getFirst(OAuth2Constants.SCOPE); UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "oauth_credentials", false); - audit.session(userSession); + event.session(userSession); - AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit) + AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event) .generateAccessToken(scope, client, user, userSession) .generateRefreshToken() .generateIDToken() .build(); - audit.success(); + event.success(); return Response.ok(res, MediaType.APPLICATION_JSON_TYPE).build(); } @@ -311,7 +311,7 @@ public class TokenService { if (!checkSsl()) { return createError("https_required", "HTTPS required", Response.Status.FORBIDDEN); } - audit.event(EventType.VALIDATE_ACCESS_TOKEN); + event.event(EventType.VALIDATE_ACCESS_TOKEN); AccessToken token = null; try { token = RSATokenVerifier.verifyToken(tokenString, realm.getPublicKey(), realm.getName()); @@ -319,11 +319,11 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Token invalid"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } - audit.user(token.getSubject()).session(token.getSessionState()).detail(Details.VALIDATE_ACCESS_TOKEN, token.getId()); + event.user(token.getSubject()).session(token.getSessionState()).detail(Details.VALIDATE_ACCESS_TOKEN, token.getId()); if (token.isExpired() || token.getIssuedAt() < realm.getNotBefore() @@ -331,7 +331,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Token expired"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -342,7 +342,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "User does not exist"); - audit.error(Errors.USER_NOT_FOUND); + event.error(Errors.USER_NOT_FOUND); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -351,7 +351,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "User disabled"); - audit.error(Errors.USER_DISABLED); + event.error(Errors.USER_DISABLED); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -361,7 +361,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_GRANT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Expired session"); - audit.error(Errors.USER_SESSION_NOT_FOUND); + event.error(Errors.USER_SESSION_NOT_FOUND); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -371,7 +371,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_CLIENT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Issued for client no longer exists"); - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); @@ -381,7 +381,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_CLIENT); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Issued for client no longer exists"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); } @@ -392,7 +392,7 @@ public class TokenService { Map err = new HashMap(); err.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_SCOPE); err.put(OAuth2Constants.ERROR_DESCRIPTION, "Role mappings have changed"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(err) .build(); @@ -424,34 +424,34 @@ public class TokenService { return createError("https_required", "HTTPS required", Response.Status.FORBIDDEN); } - audit.event(EventType.REFRESH_TOKEN); + event.event(EventType.REFRESH_TOKEN); - ClientModel client = authorizeClient(authorizationHeader, form, audit); + ClientModel client = authorizeClient(authorizationHeader, form, event); String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN); if (refreshToken == null) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_REQUEST); error.put(OAuth2Constants.ERROR_DESCRIPTION, "No refresh token"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); } AccessToken accessToken; try { - accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, audit); + accessToken = tokenManager.refreshAccessToken(session, uriInfo, clientConnection, realm, client, refreshToken, event); } catch (OAuthErrorException e) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, e.getError()); if (e.getDescription() != null) error.put(OAuth2Constants.ERROR_DESCRIPTION, e.getDescription()); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); } - AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit) + AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event) .accessToken(accessToken) .generateIDToken() .generateRefreshToken().build(); - audit.success(); + event.success(); return Cors.add(request, Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build(); } @@ -477,14 +477,14 @@ public class TokenService { String rememberMe = formData.getFirst("rememberMe"); boolean remember = rememberMe != null && rememberMe.equalsIgnoreCase("on"); - audit.event(EventType.LOGIN).client(clientId) + event.event(EventType.LOGIN).client(clientId) .detail(Details.REDIRECT_URI, redirect) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.AUTH_METHOD, "form") .detail(Details.USERNAME, username); if (remember) { - audit.detail(Details.REMEMBER_ME, "true"); + event.detail(Details.REMEMBER_ME, "true"); } OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); @@ -494,27 +494,27 @@ public class TokenService { } if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return oauth.forwardToSecurityFailure("Realm not enabled."); } ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Unknown login requester."); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Login requester not enabled."); } redirect = verifyRedirectUri(uriInfo, redirect, realm, client); if (redirect == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return oauth.forwardToSecurityFailure("Invalid redirect_uri."); } if (formData.containsKey("cancel")) { - audit.error(Errors.REJECTED_BY_USER); + event.error(Errors.REJECTED_BY_USER); return oauth.redirectError(client, "access_denied", state, redirect); } @@ -528,36 +528,36 @@ public class TokenService { UserModel user = KeycloakModelUtils.findUserByNameOrEmail(session, realm, username); if (user != null) { - audit.user(user); + event.user(user); } switch (status) { case SUCCESS: case ACTIONS_REQUIRED: UserSessionModel userSession = session.sessions().createUserSession(realm, user, username, clientConnection.getRemoteAddr(), "form", remember); - audit.session(userSession); + event.session(userSession); - return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, audit); + return oauth.processAccessCode(scopeParam, state, redirect, client, user, userSession, event); case ACCOUNT_TEMPORARILY_DISABLED: - audit.error(Errors.USER_TEMPORARILY_DISABLED); + event.error(Errors.USER_TEMPORARILY_DISABLED); return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_TEMPORARILY_DISABLED).setFormData(formData).createLogin(); case ACCOUNT_DISABLED: - audit.error(Errors.USER_DISABLED); + event.error(Errors.USER_DISABLED); return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.ACCOUNT_DISABLED).setFormData(formData).createLogin(); case MISSING_TOTP: return Flows.forms(this.session, realm, client, uriInfo).setFormData(formData).createLoginTotp(); case INVALID_USER: - audit.error(Errors.USER_NOT_FOUND); + event.error(Errors.USER_NOT_FOUND); return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin(); default: - audit.error(Errors.INVALID_USER_CREDENTIALS); + event.error(Errors.INVALID_USER_CREDENTIALS); return Flows.forms(this.session, realm, client, uriInfo).setError(Messages.INVALID_USER).setFormData(formData).createLogin(); } } @Path("auth/request/login-actions") public RequiredActionsService getRequiredActionsService() { - RequiredActionsService service = new RequiredActionsService(realm, tokenManager, audit); + RequiredActionsService service = new RequiredActionsService(realm, tokenManager, event); ResteasyProviderFactory.getInstance().injectProperties(service); //resourceContext.initResource(service); @@ -584,7 +584,7 @@ public class TokenService { String username = formData.getFirst("username"); String email = formData.getFirst("email"); - audit.event(EventType.REGISTER).client(clientId) + event.event(EventType.REGISTER).client(clientId) .detail(Details.REDIRECT_URI, redirect) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.USERNAME, username) @@ -594,28 +594,28 @@ public class TokenService { OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return oauth.forwardToSecurityFailure("Realm not enabled"); } ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Unknown login requester."); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); return oauth.forwardToSecurityFailure("Login requester not enabled."); } redirect = verifyRedirectUri(uriInfo, redirect, realm, client); if (redirect == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return oauth.forwardToSecurityFailure("Invalid redirect_uri."); } if (!realm.isRegistrationAllowed()) { - audit.error(Errors.REGISTRATION_DISABLED); + event.error(Errors.REGISTRATION_DISABLED); return oauth.forwardToSecurityFailure("Registration not allowed"); } @@ -631,19 +631,19 @@ public class TokenService { } if (error != null) { - audit.error(Errors.INVALID_REGISTRATION); + event.error(Errors.INVALID_REGISTRATION); return Flows.forms(session, realm, client, uriInfo).setError(error).setFormData(formData).createRegistration(); } // Validate that user with this username doesn't exist in realm or any federation provider if (session.users().getUserByUsername(username, realm) != null) { - audit.error(Errors.USERNAME_IN_USE); + event.error(Errors.USERNAME_IN_USE); return Flows.forms(session, realm, client, uriInfo).setError(Messages.USERNAME_EXISTS).setFormData(formData).createRegistration(); } // Validate that user with this email doesn't exist in realm or any federation provider if (session.users().getUserByEmail(email, realm) != null) { - audit.error(Errors.EMAIL_IN_USE); + event.error(Errors.EMAIL_IN_USE); return Flows.forms(session, realm, client, uriInfo).setError(Messages.EMAIL_EXISTS).setFormData(formData).createRegistration(); } @@ -676,8 +676,8 @@ public class TokenService { } } - audit.user(user).success(); - audit.reset(); + event.user(user).success(); + event.reset(); return processLogin(clientId, scopeParam, state, redirect, formData); } @@ -714,10 +714,10 @@ public class TokenService { throw new ForbiddenException("HTTPS required"); } - audit.event(EventType.CODE_TO_TOKEN); + event.event(EventType.CODE_TO_TOKEN); if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); throw new UnauthorizedException("Realm not enabled"); } @@ -726,7 +726,7 @@ public class TokenService { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_request"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "code not specified"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); throw new BadRequestException("Code not specified", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } @@ -735,39 +735,39 @@ public class TokenService { String[] parts = code.split("\\."); if (parts.length == 2) { try { - audit.detail(Details.CODE_ID, new String(Base64Url.decode(parts[1]))); + event.detail(Details.CODE_ID, new String(Base64Url.decode(parts[1]))); } catch (Throwable t) { } } Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "Code not found"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } - audit.detail(Details.CODE_ID, accessCode.getCodeId()); + event.detail(Details.CODE_ID, accessCode.getCodeId()); if (!accessCode.isValid(ClientSessionModel.Action.CODE_TO_TOKEN)) { Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "Code is expired"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } accessCode.setAction(null); - audit.user(accessCode.getUser()); - audit.session(accessCode.getSessionState()); + event.user(accessCode.getUser()); + event.session(accessCode.getSessionState()); - ClientModel client = authorizeClient(authorizationHeader, formData, audit); + ClientModel client = authorizeClient(authorizationHeader, formData, event); if (!client.getClientId().equals(accessCode.getClient().getClientId())) { Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "Auth error"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } @@ -777,7 +777,7 @@ public class TokenService { Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "User not found"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } @@ -786,7 +786,7 @@ public class TokenService { Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "User disabled"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } @@ -797,7 +797,7 @@ public class TokenService { Map res = new HashMap(); res.put(OAuth2Constants.ERROR, "invalid_grant"); res.put(OAuth2Constants.ERROR_DESCRIPTION, "Session not active"); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON_TYPE).entity(res) .build(); } @@ -810,21 +810,21 @@ public class TokenService { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, e.getError()); if (e.getDescription() != null) error.put(OAuth2Constants.ERROR_DESCRIPTION, e.getDescription()); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); } - AccessTokenResponse res = tokenManager.responseBuilder(realm, client, audit) + AccessTokenResponse res = tokenManager.responseBuilder(realm, client, event) .accessToken(token) .generateIDToken() .generateRefreshToken().build(); - audit.success(); + event.success(); return Cors.add(request, Response.ok(res)).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build(); } - protected ClientModel authorizeClient(String authorizationHeader, MultivaluedMap formData, Audit audit) { + protected ClientModel authorizeClient(String authorizationHeader, MultivaluedMap formData, EventBuilder event) { String client_id; String clientSecret; if (authorizationHeader != null) { @@ -846,14 +846,14 @@ public class TokenService { throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } - audit.client(client_id); + event.client(client_id); ClientModel client = realm.findClient(client_id); if (client == null) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Could not find client"); - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); throw new BadRequestException("Could not find client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } @@ -861,7 +861,7 @@ public class TokenService { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Client is not enabled"); - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); throw new BadRequestException("Client is not enabled", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } @@ -869,7 +869,7 @@ public class TokenService { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "invalid_client"); error.put(OAuth2Constants.ERROR_DESCRIPTION, "Bearer-only not allowed"); - audit.error(Errors.INVALID_CLIENT); + event.error(Errors.INVALID_CLIENT); throw new BadRequestException("Bearer-only not allowed", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } @@ -877,7 +877,7 @@ public class TokenService { if (clientSecret == null || !client.validateSecret(clientSecret)) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, "unauthorized_client"); - audit.error(Errors.INVALID_CLIENT_CREDENTIALS); + event.error(Errors.INVALID_CLIENT_CREDENTIALS); throw new BadRequestException("Unauthorized Client", Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build()); } } @@ -904,7 +904,7 @@ public class TokenService { @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId, final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state, final @QueryParam("prompt") String prompt, final @QueryParam("login_hint") String loginHint) { - audit.event(EventType.LOGIN).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code"); + event.event(EventType.LOGIN).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code"); OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); @@ -913,30 +913,30 @@ public class TokenService { } if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return oauth.forwardToSecurityFailure("Realm not enabled"); } ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Unknown login requester."); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); return oauth.forwardToSecurityFailure("Login requester not enabled."); } if ( (client instanceof ApplicationModel) && ((ApplicationModel)client).isBearerOnly()) { - audit.error(Errors.NOT_ALLOWED); + event.error(Errors.NOT_ALLOWED); return oauth.forwardToSecurityFailure("Bearer-only applications are not allowed to initiate browser login"); } if (client.isDirectGrantsOnly()) { - audit.error(Errors.NOT_ALLOWED); + event.error(Errors.NOT_ALLOWED); return oauth.forwardToSecurityFailure("direct-grants-only clients are not allowed to initiate browser login"); } redirect = verifyRedirectUri(uriInfo, redirect, realm, client); if (redirect == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return oauth.forwardToSecurityFailure("Invalid redirect_uri."); } @@ -945,8 +945,8 @@ public class TokenService { UserModel user = authResult.getUser(); UserSessionModel session = authResult.getSession(); - audit.user(user).session(session).detail(Details.AUTH_METHOD, "sso"); - return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, audit); + event.user(user).session(session).detail(Details.AUTH_METHOD, "sso"); + return oauth.processAccessCode(scopeParam, state, redirect, client, user, session, event); } if (prompt != null && prompt.equals("none")) { @@ -980,7 +980,7 @@ public class TokenService { public Response registerPage(final @QueryParam("response_type") String responseType, @QueryParam("redirect_uri") String redirect, final @QueryParam("client_id") String clientId, final @QueryParam("scope") String scopeParam, final @QueryParam("state") String state) { - audit.event(EventType.REGISTER).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code"); + event.event(EventType.REGISTER).client(clientId).detail(Details.REDIRECT_URI, redirect).detail(Details.RESPONSE_TYPE, "code"); OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); @@ -989,28 +989,28 @@ public class TokenService { } if (!realm.isEnabled()) { - audit.error(Errors.REALM_DISABLED); + event.error(Errors.REALM_DISABLED); return oauth.forwardToSecurityFailure("Realm not enabled"); } ClientModel client = realm.findClient(clientId); if (client == null) { - audit.error(Errors.CLIENT_NOT_FOUND); + event.error(Errors.CLIENT_NOT_FOUND); return oauth.forwardToSecurityFailure("Unknown login requester."); } if (!client.isEnabled()) { - audit.error(Errors.CLIENT_DISABLED); + event.error(Errors.CLIENT_DISABLED); return oauth.forwardToSecurityFailure("Login requester not enabled."); } redirect = verifyRedirectUri(uriInfo, redirect, realm, client); if (redirect == null) { - audit.error(Errors.INVALID_REDIRECT_URI); + event.error(Errors.INVALID_REDIRECT_URI); return oauth.forwardToSecurityFailure("Invalid redirect_uri."); } if (!realm.isRegistrationAllowed()) { - audit.error(Errors.REGISTRATION_DISABLED); + event.error(Errors.REGISTRATION_DISABLED); return oauth.forwardToSecurityFailure("Registration not allowed"); } @@ -1029,9 +1029,9 @@ public class TokenService { @GET @NoCache public Response logout(final @QueryParam("redirect_uri") String redirectUri) { - audit.event(EventType.LOGOUT); + event.event(EventType.LOGOUT); if (redirectUri != null) { - audit.detail(Details.REDIRECT_URI, redirectUri); + event.detail(Details.REDIRECT_URI, redirectUri); } // authenticate identity cookie, but ignore an access token timeout as we're logging out anyways. AuthenticationManager.AuthResult authResult = authManager.authenticateIdentityCookie(session, realm, uriInfo, clientConnection, headers, false); @@ -1076,15 +1076,15 @@ public class TokenService { throw new NotAcceptableException("HTTPS required"); } - audit.event(EventType.LOGOUT); + event.event(EventType.LOGOUT); - ClientModel client = authorizeClient(authorizationHeader, form, audit); + ClientModel client = authorizeClient(authorizationHeader, form, event); String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN); if (refreshToken == null) { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, OAuthErrorException.INVALID_REQUEST); error.put(OAuth2Constants.ERROR_DESCRIPTION, "No refresh token"); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); } try { @@ -1097,7 +1097,7 @@ public class TokenService { Map error = new HashMap(); error.put(OAuth2Constants.ERROR, e.getError()); if (e.getDescription() != null) error.put(OAuth2Constants.ERROR_DESCRIPTION, e.getDescription()); - audit.error(Errors.INVALID_TOKEN); + event.error(Errors.INVALID_TOKEN); return Response.status(Response.Status.BAD_REQUEST).entity(error).type("application/json").build(); } return Cors.add(request, Response.noContent()).auth().allowedOrigins(client).allowedMethods("POST").exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS).build(); @@ -1105,7 +1105,7 @@ public class TokenService { private void logout(UserSessionModel userSession) { authManager.logout(session, realm, userSession, uriInfo, clientConnection); - audit.user(userSession.getUser()).session(userSession).success(); + event.user(userSession.getUser()).session(userSession).success(); } /** @@ -1118,7 +1118,7 @@ public class TokenService { @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response processOAuth(final MultivaluedMap formData) { - audit.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code"); + event.event(EventType.LOGIN).detail(Details.RESPONSE_TYPE, "code"); OAuthFlows oauth = Flows.oauth(session, realm, request, uriInfo, clientConnection, authManager, tokenManager); @@ -1130,41 +1130,41 @@ public class TokenService { AccessCode accessCode = AccessCode.parse(code, session, realm); if (accessCode == null || !accessCode.isValid(ClientSessionModel.Action.OAUTH_GRANT)) { - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return oauth.forwardToSecurityFailure("Invalid access code."); } - audit.detail(Details.CODE_ID, accessCode.getCodeId()); + event.detail(Details.CODE_ID, accessCode.getCodeId()); String redirect = accessCode.getRedirectUri(); String state = accessCode.getState(); - audit.client(accessCode.getClient()) + event.client(accessCode.getClient()) .user(accessCode.getUser()) .detail(Details.RESPONSE_TYPE, "code") .detail(Details.REDIRECT_URI, redirect); UserSessionModel userSession = session.sessions().getUserSession(realm, accessCode.getSessionState()); if (userSession != null) { - audit.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); - audit.detail(Details.USERNAME, userSession.getLoginUsername()); + event.detail(Details.AUTH_METHOD, userSession.getAuthMethod()); + event.detail(Details.USERNAME, userSession.getLoginUsername()); if (userSession.isRememberMe()) { - audit.detail(Details.REMEMBER_ME, "true"); + event.detail(Details.REMEMBER_ME, "true"); } } if (!AuthenticationManager.isSessionValid(realm, userSession)) { AuthenticationManager.logout(session, realm, userSession, uriInfo, clientConnection); - audit.error(Errors.INVALID_CODE); + event.error(Errors.INVALID_CODE); return oauth.forwardToSecurityFailure("Session not active"); } - audit.session(userSession); + event.session(userSession); if (formData.containsKey("cancel")) { - audit.error(Errors.REJECTED_BY_USER); + event.error(Errors.REJECTED_BY_USER); return redirectAccessDenied(redirect, state); } - audit.success(); + event.success(); accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN); return oauth.redirectAccessCode(accessCode, userSession, state, redirect); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index 7b41b55ade..fe8a11e3e9 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -4,10 +4,10 @@ import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventQuery; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventType; import org.keycloak.models.ApplicationModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; @@ -19,7 +19,7 @@ import org.keycloak.models.cache.CacheUserProvider; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.adapters.action.SessionStats; -import org.keycloak.representations.idm.RealmAuditRepresentation; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.LDAPConnectionTestManager; import org.keycloak.services.managers.UsersSyncManager; @@ -306,62 +306,62 @@ public class RealmAdminResource { } /** - * View the audit provider and how it is configured. + * View the events provider and how it is configured. * * @return */ @GET @NoCache - @Path("audit") + @Path("events/config") @Produces("application/json") - public RealmAuditRepresentation getRealmAudit() { - auth.init(RealmAuth.Resource.AUDIT).requireView(); + public RealmEventsConfigRepresentation getRealmEventsConfig() { + auth.init(RealmAuth.Resource.EVENTS).requireView(); - return ModelToRepresentation.toAuditReprensetation(realm); + return ModelToRepresentation.toEventsConfigReprensetation(realm); } /** - * Change the audit provider and/or it's configuration + * Change the events provider and/or it's configuration * * @param rep */ @PUT - @Path("audit") + @Path("events/config") @Consumes("application/json") - public void updateRealmAudit(final RealmAuditRepresentation rep) { - auth.init(RealmAuth.Resource.AUDIT).requireManage(); + public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) { + auth.init(RealmAuth.Resource.EVENTS).requireManage(); - logger.debug("updating realm audit: " + realm.getName()); - new RealmManager(session).updateRealmAudit(rep, realm); + logger.debug("updating realm events config: " + realm.getName()); + new RealmManager(session).updateRealmEventsConfig(rep, realm); } /** - * Query audit events. Returns all events, or will query based on URL query parameters listed here + * Query events. Returns all events, or will query based on URL query parameters listed here * * @param client app or oauth client name - * @param event event type + * @param type type type * @param user user id * @param ipAddress * @param firstResult * @param maxResults * @return */ - @Path("audit/events") + @Path("events") @GET @NoCache @Produces(MediaType.APPLICATION_JSON) - public List getAudit(@QueryParam("client") String client, @QueryParam("event") String event, @QueryParam("user") String user, - @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { - auth.init(RealmAuth.Resource.AUDIT).requireView(); + public List getEvents(@QueryParam("client") String client, @QueryParam("type") String type, @QueryParam("user") String user, + @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { + auth.init(RealmAuth.Resource.EVENTS).requireView(); - AuditProvider audit = session.getProvider(AuditProvider.class); + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - EventQuery query = audit.createQuery().realm(realm.getId()); + EventQuery query = eventStore.createQuery().realm(realm.getId()); if (client != null) { query.client(client); } - if (event != null) { - query.event(EventType.valueOf(event)); + if (type != null) { + query.type(EventType.valueOf(type)); } if (user != null) { query.user(user); @@ -380,16 +380,16 @@ public class RealmAdminResource { } /** - * Delete all audit events. + * Delete all events. * */ - @Path("audit/events") + @Path("events") @DELETE - public void clearAudit() { - auth.init(RealmAuth.Resource.AUDIT).requireManage(); + public void clearEvents() { + auth.init(RealmAuth.Resource.EVENTS).requireManage(); - AuditProvider audit = session.getProvider(AuditProvider.class); - audit.clear(realm.getId()); + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + eventStore.clear(realm.getId()); } @Path("testLDAPConnection") diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java index e2ef922433..641315beb5 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAuth.java @@ -13,7 +13,7 @@ public class RealmAuth { private Resource resource; public enum Resource { - APPLICATION, CLIENT, USER, REALM, AUDIT + APPLICATION, CLIENT, USER, REALM, EVENTS } private AdminAuth auth; @@ -65,8 +65,8 @@ public class RealmAuth { return AdminRoles.VIEW_USERS; case REALM: return AdminRoles.VIEW_REALM; - case AUDIT: - return AdminRoles.VIEW_AUDIT; + case EVENTS: + return AdminRoles.VIEW_EVENTS; default: throw new IllegalStateException(); } @@ -82,8 +82,8 @@ public class RealmAuth { return AdminRoles.MANAGE_USERS; case REALM: return AdminRoles.MANAGE_REALM; - case AUDIT: - return AdminRoles.MANAGE_AUDIT; + case EVENTS: + return AdminRoles.MANAGE_EVENTS; default: throw new IllegalStateException(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java index 891e64e047..391ffbb71a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java @@ -1,7 +1,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; -import org.keycloak.audit.AuditListener; +import org.keycloak.events.EventListenerProvider; import org.keycloak.freemarker.Theme; import org.keycloak.freemarker.ThemeProvider; import org.keycloak.models.KeycloakSession; @@ -26,7 +26,7 @@ public class ServerInfoAdminResource { private KeycloakSession session; /** - * Returns a list of themes, social providers, auth providers, and audit listeners available on this server + * Returns a list of themes, social providers, auth providers, and event listeners available on this server * * @return */ @@ -36,7 +36,7 @@ public class ServerInfoAdminResource { ServerInfoRepresentation info = new ServerInfoRepresentation(); setSocialProviders(info); setThemes(info); - setAuditListeners(info); + setEventListeners(info); return info; } @@ -60,12 +60,12 @@ public class ServerInfoAdminResource { Collections.sort(info.socialProviders); } - private void setAuditListeners(ServerInfoRepresentation info) { - info.auditListeners = new LinkedList(); + private void setEventListeners(ServerInfoRepresentation info) { + info.eventListeners = new LinkedList(); - Set providers = session.listProviderIds(AuditListener.class); + Set providers = session.listProviderIds(EventListenerProvider.class); if (providers != null) { - info.auditListeners.addAll(providers); + info.eventListeners.addAll(providers); } } @@ -76,7 +76,7 @@ public class ServerInfoAdminResource { private List socialProviders; - private List auditListeners; + private List eventListeners; public ServerInfoRepresentation() { } @@ -89,8 +89,8 @@ public class ServerInfoAdminResource { return socialProviders; } - public List getAuditListeners() { - return auditListeners; + public List getEventListeners() { + return eventListeners; } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index 8f0b0bf93a..de1cc0612f 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -5,7 +5,6 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.ClientConnection; -import org.keycloak.audit.Details; import org.keycloak.email.EmailException; import org.keycloak.email.EmailProvider; import org.keycloak.models.ApplicationModel; diff --git a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java index 0b10857f43..d6beb1796e 100755 --- a/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java +++ b/services/src/main/java/org/keycloak/services/resources/flows/OAuthFlows.java @@ -26,9 +26,9 @@ import org.jboss.resteasy.specimpl.MultivaluedMapImpl; import org.jboss.resteasy.spi.HttpRequest; import org.keycloak.ClientConnection; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Audit; -import org.keycloak.audit.Details; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.Details; +import org.keycloak.events.EventType; import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; @@ -124,7 +124,7 @@ public class OAuthFlows { return Response.status(302).location(redirectUri.build()).build(); } - public Response processAccessCode(String scopeParam, String state, String redirect, ClientModel client, UserModel user, UserSessionModel session, Audit audit) { + public Response processAccessCode(String scopeParam, String state, String redirect, ClientModel client, UserModel user, UserSessionModel session, EventBuilder event) { isTotpConfigurationRequired(user); isEmailVerificationRequired(user); @@ -135,7 +135,7 @@ public class OAuthFlows { log.debugv("processAccessCode: go to oauth page?: {0}", !isResource); - audit.detail(Details.CODE_ID, accessCode.getCodeId()); + event.detail(Details.CODE_ID, accessCode.getCodeId()); Set requiredActions = user.getRequiredActions(); if (!requiredActions.isEmpty()) { @@ -143,7 +143,7 @@ public class OAuthFlows { accessCode.setRequiredAction(action); if (action.equals(RequiredAction.VERIFY_EMAIL)) { - audit.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); + event.clone().event(EventType.SEND_VERIFY_EMAIL).detail(Details.EMAIL, accessCode.getUser().getEmail()).success(); } return Flows.forms(this.session, realm, client, uriInfo).setAccessCode(accessCode.getCode()).setUser(user) @@ -171,7 +171,7 @@ public class OAuthFlows { } if (redirect != null) { - audit.success(); + event.success(); accessCode.setAction(ClientSessionModel.Action.CODE_TO_TOKEN); return redirectAccessCode(accessCode, session, state, redirect); diff --git a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredEvents.java similarity index 52% rename from services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java rename to services/src/main/java/org/keycloak/services/scheduled/ClearExpiredEvents.java index 193589c046..720c48235b 100755 --- a/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredAuditEvents.java +++ b/services/src/main/java/org/keycloak/services/scheduled/ClearExpiredEvents.java @@ -1,22 +1,22 @@ package org.keycloak.services.scheduled; -import org.keycloak.audit.AuditProvider; +import org.keycloak.events.EventStoreProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; /** * @author Stian Thorgersen */ -public class ClearExpiredAuditEvents implements ScheduledTask { +public class ClearExpiredEvents implements ScheduledTask { @Override public void run(KeycloakSession session) { - AuditProvider audit = session.getProvider(AuditProvider.class); - if (audit != null) { + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + if (eventStore != null) { for (RealmModel realm : session.realms().getRealms()) { - if (realm.isAuditEnabled() && realm.getAuditExpiration() > 0) { - long olderThan = System.currentTimeMillis() - realm.getAuditExpiration() * 1000; - audit.clear(realm.getId(), olderThan); + if (realm.isEventsEnabled() && realm.getEventsExpiration() > 0) { + long olderThan = System.currentTimeMillis() - realm.getEventsExpiration() * 1000; + eventStore.clear(realm.getId(), olderThan); } } } diff --git a/testsuite/integration/README.md b/testsuite/integration/README.md index 564451f504..9de055c154 100644 --- a/testsuite/integration/README.md +++ b/testsuite/integration/README.md @@ -57,7 +57,7 @@ To start a Keycloak server with identity model data persisted in Mongo database By default it's using database `keycloak` on localhost/27017 and it uses already existing data from this DB (no cleanup of existing data during bootstrap). Assumption is that you already have DB running on localhost/27017 . Use system properties to configure things differently: - mvn exec:java -Pkeycloak-server -Dkeycloak.realm.provider=mongo -Dkeycloak.user.provider=mongo -Dkeycloak.audit.provider=mongo -Dkeycloak.connectionsMongo.host=localhost -Dkeycloak.connectionsMongo.port=27017 -Dkeycloak.connectionsMongo.db=keycloak -Dkeycloak.connectionsMongo.clearOnStartup=false + mvn exec:java -Pkeycloak-server -Dkeycloak.realm.provider=mongo -Dkeycloak.user.provider=mongo -Dkeycloak.eventStore.provider=mongo -Dkeycloak.connectionsMongo.host=localhost -Dkeycloak.connectionsMongo.port=27017 -Dkeycloak.connectionsMongo.db=keycloak -Dkeycloak.connectionsMongo.clearOnStartup=false Note that if you are using Mongo model, it would mean that Mongo will be used for audit as well. You may need to use audit related properties for configuration of Mongo if you want to override default ones (For example keycloak.audit.mongo.host, keycloak.audit.mongo.port etc) diff --git a/testsuite/integration/pom.xml b/testsuite/integration/pom.xml index c75f38dae6..f7b098287a 100755 --- a/testsuite/integration/pom.xml +++ b/testsuite/integration/pom.xml @@ -288,7 +288,7 @@ jpa jpa - jpa + jpa jpa diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json index 7101a8f8fb..6e90fa12df 100755 --- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json +++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json @@ -3,8 +3,8 @@ "realm": "master" }, - "audit": { - "provider": "${keycloak.audit.provider:jpa}" + "eventsStore": { + "provider": "${keycloak.eventStore.provider:jpa}" }, "realm": { 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 fa2b7674bb..0dd893bbbb 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/AssertEvents.java @@ -8,11 +8,11 @@ import org.junit.Assert; import org.junit.rules.TestRule; import org.junit.runners.model.Statement; import org.keycloak.Config; -import org.keycloak.audit.AuditListener; -import org.keycloak.audit.AuditListenerFactory; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventListenerProviderFactory; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -34,7 +34,7 @@ import java.util.concurrent.TimeUnit; /** * @author Stian Thorgersen */ -public class AssertEvents implements TestRule, AuditListenerFactory { +public class AssertEvents implements TestRule, EventListenerProviderFactory { public static String DEFAULT_CLIENT_ID = "test-app"; public static String DEFAULT_REDIRECT_URI = "http://localhost:8081/app/auth"; @@ -71,7 +71,7 @@ public class AssertEvents implements TestRule, AuditListenerFactory { Set listeners = new HashSet(); listeners.add("jboss-logging"); listeners.add("assert-events"); - appRealm.setAuditListeners(listeners); + appRealm.setEventsListeners(listeners); } }); @@ -80,13 +80,13 @@ public class AssertEvents implements TestRule, AuditListenerFactory { Event event = events.peek(); if (event != null) { - Assert.fail("Unexpected event after test: " + event.getEvent()); + Assert.fail("Unexpected type after test: " + event.getType()); } } finally { keycloak.configure(new KeycloakRule.KeycloakSetup() { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.setAuditListeners(null); + appRealm.setEventsListeners(null); } }); } @@ -172,12 +172,12 @@ public class AssertEvents implements TestRule, AuditListenerFactory { } @Override - public AuditListener create(KeycloakSession session) { - return new AuditListener() { + public EventListenerProvider create(KeycloakSession session) { + return new EventListenerProvider() { @Override public void onEvent(Event event) { if (event == null) { - throw new RuntimeException("Added null event"); + throw new RuntimeException("Added null type"); } events.add(event); } @@ -254,7 +254,7 @@ public class AssertEvents implements TestRule, AuditListenerFactory { } public ExpectedEvent event(EventType e) { - expected.setEvent(e); + expected.setType(e); return this; } @@ -286,15 +286,15 @@ public class AssertEvents implements TestRule, AuditListenerFactory { try { return assertEvent(events.poll(10, TimeUnit.SECONDS)); } catch (InterruptedException e) { - throw new AssertionError("No event received within timeout"); + throw new AssertionError("No type received within timeout"); } } public Event assertEvent(Event actual) { - if (expected.getError() != null && !expected.getEvent().toString().endsWith("_ERROR")) { - expected.setEvent(EventType.valueOf(expected.getEvent().toString() + "_ERROR")); + if (expected.getError() != null && !expected.getType().toString().endsWith("_ERROR")) { + expected.setType(EventType.valueOf(expected.getType().toString() + "_ERROR")); } - Assert.assertEquals(expected.getEvent(), actual.getEvent()); + Assert.assertEquals(expected.getType(), actual.getType()); Assert.assertEquals(expected.getRealmId(), actual.getRealmId()); Assert.assertEquals(expected.getClientId(), actual.getClientId()); Assert.assertEquals(expected.getError(), actual.getError()); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java index 5fbf669618..c8a17befa1 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/account/AccountTest.java @@ -28,9 +28,9 @@ import org.junit.ClassRule; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.ApplicationModel; import org.keycloak.models.PasswordPolicy; import org.keycloak.models.RealmModel; @@ -370,7 +370,7 @@ public class AccountTest { keycloakRule.update(new KeycloakSetup() { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.setAuditEnabled(true); + appRealm.setEventsEnabled(true); } }); @@ -407,7 +407,7 @@ public class AccountTest { Iterator> itr = logPage.getEvents().iterator(); for (Event event : e) { List a = itr.next(); - Assert.assertEquals(event.getEvent().toString().replace('_', ' ').toLowerCase(), a.get(1)); + Assert.assertEquals(event.getType().toString().replace('_', ' ').toLowerCase(), a.get(1)); Assert.assertEquals(event.getIpAddress(), a.get(2)); Assert.assertEquals(event.getClientId(), a.get(3)); } @@ -417,7 +417,7 @@ public class AccountTest { keycloakRule.update(new KeycloakSetup() { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.setAuditEnabled(false); + appRealm.setEventsEnabled(false); } }); } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java index 012cb9e184..2ad03e3d8c 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java @@ -26,9 +26,9 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.services.managers.RealmManager; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java index 4f9f7409af..4d16a1b1dc 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java @@ -25,8 +25,8 @@ import org.junit.Assert; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java index e357843d87..a512795b82 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java @@ -25,8 +25,8 @@ import org.junit.Assert; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java index dcc844c962..0874c3815f 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java @@ -25,9 +25,9 @@ import org.junit.Assert; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.CredentialRepresentation; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java index a5a87c12a4..f66c88e72b 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java @@ -26,8 +26,8 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.services.managers.RealmManager; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/audit/AuditProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/audit/AuditProviderTest.java deleted file mode 100644 index 6c0c538785..0000000000 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/audit/AuditProviderTest.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.keycloak.testsuite.audit; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.keycloak.audit.AuditProvider; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; -import org.keycloak.models.KeycloakSession; -import org.keycloak.testsuite.rule.KeycloakRule; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author Stian Thorgersen - */ -public class AuditProviderTest { - - @ClassRule - public static KeycloakRule kc = new KeycloakRule(); - - private KeycloakSession session; - - private AuditProvider audit; - - @Before - public void before() { - session = kc.startSession(); - audit = session.getProvider(AuditProvider.class); - } - - @After - public void after() { - audit.clear(); - kc.stopSession(session, true); - } - - @Test - public void save() { - audit.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - } - - @Test - public void query() { - long oldest = System.currentTimeMillis() - 30000; - long newest = System.currentTimeMillis() + 30000; - - audit.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(newest, EventType.REGISTER, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(newest, EventType.REGISTER, "realmId", "clientId", "userId2", "127.0.0.1", "error")); - audit.onEvent(create(EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(oldest, EventType.LOGIN, "realmId", "clientId2", "userId", "127.0.0.1", "error")); - audit.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId2", "127.0.0.1", "error")); - - resetSession(); - - Assert.assertEquals(5, audit.createQuery().client("clientId").getResultList().size()); - Assert.assertEquals(5, audit.createQuery().realm("realmId").getResultList().size()); - Assert.assertEquals(4, audit.createQuery().event(EventType.LOGIN).getResultList().size()); - Assert.assertEquals(6, audit.createQuery().event(EventType.LOGIN, EventType.REGISTER).getResultList().size()); - Assert.assertEquals(4, audit.createQuery().user("userId").getResultList().size()); - - Assert.assertEquals(1, audit.createQuery().user("userId").event(EventType.REGISTER).getResultList().size()); - - Assert.assertEquals(2, audit.createQuery().maxResults(2).getResultList().size()); - Assert.assertEquals(1, audit.createQuery().firstResult(5).getResultList().size()); - - Assert.assertEquals(newest, audit.createQuery().maxResults(1).getResultList().get(0).getTime()); - Assert.assertEquals(oldest, audit.createQuery().firstResult(5).maxResults(1).getResultList().get(0).getTime()); - } - - @Test - public void clear() { - audit.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis() - 20000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); - - resetSession(); - - audit.clear("realmId"); - - Assert.assertEquals(1, audit.createQuery().getResultList().size()); - } - - @Test - public void clearOld() { - audit.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis() - 20000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); - audit.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); - - resetSession(); - - audit.clear("realmId", System.currentTimeMillis() - 10000); - - Assert.assertEquals(3, audit.createQuery().getResultList().size()); - } - - private Event create(EventType event, String realmId, String clientId, String userId, String ipAddress, String error) { - return create(System.currentTimeMillis(), event, realmId, clientId, userId, ipAddress, error); - } - - private Event create(long time, EventType event, String realmId, String clientId, String userId, String ipAddress, String error) { - Event e = new Event(); - e.setTime(time); - e.setEvent(event); - e.setRealmId(realmId); - e.setClientId(clientId); - e.setUserId(userId); - e.setIpAddress(ipAddress); - e.setError(error); - - Map details = new HashMap(); - details.put("key1", "value1"); - details.put("key2", "value2"); - - e.setDetails(details); - - return e; - } - - private void resetSession() { - kc.stopSession(session, true); - session = kc.startSession(); - audit = session.getProvider(AuditProvider.class); - } - -} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/events/EventStoreProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/EventStoreProviderTest.java new file mode 100644 index 0000000000..4f3a206915 --- /dev/null +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/EventStoreProviderTest.java @@ -0,0 +1,134 @@ +package org.keycloak.testsuite.events; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; +import org.keycloak.models.KeycloakSession; +import org.keycloak.testsuite.rule.KeycloakRule; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Stian Thorgersen + */ +public class EventStoreProviderTest { + + @ClassRule + public static KeycloakRule kc = new KeycloakRule(); + + private KeycloakSession session; + + private EventStoreProvider eventStore; + + @Before + public void before() { + session = kc.startSession(); + eventStore = session.getProvider(EventStoreProvider.class); + } + + @After + public void after() { + eventStore.clear(); + kc.stopSession(session, true); + } + + @Test + public void save() { + eventStore.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + } + + @Test + public void query() { + long oldest = System.currentTimeMillis() - 30000; + long newest = System.currentTimeMillis() + 30000; + + eventStore.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(newest, EventType.REGISTER, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(newest, EventType.REGISTER, "realmId", "clientId", "userId2", "127.0.0.1", "error")); + eventStore.onEvent(create(EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(oldest, EventType.LOGIN, "realmId", "clientId2", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(EventType.LOGIN, "realmId", "clientId", "userId2", "127.0.0.1", "error")); + + resetSession(); + + Assert.assertEquals(5, eventStore.createQuery().client("clientId").getResultList().size()); + Assert.assertEquals(5, eventStore.createQuery().realm("realmId").getResultList().size()); + Assert.assertEquals(4, eventStore.createQuery().type(EventType.LOGIN).getResultList().size()); + Assert.assertEquals(6, eventStore.createQuery().type(EventType.LOGIN, EventType.REGISTER).getResultList().size()); + Assert.assertEquals(4, eventStore.createQuery().user("userId").getResultList().size()); + + Assert.assertEquals(1, eventStore.createQuery().user("userId").type(EventType.REGISTER).getResultList().size()); + + Assert.assertEquals(2, eventStore.createQuery().maxResults(2).getResultList().size()); + Assert.assertEquals(1, eventStore.createQuery().firstResult(5).getResultList().size()); + + Assert.assertEquals(newest, eventStore.createQuery().maxResults(1).getResultList().get(0).getTime()); + Assert.assertEquals(oldest, eventStore.createQuery().firstResult(5).maxResults(1).getResultList().get(0).getTime()); + } + + @Test + public void clear() { + eventStore.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis() - 20000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); + + resetSession(); + + eventStore.clear("realmId"); + + Assert.assertEquals(1, eventStore.createQuery().getResultList().size()); + } + + @Test + public void clearOld() { + eventStore.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis() - 20000, EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis(), EventType.LOGIN, "realmId", "clientId", "userId", "127.0.0.1", "error")); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, EventType.LOGIN, "realmId2", "clientId", "userId", "127.0.0.1", "error")); + + resetSession(); + + eventStore.clear("realmId", System.currentTimeMillis() - 10000); + + Assert.assertEquals(3, eventStore.createQuery().getResultList().size()); + } + + private Event create(EventType event, String realmId, String clientId, String userId, String ipAddress, String error) { + return create(System.currentTimeMillis(), event, realmId, clientId, userId, ipAddress, error); + } + + private Event create(long time, EventType event, String realmId, String clientId, String userId, String ipAddress, String error) { + Event e = new Event(); + e.setTime(time); + e.setType(event); + e.setRealmId(realmId); + e.setClientId(clientId); + e.setUserId(userId); + e.setIpAddress(ipAddress); + e.setError(error); + + Map details = new HashMap(); + details.put("key1", "value1"); + details.put("key2", "value2"); + + e.setDetails(details); + + return e; + } + + private void resetSession() { + kc.stopSession(session, true); + session = kc.startSession(); + eventStore = session.getProvider(EventStoreProvider.class); + } + +} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java index 4447019c4f..77f3a54a8f 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTest.java @@ -26,7 +26,7 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.models.BrowserSecurityHeaders; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java index b680d0932c..f53e85a327 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserModel; @@ -66,7 +66,7 @@ public class LoginTotpTest { user.updateCredential(credentials); user.setTotp(true); - appRealm.setAuditListeners(Collections.singleton("dummy")); + appRealm.setEventsListeners(Collections.singleton("dummy")); } }); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java index 3f8bc1cf52..561fcd6815 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/LogoutTest.java @@ -24,7 +24,7 @@ package org.keycloak.testsuite.forms; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.OAuthClient; import org.keycloak.testsuite.pages.AppPage; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java index 429e5f90a9..ff76d22303 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java @@ -25,7 +25,7 @@ import org.junit.Assert; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.models.PasswordPolicy; import org.keycloak.models.RealmModel; import org.keycloak.services.managers.RealmManager; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java index 451056553f..22ec3c184c 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java @@ -25,8 +25,8 @@ import org.junit.Assert; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.EventType; import org.keycloak.models.PasswordPolicy; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; @@ -72,7 +72,7 @@ public class ResetPasswordTest { creds.setValue("password"); user.updateCredential(creds); - appRealm.setAuditListeners(Collections.singleton("dummy")); + appRealm.setEventsListeners(Collections.singleton("dummy")); } })); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/SSOTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/SSOTest.java index 4796226189..30c10a7628 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/SSOTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/SSOTest.java @@ -26,7 +26,7 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.OAuthClient; import org.keycloak.testsuite.pages.AccountUpdateProfilePage; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java index d3bb9154a0..98dd5ac0b6 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java @@ -26,9 +26,9 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; -import org.keycloak.audit.Event; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; +import org.keycloak.events.Event; import org.keycloak.enums.SslRequired; import org.keycloak.models.ApplicationModel; import org.keycloak.models.ClientModel; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java index 78cab61fc9..2ca2021303 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java @@ -26,7 +26,7 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; +import org.keycloak.events.Details; import org.keycloak.models.Constants; import org.keycloak.models.RealmModel; import org.keycloak.services.managers.AccessCode; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java index 947551e302..6985e88dab 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java @@ -26,8 +26,8 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; +import org.keycloak.events.Details; +import org.keycloak.events.Event; import org.keycloak.representations.AccessToken; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.OAuthClient; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java index bc1195a3ea..447ca753f2 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java @@ -26,15 +26,12 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; -import org.keycloak.audit.Event; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; +import org.keycloak.events.Event; import org.keycloak.enums.SslRequired; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java index 1ebf3279d8..f59c8ef811 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java @@ -4,8 +4,8 @@ import org.apache.http.HttpResponse; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; -import org.keycloak.audit.Details; -import org.keycloak.audit.Errors; +import org.keycloak.events.Details; +import org.keycloak.events.Errors; import org.keycloak.models.ApplicationModel; import org.keycloak.models.RealmModel; import org.keycloak.representations.AccessToken; diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java index 7293f3c1fc..f81b160074 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/social/SocialLoginTest.java @@ -27,9 +27,9 @@ import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.keycloak.OAuth2Constants; -import org.keycloak.audit.Details; -import org.keycloak.audit.Event; -import org.keycloak.audit.EventType; +import org.keycloak.events.Details; +import org.keycloak.events.Event; +import org.keycloak.events.EventType; import org.keycloak.models.RealmModel; import org.keycloak.representations.AccessToken; import org.keycloak.representations.idm.UserRepresentation; diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory similarity index 100% rename from testsuite/integration/src/test/resources/META-INF/services/org.keycloak.audit.AuditListenerFactory rename to testsuite/integration/src/test/resources/META-INF/services/org.keycloak.events.EventListenerProviderFactory diff --git a/testsuite/tools/src/main/resources/META-INF/keycloak-server.json b/testsuite/tools/src/main/resources/META-INF/keycloak-server.json index 654c17e1fa..a9662a036c 100755 --- a/testsuite/tools/src/main/resources/META-INF/keycloak-server.json +++ b/testsuite/tools/src/main/resources/META-INF/keycloak-server.json @@ -3,7 +3,7 @@ "realm": "master" }, - "audit": { + "eventsStore": { "provider": "jpa", "jpa": { "exclude-events": [ "REFRESH_TOKEN" ]
    Client{{event.clientId}}