[KEYCLOAK 392] Audit admin events

This commit is contained in:
girirajsharma committed 2015-05-13 16:47:30 +05:30
1 parent 502efe42c9
commit ccd5deb85f
46 files changed
+391 -462

No files matched your search

@@ -1,205 +0,0 @@
package org.keycloak.events;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.jboss.logging.Logger;
import org.keycloak.ClientConnection;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.events.admin.AuthDetails;
import org.keycloak.events.admin.OperationType;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.util.JsonSerialization;
import org.keycloak.util.Time;
public class AdminEventBuilder {
private static final Logger log = Logger.getLogger(AdminEventBuilder.class);
private EventStoreProvider store;
private List<EventListenerProvider> listeners;
private RealmModel realm;
private AdminEvent adminEvent;
public AdminEventBuilder(RealmModel realm, KeycloakSession session, ClientConnection clientConnection) {
this.realm = realm;
adminEvent = new AdminEvent();
if (realm.isAdminEventsEnabled()) {
EventStoreProvider store = session.getProvider(EventStoreProvider.class);
if (store != null) {
this.store = store;
} else {
log.error("Admin Events enabled, but no event store provider configured");
}
}
if (realm.getEventsListeners() != null && !realm.getEventsListeners().isEmpty()) {
this.listeners = new LinkedList<>();
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");
}
}
}
realm(realm);
ipAddress(clientConnection.getRemoteAddr());
}
public AdminEventBuilder operation(OperationType e) {
adminEvent.setOperationType(e);
return this;
}
public AdminEventBuilder realm(RealmModel realm) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setRealmId(realm.getId());
} else {
authDetails.setRealmId(realm.getId());
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder realm(String realmId) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setRealmId(realmId);
} else {
authDetails.setRealmId(realmId);
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder client(ClientModel client) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setClientId(client.getId());
} else {
authDetails.setClientId(client.getId());
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder client(String clientId) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setClientId(clientId);
} else {
authDetails.setClientId(clientId);
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder user(UserModel user) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setUserId(user.getId());
} else {
authDetails.setUserId(user.getId());
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder user(String userId) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setUserId(userId);
} else {
authDetails.setUserId(userId);
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder ipAddress(String ipAddress) {
AuthDetails authDetails = adminEvent.getAuthDetails();
if(authDetails == null) {
authDetails = new AuthDetails();
authDetails.setIpAddress(ipAddress);
} else {
authDetails.setIpAddress(ipAddress);
}
adminEvent.setAuthDetails(authDetails);
return this;
}
public AdminEventBuilder resourcePath(String resourcePath) {
adminEvent.setResourcePath(resourcePath);
return this;
}
public void error(String error) {
adminEvent.setOperationType(OperationType.valueOf(adminEvent.getOperationType().name() + "_ERROR"));
adminEvent.setError(error);
send();
}
public AdminEventBuilder representation(Object value) {
if (value == null || value.equals("")) {
return this;
}
try {
adminEvent.setRepresentation(JsonSerialization.writeValueAsString(value));
} catch (IOException e) {
throw new RuntimeException(e);
}
return this;
}
public AdminEvent getEvent() {
return adminEvent;
}
public void success() {
send();
}
private void send() {
boolean includeRepresentation = false;
if(realm.isAdminEventsDetailsEnabled()) {
includeRepresentation = true;
}
adminEvent.setTime(Time.toMillis(Time.currentTime()));
if (store != null) {
if (realm.getAdminEnabledEventOperations() != null && !realm.getAdminEnabledEventOperations().isEmpty() ? realm.getAdminEnabledEventOperations().contains(adminEvent.getOperationType().name()) : adminEvent.getOperationType().isSaveByDefault()) {
try {
store.onEvent(adminEvent, includeRepresentation);
} catch (Throwable t) {
log.error("Failed to save event", t);
}
}
}
if (listeners != null) {
for (EventListenerProvider l : listeners) {
try {
l.onEvent(adminEvent, includeRepresentation);
} catch (Throwable t) {
log.error("Failed to send type to " + l, t);
}
}
}
}
}
@@ -1,13 +1,13 @@
package org.keycloak.events.admin;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AdminEvent {
private long time;
private String realmId;
private AuthDetails authDetails;
@@ -31,6 +31,19 @@ public class AdminEvent {
public void setTime(long time) {
this.time = time;
}
/**
* Returns the id of the realm
*
* @return
*/
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
/**
* Returns authentication details
@@ -8,28 +8,36 @@ import java.util.List;
public interface AdminEventQuery {
/**
* Search by authentication realm
* Search by resource realm
*
* @param realm realm name
* @param realmId realm id
* @return Associated <code>AdminEventQuery</code> for method chaining
*/
AdminEventQuery authRealm(String realm);
AdminEventQuery realm(String realmId);
/**
* Search by authentication realm
*
* @param realmId realm name
* @return Associated <code>AdminEventQuery</code> for method chaining
*/
AdminEventQuery authRealm(String realmId);
/**
* Search by authenticated client
*
* @param client client uuid
* @param clientId client uuid
* @return Associated <code>AdminEventQuery</code> for method chaining
*/
AdminEventQuery authClient(String client);
AdminEventQuery authClient(String clientId);
/**
* Search by authenticated user
*
* @param user user uuid
* @param userId user uuid
* @return Associated <code>AdminEventQuery</code> for method chaining
*/
AdminEventQuery authUser(String user);
AdminEventQuery authUser(String userId);
/**
* Search by request ip address
@@ -5,20 +5,9 @@ package org.keycloak.events.admin;
*/
public enum OperationType {
VIEW(false),
CREATE(true),
UPDATE(true),
DELETE(true),
ACTION(false);
private boolean saveByDefault;
OperationType(boolean saveByDefault) {
this.saveByDefault = saveByDefault;
}
public boolean isSaveByDefault() {
return saveByDefault;
}
CREATE,
UPDATE,
DELETE,
ACTION;
}
@@ -19,16 +19,19 @@ public class AdminEventEntity {
@Column(name="ADMIN_EVENT_TIME")
private long time;
@Column(name="REALM_ID")
private String realmId;
@Column(name="OPERATION_TYPE")
private String operationType;
@Column(name="REALM_ID")
@Column(name="AUTH_REALM_ID")
private String authRealmId;
@Column(name="CLIENT_ID")
@Column(name="AUTH_CLIENT_ID")
private String authClientId;
@Column(name="USER_ID")
@Column(name="AUTH_USER_ID")
private String authUserId;
@Column(name="IP_ADDRESS")
@@ -59,6 +62,14 @@ public class AdminEventEntity {
this.time = time;
}
public String getRealmId() {
return realmId;
}
public void setRealmId(String realmId) {
this.realmId = realmId;
}
public String getOperationType() {
return operationType;
}
@@ -39,6 +39,12 @@ public class JpaAdminEventQuery implements AdminEventQuery {
root = cq.from(AdminEventEntity.class);
predicates = new ArrayList<Predicate>();
}
@Override
public AdminEventQuery realm(String realmId) {
predicates.add(cb.equal(root.get("realmId"), realmId));
return this;
}
@Override
public AdminEventQuery operation(OperationType... operations) {
@@ -51,20 +57,20 @@ public class JpaAdminEventQuery implements AdminEventQuery {
}
@Override
public AdminEventQuery authRealm(String realmId) {
predicates.add(cb.equal(root.get("authRealmId"), realmId));
public AdminEventQuery authRealm(String authRealmId) {
predicates.add(cb.equal(root.get("authRealmId"), authRealmId));
return this;
}
@Override
public AdminEventQuery authClient(String clientId) {
predicates.add(cb.equal(root.get("authClientId"), clientId));
public AdminEventQuery authClient(String authClientId) {
predicates.add(cb.equal(root.get("authClientId"), authClientId));
return this;
}
@Override
public AdminEventQuery authUser(String userId) {
predicates.add(cb.equal(root.get("authUserId"), userId));
public AdminEventQuery authUser(String authUserId) {
predicates.add(cb.equal(root.get("authUserId"), authUserId));
return this;
}
@@ -144,5 +150,5 @@ public class JpaAdminEventQuery implements AdminEventQuery {
return events;
}
}
@@ -70,13 +70,13 @@ public class JpaEventStoreProvider implements EventStoreProvider {
}
@Override
public void clearAdmin(String authRealmId) {
em.createQuery("delete from AdminEventEntity where authRealmId = :authRealmId").setParameter("authRealmId", authRealmId).executeUpdate();
public void clearAdmin(String realmId) {
em.createQuery("delete from AdminEventEntity where realmId = :realmId").setParameter("realmId", realmId).executeUpdate();
}
@Override
public void clearAdmin(String authRealmId, long olderThan) {
em.createQuery("delete from AdminEventEntity where authRealmId = :authRealmId and time < :time").setParameter("authRealmId", authRealmId).setParameter("time", olderThan).executeUpdate();
public void clearAdmin(String realmId, long olderThan) {
em.createQuery("delete from AdminEventEntity where realmId = :realmId and time < :time").setParameter("realmId", realmId).setParameter("time", olderThan).executeUpdate();
}
@Override
@@ -130,6 +130,7 @@ public class JpaEventStoreProvider implements EventStoreProvider {
AdminEventEntity adminEventEntity = new AdminEventEntity();
adminEventEntity.setId(UUID.randomUUID().toString());
adminEventEntity.setTime(adminEvent.getTime());
adminEventEntity.setRealmId(adminEvent.getRealmId());
setAuthDetails(adminEventEntity, adminEvent.getAuthDetails());
adminEventEntity.setOperationType(adminEvent.getOperationType().toString());
adminEventEntity.setResourcePath(adminEvent.getResourcePath());
@@ -144,6 +145,7 @@ public class JpaEventStoreProvider implements EventStoreProvider {
static AdminEvent convertAdminEvent(AdminEventEntity adminEventEntity) {
AdminEvent adminEvent = new AdminEvent();
adminEvent.setTime(adminEventEntity.getTime());
adminEvent.setRealmId(adminEventEntity.getRealmId());
setAuthDetails(adminEvent, adminEventEntity);
adminEvent.setOperationType(OperationType.valueOf(adminEventEntity.getOperationType()));
adminEvent.setResourcePath(adminEventEntity.getResourcePath());
@@ -26,6 +26,12 @@ public class MongoAdminEventQuery implements AdminEventQuery{
this.audit = audit;
query = new BasicDBObject();
}
@Override
public AdminEventQuery realm(String realmId) {
query.put("realmId", realmId);
return this;
}
@Override
public AdminEventQuery operation(OperationType... operations) {
@@ -38,26 +44,26 @@ public class MongoAdminEventQuery implements AdminEventQuery{
}
@Override
public AdminEventQuery authRealm(String realmId) {
query.put("realmId", realmId);
public AdminEventQuery authRealm(String authRealmId) {
query.put("authRealmId", authRealmId);
return this;
}
@Override
public AdminEventQuery authClient(String clientId) {
query.put("clientId", clientId);
public AdminEventQuery authClient(String authClientId) {
query.put("authClientId", authClientId);
return this;
}
@Override
public AdminEventQuery authUser(String userId) {
query.put("userId", userId);
public AdminEventQuery authUser(String authUserId) {
query.put("authUserId", authUserId);
return this;
}
@Override
public AdminEventQuery authIpAddress(String ipAddress) {
query.put("ipAddress", ipAddress);
query.put("authIpAddress", ipAddress);
return this;
}
@@ -122,5 +128,5 @@ public class MongoAdminEventQuery implements AdminEventQuery{
return events;
}
}
@@ -137,6 +137,7 @@ public class MongoEventStoreProvider implements EventStoreProvider {
private static DBObject convertAdminEvent(AdminEvent adminEvent, boolean includeRepresentation) {
BasicDBObject e = new BasicDBObject();
e.put("time", adminEvent.getTime());
e.put("realmId", adminEvent.getRealmId());
e.put("operationType", adminEvent.getOperationType().toString());
setAuthDetails(e, adminEvent.getAuthDetails());
e.put("resourcePath", adminEvent.getResourcePath());
@@ -152,6 +153,7 @@ public class MongoEventStoreProvider implements EventStoreProvider {
static AdminEvent convertAdminEvent(BasicDBObject o) {
AdminEvent adminEvent = new AdminEvent();
adminEvent.setTime(o.getLong("time"));
adminEvent.setRealmId(o.getString("realmId"));
adminEvent.setOperationType(OperationType.valueOf(o.getString("operationType")));
setAuthDetails(adminEvent, o);
adminEvent.setResourcePath(o.getString("resourcePath"));
@@ -164,18 +166,18 @@ public class MongoEventStoreProvider implements EventStoreProvider {
}
private static void setAuthDetails(BasicDBObject e, AuthDetails authDetails) {
e.put("realmId", authDetails.getRealmId());
e.put("clientId", authDetails.getClientId());
e.put("userId", authDetails.getUserId());
e.put("ipAddress", authDetails.getIpAddress());
e.put("authRealmId", authDetails.getRealmId());
e.put("authClientId", authDetails.getClientId());
e.put("authUserId", authDetails.getUserId());
e.put("authIpAddress", authDetails.getIpAddress());
}
private static void setAuthDetails(AdminEvent adminEvent, BasicDBObject o) {
AuthDetails authDetails = new AuthDetails();
authDetails.setRealmId(o.getString("realmId"));
authDetails.setClientId(o.getString("clientId"));
authDetails.setUserId(o.getString("userId"));
authDetails.setIpAddress(o.getString("ipAddress"));
authDetails.setRealmId(o.getString("authRealmId"));
authDetails.setClientId(o.getString("authClientId"));
authDetails.setUserId(o.getString("authUserId"));
authDetails.setIpAddress(o.getString("authIpAddress"));
adminEvent.setAuthDetails(authDetails);
}