KEYCLOAK-392 Admin events
This commit is contained in:
1 parent
962b623b4a
commit
96dad77c66
54 files changed
+502
-648
No files matched your search
@@ -13,10 +13,7 @@ public interface Details {
|
||||
String RESPONSE_TYPE = "response_type";
|
||||
String AUTH_METHOD = "auth_method";
|
||||
String IDENTITY_PROVIDER = "identity_provider";
|
||||
String IDENTITY_PROVIDER_IDENTITY = "identity_provider_identity";
|
||||
String IDENTITY_PROVIDER_ALIAS = "identity_provider_alias";
|
||||
String IDENTITY_PROVIDER_FACTORY = "identity_provider_factory";
|
||||
String IDENTITY_PROVIDER_FACTORY_IDENTITY = "identity_provider_factory_identity";
|
||||
String IDENTITY_PROVIDER_USERNAME = "identity_provider_identity";
|
||||
String REGISTER_METHOD = "register_method";
|
||||
String USERNAME = "username";
|
||||
String REMEMBER_ME = "remember_me";
|
||||
@@ -26,20 +23,10 @@ public interface Details {
|
||||
String UPDATED_REFRESH_TOKEN_ID = "updated_refresh_token_id";
|
||||
String NODE_HOST = "node_host";
|
||||
String REASON = "reason";
|
||||
|
||||
String REALM_ID = "realm_id";
|
||||
String REALM_NAME = "realm_name";
|
||||
String REALM_REQUIRED_SSL = "realm_required_ssl";
|
||||
|
||||
|
||||
String REALM = "realm";
|
||||
String REPRESENTATION = "representation";
|
||||
|
||||
String APPLICATION_CLUSTER_NODE = "application_cluster_node";
|
||||
|
||||
String ROLE_ID = "role_id";
|
||||
String ROLE_NAME = "role_name";
|
||||
|
||||
String PROVIDER_ID = "provider_id";
|
||||
String PROVIDER_NAME = "provider_name";
|
||||
|
||||
String SERVER_VERSION = "server_version";
|
||||
String SERVER_TIME = "server_time";
|
||||
|
||||
|
||||
}
|
||||
@@ -12,7 +12,7 @@ public class Event {
|
||||
|
||||
private EventType type;
|
||||
|
||||
private EventGroup eventGroup;
|
||||
private EventGroup group;
|
||||
|
||||
private String realmId;
|
||||
|
||||
@@ -26,6 +26,8 @@ public class Event {
|
||||
|
||||
private String error;
|
||||
|
||||
private String representation;
|
||||
|
||||
private Map<String, String> details;
|
||||
|
||||
public long getTime() {
|
||||
@@ -44,12 +46,12 @@ public class Event {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public EventGroup getEventGroup() {
|
||||
return eventGroup;
|
||||
public EventGroup getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setEventGroup(EventGroup group) {
|
||||
this.eventGroup = group;
|
||||
public void setGroup(EventGroup group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getRealmId() {
|
||||
@@ -100,6 +102,14 @@ public class Event {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getRepresentation() {
|
||||
return representation;
|
||||
}
|
||||
|
||||
public void setRepresentation(String representation) {
|
||||
this.representation = representation;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
}
|
||||
@@ -112,14 +122,15 @@ public class Event {
|
||||
Event clone = new Event();
|
||||
clone.time = time;
|
||||
clone.type = type;
|
||||
clone.eventGroup = eventGroup;
|
||||
clone.group = group;
|
||||
clone.realmId = realmId;
|
||||
clone.clientId = clientId;
|
||||
clone.userId = userId;
|
||||
clone.sessionId = sessionId;
|
||||
clone.ipAddress = ipAddress;
|
||||
clone.error = error;
|
||||
clone.details = details != null ? new HashMap<String, String>(details) : null;
|
||||
clone.details = details != null ? new HashMap<>(details) : null;
|
||||
clone.representation = representation;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
package org.keycloak.events;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.ClientConnection;
|
||||
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.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
@@ -18,30 +20,48 @@ import org.keycloak.models.UserSessionModel;
|
||||
public class EventBuilder {
|
||||
|
||||
private static final Logger log = Logger.getLogger(EventBuilder.class);
|
||||
|
||||
// These events are excluded by default and not persisted.
|
||||
private EventType[] events = {EventType.VIEW_REALM,
|
||||
EventType.VIEW_REALM_APPLICATIONS, EventType.VIEW_APPLICATION, EventType.VIEW_APPLICATION_USER_SESSIONS,
|
||||
EventType.VIEW_IDENTITY_PROVIDER, EventType.VIEW_IDENTITY_PROVIDERS, EventType.VIEW_OAUTH_CLIENT,
|
||||
EventType.VIEW_OAUTH_CLIENTS, EventType.VIEW_PROVIDER, EventType.VIEW_PROVIDER_FACTORIES, EventType.VIEW_USER,
|
||||
EventType.VIEW_USER_SESSIONS, EventType.VIEW_USER_SOCIAL_LOGINS, EventType.VIEW_ROLE, EventType.VIEW_ROLES,
|
||||
EventType.VIEW_CLIENT_CERTIFICATE, EventType.VIEW_SERVER_INFO };
|
||||
|
||||
private Event event;
|
||||
private List<EventListenerProvider> listeners;
|
||||
private Set<EventType> enabledEventTypes;
|
||||
private Set<EventType> excludedEvents = new HashSet<EventType>(Arrays.asList(events));;
|
||||
|
||||
public EventBuilder(List<EventListenerProvider> listeners, Set<EventType> enabledEventTypes, RealmModel realm, String ipAddress) {
|
||||
this.listeners = listeners;
|
||||
this.enabledEventTypes = enabledEventTypes;
|
||||
this.event = new Event();
|
||||
private EventStoreProvider store;
|
||||
private List<EventListenerProvider> listeners;
|
||||
private RealmModel realm;
|
||||
private Event event;
|
||||
|
||||
public EventBuilder(EventGroup group, RealmModel realm, KeycloakSession session, ClientConnection clientConnection) {
|
||||
this.realm = realm;
|
||||
|
||||
event = new Event();
|
||||
event.setGroup(group);
|
||||
|
||||
if (realm.isEventsEnabled()) {
|
||||
EventStoreProvider store = session.getProvider(EventStoreProvider.class);
|
||||
if (store != null) {
|
||||
this.store = store;
|
||||
} else {
|
||||
log.error("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(ipAddress);
|
||||
ipAddress(clientConnection.getRemoteAddr());
|
||||
}
|
||||
|
||||
EventBuilder() {
|
||||
private EventBuilder(EventStoreProvider store, List<EventListenerProvider> listeners, RealmModel realm, Event event) {
|
||||
this.store = store;
|
||||
this.listeners = listeners;
|
||||
this.realm = realm;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public EventBuilder realm(RealmModel realm) {
|
||||
@@ -94,11 +114,6 @@ public class EventBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventBuilder eventGroup(EventGroup e) {
|
||||
event.setEventGroup(e);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EventBuilder detail(String key, String value) {
|
||||
if (value == null || value.equals("")) {
|
||||
return this;
|
||||
@@ -107,9 +122,18 @@ public class EventBuilder {
|
||||
if (event.getDetails() == null) {
|
||||
event.setDetails(new HashMap<String, String>());
|
||||
}
|
||||
event.getDetails().put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (value != null && !value.isEmpty()) {
|
||||
event.getDetails().put(key, value);
|
||||
public EventBuilder representation(Object value) {
|
||||
if (value == null || value.equals("")) {
|
||||
return this;
|
||||
}
|
||||
try {
|
||||
event.setRepresentation(JsonSerialization.writeValueAsPrettyString(value));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -136,37 +160,26 @@ public class EventBuilder {
|
||||
}
|
||||
|
||||
public EventBuilder clone() {
|
||||
EventBuilder clone = new EventBuilder();
|
||||
clone.listeners = listeners;
|
||||
clone.event = event.clone();
|
||||
return clone;
|
||||
}
|
||||
|
||||
public EventBuilder reset() {
|
||||
Event old = event;
|
||||
|
||||
event = new Event();
|
||||
event.setRealmId(old.getRealmId());
|
||||
event.setIpAddress(old.getIpAddress());
|
||||
event.setClientId(old.getClientId());
|
||||
event.setUserId(old.getUserId());
|
||||
|
||||
return this;
|
||||
return new EventBuilder(store, listeners, realm, event.clone());
|
||||
}
|
||||
|
||||
private void send() {
|
||||
event.setTime(System.currentTimeMillis());
|
||||
|
||||
if (store != null) {
|
||||
if (realm.getEnabledEventTypes() != null && !realm.getEnabledEventTypes().isEmpty() ? realm.getEnabledEventTypes().contains(event.getType().name()) : event.getType().isSaveByDefault()) {
|
||||
try {
|
||||
store.onEvent(event);
|
||||
} catch (Throwable t) {
|
||||
log.error("Failed to save event", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (listeners != null) {
|
||||
for (EventListenerProvider l : listeners) {
|
||||
try {
|
||||
if (enabledEventTypes != null && enabledEventTypes.size() > 0) {
|
||||
if (enabledEventTypes.contains(event.getType())) {
|
||||
l.onEvent(event);
|
||||
}
|
||||
} else if (!excludedEvents.contains(event.getType())) {
|
||||
l.onEvent(event);
|
||||
}
|
||||
l.onEvent(event);
|
||||
} catch (Throwable t) {
|
||||
log.error("Failed to send type to " + l, t);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package org.keycloak.events;
|
||||
public enum EventGroup {
|
||||
|
||||
ADMIN,
|
||||
USER,
|
||||
EMAIL,
|
||||
USER
|
||||
|
||||
}
|
||||
@@ -5,119 +5,125 @@ package org.keycloak.events;
|
||||
*/
|
||||
public enum EventType {
|
||||
|
||||
LOGIN,
|
||||
LOGIN_ERROR,
|
||||
REGISTER,
|
||||
REGISTER_ERROR,
|
||||
LOGOUT,
|
||||
LOGOUT_ERROR,
|
||||
CODE_TO_TOKEN,
|
||||
CODE_TO_TOKEN_ERROR,
|
||||
REFRESH_TOKEN,
|
||||
VALIDATE_ACCESS_TOKEN,
|
||||
VALIDATE_ACCESS_TOKEN_ERROR,
|
||||
REFRESH_TOKEN_ERROR,
|
||||
SOCIAL_LINK,
|
||||
SOCIAL_LINK_ERROR,
|
||||
REMOVE_FEDERATED_IDENTITY,
|
||||
REMOVE_SOCIAL_LINK_ERROR,
|
||||
LOGIN(true),
|
||||
LOGIN_ERROR(true),
|
||||
REGISTER(true),
|
||||
REGISTER_ERROR(true),
|
||||
LOGOUT(true),
|
||||
LOGOUT_ERROR(true),
|
||||
|
||||
UPDATE_EMAIL,
|
||||
UPDATE_EMAIL_ERROR,
|
||||
UPDATE_PROFILE,
|
||||
UPDATE_PROFILE_ERROR,
|
||||
UPDATE_PASSWORD,
|
||||
UPDATE_PASSWORD_ERROR,
|
||||
UPDATE_TOTP,
|
||||
UPDATE_TOTP_ERROR,
|
||||
VERIFY_EMAIL,
|
||||
VERIFY_EMAIL_ERROR,
|
||||
CODE_TO_TOKEN(true),
|
||||
CODE_TO_TOKEN_ERROR(true),
|
||||
|
||||
REMOVE_TOTP,
|
||||
REMOVE_TOTP_ERROR,
|
||||
REFRESH_TOKEN(false),
|
||||
REFRESH_TOKEN_ERROR(false),
|
||||
VALIDATE_ACCESS_TOKEN(false),
|
||||
VALIDATE_ACCESS_TOKEN_ERROR(false),
|
||||
|
||||
SEND_VERIFY_EMAIL,
|
||||
SEND_VERIFY_EMAIL_ERROR,
|
||||
SEND_RESET_PASSWORD,
|
||||
SEND_RESET_PASSWORD_ERROR,
|
||||
RESET_PASSWORD,
|
||||
RESET_PASSWORD_ERROR,
|
||||
FEDERATED_IDENTITY_LINK(true),
|
||||
FEDERATED_IDENTITY_LINK_ERROR(true),
|
||||
REMOVE_FEDERATED_IDENTITY(true),
|
||||
REMOVE_FEDERATED_IDENTITY_ERROR(true),
|
||||
|
||||
INVALID_SIGNATURE_ERROR,
|
||||
REGISTER_NODE,
|
||||
UNREGISTER_NODE,
|
||||
UPDATE_EMAIL(true),
|
||||
UPDATE_EMAIL_ERROR(true),
|
||||
UPDATE_PROFILE(true),
|
||||
UPDATE_PROFILE_ERROR(true),
|
||||
UPDATE_PASSWORD(true),
|
||||
UPDATE_PASSWORD_ERROR(true),
|
||||
UPDATE_TOTP(true),
|
||||
UPDATE_TOTP_ERROR(true),
|
||||
VERIFY_EMAIL(true),
|
||||
VERIFY_EMAIL_ERROR(true),
|
||||
|
||||
USER_INFO_REQUEST,
|
||||
USER_INFO_REQUEST_ERROR,
|
||||
REMOVE_TOTP(true),
|
||||
REMOVE_TOTP_ERROR(true),
|
||||
|
||||
IDENTITY_PROVIDER_LOGIN,
|
||||
IDENTITY_PROVIDER_LOGIN_ERROR,
|
||||
IDENTITY_PROVIDER_RESPONSE,
|
||||
IDENTITY_PROVIDER_RESPONSE_ERROR,
|
||||
IDENTITY_PROVIDER_RETRIEVE_TOKEN,
|
||||
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR,
|
||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING,
|
||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING_ERROR,
|
||||
SEND_VERIFY_EMAIL(true),
|
||||
SEND_VERIFY_EMAIL_ERROR(true),
|
||||
SEND_RESET_PASSWORD(true),
|
||||
SEND_RESET_PASSWORD_ERROR(true),
|
||||
RESET_PASSWORD(true),
|
||||
RESET_PASSWORD_ERROR(true),
|
||||
|
||||
INVALID_SIGNATURE_ERROR(false),
|
||||
REGISTER_NODE(false),
|
||||
UNREGISTER_NODE(false),
|
||||
|
||||
USER_INFO_REQUEST(false),
|
||||
USER_INFO_REQUEST_ERROR(false),
|
||||
|
||||
IDENTITY_PROVIDER_LOGIN(false),
|
||||
IDENTITY_PROVIDER_LOGIN_ERROR(false),
|
||||
IDENTITY_PROVIDER_RESPONSE(false),
|
||||
IDENTITY_PROVIDER_RESPONSE_ERROR(false),
|
||||
IDENTITY_PROVIDER_RETRIEVE_TOKEN(false),
|
||||
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR(false),
|
||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING(false),
|
||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING_ERROR(false),
|
||||
|
||||
VIEW_REALM,
|
||||
UPDATE_REALM,
|
||||
DELETE_REALM,
|
||||
IMPORT_REALM,
|
||||
UPLOAD_REALM,
|
||||
VIEW_REALM_APPLICATIONS,
|
||||
SET_REALM_USER_PERMISSIONS,
|
||||
SET_REALM_ADAPTER_CONFIGURATION,
|
||||
VIEW_REALM(false),
|
||||
CREATE_REALM(false),
|
||||
UPDATE_REALM(false),
|
||||
DELETE_REALM(false),
|
||||
|
||||
VIEW_APPLICATIONS(false),
|
||||
VIEW_APPLICATION(false),
|
||||
CREATE_APPLICATION(false),
|
||||
UPDATE_APPLICATION(false),
|
||||
DELETE_APPLICATION(false),
|
||||
|
||||
CREATE_APPLICATION,
|
||||
UPDATE_APPLICATION,
|
||||
VIEW_APPLICATION,
|
||||
DELETE_APPLICATION,
|
||||
|
||||
VIEW_APPLICATION_USER_SESSIONS,
|
||||
INVALIDATE_APPLICATION_USER_SESSIONS,
|
||||
INVALIDATE_APPLICATION_USER_SESSION,
|
||||
REGISTER_APPLICATION_CLUSTER_NODE,
|
||||
UNREGISTER_APPLICATION_CLUSTER_NODE,
|
||||
|
||||
VIEW_CLIENT_CERTIFICATE,
|
||||
GENERATE_CLIENT_CERTIFICATE,
|
||||
UPLOAD_CLIENT_CERTIFICATE,
|
||||
DOWNLOAD_CLIENT_CERTIFICATE,
|
||||
|
||||
VIEW_IDENTITY_PROVIDER,
|
||||
VIEW_IDENTITY_PROVIDERS,
|
||||
IMPORT_IDENTITY_PROVIDER_CONFIG,
|
||||
CREATE_IDENTITY_PROVIDER,
|
||||
UPDATE_IDENTITY_PROVIDER,
|
||||
DELETE_IDENTITY_PROVIDER,
|
||||
|
||||
CREATE_OAUTH_CLIENT,
|
||||
UPDATE_OAUTH_CLIENT,
|
||||
VIEW_OAUTH_CLIENT,
|
||||
VIEW_OAUTH_CLIENTS,
|
||||
DELETE_OAUTH_CLIENT,
|
||||
|
||||
VIEW_ROLE,
|
||||
VIEW_ROLES,
|
||||
CREATE_ROLE,
|
||||
UPDATE_ROLE,
|
||||
DELETE_ROLE,
|
||||
MAKE_ROLE_COMPOSITE,
|
||||
|
||||
UPDATE_USER,
|
||||
CREATE_USER,
|
||||
VIEW_USER,
|
||||
DELETE_USER,
|
||||
VIEW_USER_SESSIONS,
|
||||
VIEW_USER_SOCIAL_LOGINS,
|
||||
INVALIDATE_USER_SESSIONS,
|
||||
|
||||
CREATE_PROVIDER,
|
||||
VIEW_PROVIDER,
|
||||
VIEW_PROVIDER_FACTORIES,
|
||||
UPDATE_PROVIDER,
|
||||
DELETE_PROVIDER,
|
||||
|
||||
VIEW_SERVER_INFO,
|
||||
VIEW_APPLICATION_USER_SESSIONS(false),
|
||||
LOGOUT_APPLICATION_USERS(false),
|
||||
LOGOUT_USER(false),
|
||||
|
||||
REGISTER_APPLICATION_CLUSTER_NODE(false),
|
||||
UNREGISTER_APPLICATION_CLUSTER_NODE(false),
|
||||
|
||||
VIEW_CLIENT_CERTIFICATE(false),
|
||||
UPDATE_CLIENT_CERTIFICATE(false),
|
||||
|
||||
VIEW_IDENTITY_PROVIDERS(false),
|
||||
VIEW_IDENTITY_PROVIDER(false),
|
||||
CREATE_IDENTITY_PROVIDER(false),
|
||||
UPDATE_IDENTITY_PROVIDER(false),
|
||||
DELETE_IDENTITY_PROVIDER(false),
|
||||
|
||||
VIEW_OAUTH_CLIENTS(false),
|
||||
VIEW_OAUTH_CLIENT(false),
|
||||
CREATE_OAUTH_CLIENT(false),
|
||||
UPDATE_OAUTH_CLIENT(false),
|
||||
DELETE_OAUTH_CLIENT(false),
|
||||
|
||||
VIEW_ROLES(false),
|
||||
VIEW_ROLE(false),
|
||||
CREATE_ROLE(false),
|
||||
UPDATE_ROLE(false),
|
||||
DELETE_ROLE(false),
|
||||
|
||||
VIEW_USERS(false),
|
||||
VIEW_USER(false),
|
||||
CREATE_USER(false),
|
||||
UPDATE_USER(false),
|
||||
DELETE_USER(false),
|
||||
|
||||
VIEW_USER_SESSIONS(false),
|
||||
LOGOUT_USER_SESSIONS(false),
|
||||
|
||||
VIEW_FEDERATION_PROVIDERS(false),
|
||||
VIEW_FEDERATION_PROVIDER(false),
|
||||
CREATE_FEDERATION_PROVIDER(false),
|
||||
UPDATE_FEDERATION_PROVIDER(false),
|
||||
DELETE_FEDERATION_PROVIDER(false);
|
||||
|
||||
private boolean saveByDefault;
|
||||
|
||||
EventType(boolean saveByDefault) {
|
||||
this.saveByDefault = saveByDefault;
|
||||
}
|
||||
|
||||
public boolean isSaveByDefault() {
|
||||
return saveByDefault;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user