[KEYCLOAK-392] - Admin audit events
This commit is contained in:
parent
f8b25cad7f
commit
962b623b4a
57 changed files with 797 additions and 144 deletions
|
@ -92,6 +92,7 @@
|
||||||
<column name="SESSION_ID" type="VARCHAR(255)"/>
|
<column name="SESSION_ID" type="VARCHAR(255)"/>
|
||||||
<column name="TIME" type="BIGINT"/>
|
<column name="TIME" type="BIGINT"/>
|
||||||
<column name="TYPE" type="VARCHAR(255)"/>
|
<column name="TYPE" type="VARCHAR(255)"/>
|
||||||
|
<column name="EVENT_GROUP" type="VARCHAR(255)"/>
|
||||||
<column name="USER_ID" type="VARCHAR(255)"/>
|
<column name="USER_ID" type="VARCHAR(255)"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
<createTable tableName="FED_PROVIDERS">
|
<createTable tableName="FED_PROVIDERS">
|
||||||
|
@ -196,6 +197,12 @@
|
||||||
</column>
|
</column>
|
||||||
<column name="VALUE" type="VARCHAR(255)"/>
|
<column name="VALUE" type="VARCHAR(255)"/>
|
||||||
</createTable>
|
</createTable>
|
||||||
|
<createTable tableName="REALM_ENABLED_EVENT_TYPES">
|
||||||
|
<column name="REALM_ID" type="VARCHAR(36)">
|
||||||
|
<constraints nullable="false"/>
|
||||||
|
</column>
|
||||||
|
<column name="VALUE" type="VARCHAR(255)"/>
|
||||||
|
</createTable>
|
||||||
<createTable tableName="REALM_REQUIRED_CREDENTIAL">
|
<createTable tableName="REALM_REQUIRED_CREDENTIAL">
|
||||||
<column name="TYPE" type="VARCHAR(255)">
|
<column name="TYPE" type="VARCHAR(255)">
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
|
@ -405,6 +412,7 @@
|
||||||
<addForeignKeyConstraint baseColumnNames="CHILD_ROLE" baseTableName="COMPOSITE_ROLE" constraintName="FK_GR7THLLB9LU8Q4VQA4524JJY8" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
<addForeignKeyConstraint baseColumnNames="CHILD_ROLE" baseTableName="COMPOSITE_ROLE" constraintName="FK_GR7THLLB9LU8Q4VQA4524JJY8" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="REALM_DEFAULT_ROLES" constraintName="FK_H4WPD7W4HSOOLNI3H0SW7BTJE" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
<addForeignKeyConstraint baseColumnNames="ROLE_ID" baseTableName="REALM_DEFAULT_ROLES" constraintName="FK_H4WPD7W4HSOOLNI3H0SW7BTJE" referencedColumnNames="ID" referencedTableName="KEYCLOAK_ROLE"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_EVENTS_LISTENERS" constraintName="FK_H846O4H0W8EPX5NXEV9F5Y69J" referencedColumnNames="ID" referencedTableName="REALM"/>
|
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_EVENTS_LISTENERS" constraintName="FK_H846O4H0W8EPX5NXEV9F5Y69J" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||||
|
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_ENABLED_EVENT_TYPES" constraintName="FK_H846O4H0W8EPX5NWEDRF5Y69J" referencedColumnNames="ID" referencedTableName="REALM"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_APPLICATION" constraintName="FK_L5QGA3RFME47335JY8JXYXH3I" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
<addForeignKeyConstraint baseColumnNames="REALM_ID" baseTableName="REALM_APPLICATION" constraintName="FK_L5QGA3RFME47335JY8JXYXH3I" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="WEB_ORIGINS" constraintName="FK_LOJPHO213XCX4WNKOG82SSRFY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
<addForeignKeyConstraint baseColumnNames="CLIENT_ID" baseTableName="WEB_ORIGINS" constraintName="FK_LOJPHO213XCX4WNKOG82SSRFY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||||
<addForeignKeyConstraint baseColumnNames="APPLICATION_ID" baseTableName="APPLICATION_DEFAULT_ROLES" constraintName="FK_MAYLTS7KLWQW2H8M2B5JOYTKY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
<addForeignKeyConstraint baseColumnNames="APPLICATION_ID" baseTableName="APPLICATION_DEFAULT_ROLES" constraintName="FK_MAYLTS7KLWQW2H8M2B5JOYTKY" referencedColumnNames="ID" referencedTableName="CLIENT"/>
|
||||||
|
|
|
@ -10,6 +10,7 @@ public class RealmEventsConfigRepresentation {
|
||||||
protected boolean eventsEnabled;
|
protected boolean eventsEnabled;
|
||||||
protected Long eventsExpiration;
|
protected Long eventsExpiration;
|
||||||
protected List<String> eventsListeners;
|
protected List<String> eventsListeners;
|
||||||
|
protected List<String> enabledEventTypes;
|
||||||
|
|
||||||
public boolean isEventsEnabled() {
|
public boolean isEventsEnabled() {
|
||||||
return eventsEnabled;
|
return eventsEnabled;
|
||||||
|
@ -34,4 +35,12 @@ public class RealmEventsConfigRepresentation {
|
||||||
public void setEventsListeners(List<String> eventsListeners) {
|
public void setEventsListeners(List<String> eventsListeners) {
|
||||||
this.eventsListeners = eventsListeners;
|
this.eventsListeners = eventsListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getEnabledEventTypes() {
|
||||||
|
return enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabledEventTypes(List<String> enabledEventTypes) {
|
||||||
|
this.enabledEventTypes = enabledEventTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ public class RealmRepresentation {
|
||||||
protected Boolean eventsEnabled;
|
protected Boolean eventsEnabled;
|
||||||
protected Long eventsExpiration;
|
protected Long eventsExpiration;
|
||||||
protected List<String> eventsListeners;
|
protected List<String> eventsListeners;
|
||||||
|
protected List<String> enabledEventTypes;
|
||||||
private List<IdentityProviderRepresentation> identityProviders;
|
private List<IdentityProviderRepresentation> identityProviders;
|
||||||
private List<ProtocolMapperRepresentation> protocolMappers;
|
private List<ProtocolMapperRepresentation> protocolMappers;
|
||||||
private Boolean identityFederationEnabled;
|
private Boolean identityFederationEnabled;
|
||||||
|
@ -504,6 +505,14 @@ public class RealmRepresentation {
|
||||||
this.eventsListeners = eventsListeners;
|
this.eventsListeners = eventsListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getEnabledEventTypes() {
|
||||||
|
return enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabledEventTypes(List<String> enabledEventTypes) {
|
||||||
|
this.enabledEventTypes = enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public List<UserFederationProviderRepresentation> getUserFederationProviders() {
|
public List<UserFederationProviderRepresentation> getUserFederationProviders() {
|
||||||
return userFederationProviders;
|
return userFederationProviders;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,9 @@ public interface Details {
|
||||||
String AUTH_METHOD = "auth_method";
|
String AUTH_METHOD = "auth_method";
|
||||||
String IDENTITY_PROVIDER = "identity_provider";
|
String IDENTITY_PROVIDER = "identity_provider";
|
||||||
String IDENTITY_PROVIDER_IDENTITY = "identity_provider_identity";
|
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 REGISTER_METHOD = "register_method";
|
String REGISTER_METHOD = "register_method";
|
||||||
String USERNAME = "username";
|
String USERNAME = "username";
|
||||||
String REMEMBER_ME = "remember_me";
|
String REMEMBER_ME = "remember_me";
|
||||||
|
@ -23,4 +26,20 @@ public interface Details {
|
||||||
String UPDATED_REFRESH_TOKEN_ID = "updated_refresh_token_id";
|
String UPDATED_REFRESH_TOKEN_ID = "updated_refresh_token_id";
|
||||||
String NODE_HOST = "node_host";
|
String NODE_HOST = "node_host";
|
||||||
String REASON = "reason";
|
String REASON = "reason";
|
||||||
|
|
||||||
|
String REALM_ID = "realm_id";
|
||||||
|
String REALM_NAME = "realm_name";
|
||||||
|
String REALM_REQUIRED_SSL = "realm_required_ssl";
|
||||||
|
|
||||||
|
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,6 +12,8 @@ public class Event {
|
||||||
|
|
||||||
private EventType type;
|
private EventType type;
|
||||||
|
|
||||||
|
private EventGroup eventGroup;
|
||||||
|
|
||||||
private String realmId;
|
private String realmId;
|
||||||
|
|
||||||
private String clientId;
|
private String clientId;
|
||||||
|
@ -42,6 +44,14 @@ public class Event {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EventGroup getEventGroup() {
|
||||||
|
return eventGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventGroup(EventGroup group) {
|
||||||
|
this.eventGroup = group;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRealmId() {
|
public String getRealmId() {
|
||||||
return realmId;
|
return realmId;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +112,7 @@ public class Event {
|
||||||
Event clone = new Event();
|
Event clone = new Event();
|
||||||
clone.time = time;
|
clone.time = time;
|
||||||
clone.type = type;
|
clone.type = type;
|
||||||
|
clone.eventGroup = eventGroup;
|
||||||
clone.realmId = realmId;
|
clone.realmId = realmId;
|
||||||
clone.clientId = clientId;
|
clone.clientId = clientId;
|
||||||
clone.userId = userId;
|
clone.userId = userId;
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package org.keycloak.events;
|
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.jboss.logging.Logger;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
*/
|
*/
|
||||||
|
@ -16,11 +19,22 @@ public class EventBuilder {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(EventBuilder.class);
|
private static final Logger log = Logger.getLogger(EventBuilder.class);
|
||||||
|
|
||||||
private List<EventListenerProvider> listeners;
|
// These events are excluded by default and not persisted.
|
||||||
private Event event;
|
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 };
|
||||||
|
|
||||||
public EventBuilder(List<EventListenerProvider> listeners, RealmModel realm, String ipAddress) {
|
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.listeners = listeners;
|
||||||
|
this.enabledEventTypes = enabledEventTypes;
|
||||||
this.event = new Event();
|
this.event = new Event();
|
||||||
|
|
||||||
realm(realm);
|
realm(realm);
|
||||||
|
@ -80,6 +94,11 @@ public class EventBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EventBuilder eventGroup(EventGroup e) {
|
||||||
|
event.setEventGroup(e);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public EventBuilder detail(String key, String value) {
|
public EventBuilder detail(String key, String value) {
|
||||||
if (value == null || value.equals("")) {
|
if (value == null || value.equals("")) {
|
||||||
return this;
|
return this;
|
||||||
|
@ -88,7 +107,10 @@ public class EventBuilder {
|
||||||
if (event.getDetails() == null) {
|
if (event.getDetails() == null) {
|
||||||
event.setDetails(new HashMap<String, String>());
|
event.setDetails(new HashMap<String, String>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
event.getDetails().put(key, value);
|
event.getDetails().put(key, value);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +160,13 @@ public class EventBuilder {
|
||||||
if (listeners != null) {
|
if (listeners != null) {
|
||||||
for (EventListenerProvider l : listeners) {
|
for (EventListenerProvider l : listeners) {
|
||||||
try {
|
try {
|
||||||
|
if (enabledEventTypes != null && enabledEventTypes.size() > 0) {
|
||||||
|
if (enabledEventTypes.contains(event.getType())) {
|
||||||
l.onEvent(event);
|
l.onEvent(event);
|
||||||
|
}
|
||||||
|
} else if (!excludedEvents.contains(event.getType())) {
|
||||||
|
l.onEvent(event);
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
log.error("Failed to send type to " + l, t);
|
log.error("Failed to send type to " + l, t);
|
||||||
}
|
}
|
||||||
|
|
12
events/api/src/main/java/org/keycloak/events/EventGroup.java
Normal file
12
events/api/src/main/java/org/keycloak/events/EventGroup.java
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package org.keycloak.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:giriraj.sharma27@gmail.com">Giriraj Sharma</a>
|
||||||
|
*/
|
||||||
|
public enum EventGroup {
|
||||||
|
|
||||||
|
ADMIN,
|
||||||
|
USER,
|
||||||
|
EMAIL,
|
||||||
|
|
||||||
|
}
|
|
@ -58,4 +58,66 @@ public enum EventType {
|
||||||
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR,
|
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR,
|
||||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING,
|
IDENTITY_PROVIDER_ACCCOUNT_LINKING,
|
||||||
IDENTITY_PROVIDER_ACCCOUNT_LINKING_ERROR,
|
IDENTITY_PROVIDER_ACCCOUNT_LINKING_ERROR,
|
||||||
|
|
||||||
|
VIEW_REALM,
|
||||||
|
UPDATE_REALM,
|
||||||
|
DELETE_REALM,
|
||||||
|
IMPORT_REALM,
|
||||||
|
UPLOAD_REALM,
|
||||||
|
VIEW_REALM_APPLICATIONS,
|
||||||
|
SET_REALM_USER_PERMISSIONS,
|
||||||
|
SET_REALM_ADAPTER_CONFIGURATION,
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,9 @@ public class EventEntity {
|
||||||
@Column(name="TYPE")
|
@Column(name="TYPE")
|
||||||
private String type;
|
private String type;
|
||||||
|
|
||||||
|
@Column(name="EVENT_GROUP")
|
||||||
|
private String eventGroup;
|
||||||
|
|
||||||
@Column(name="REALM_ID")
|
@Column(name="REALM_ID")
|
||||||
private String realmId;
|
private String realmId;
|
||||||
|
|
||||||
|
@ -67,6 +70,14 @@ public class EventEntity {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getEventGroup() {
|
||||||
|
return eventGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventGroup(String eventGroup) {
|
||||||
|
this.eventGroup = eventGroup;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRealmId() {
|
public String getRealmId() {
|
||||||
return realmId;
|
return realmId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,14 @@ import org.codehaus.jackson.map.ObjectMapper;
|
||||||
import org.codehaus.jackson.type.TypeReference;
|
import org.codehaus.jackson.type.TypeReference;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventQuery;
|
import org.keycloak.events.EventQuery;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityTransaction;
|
import javax.persistence.EntityTransaction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -70,6 +72,7 @@ public class JpaEventStoreProvider implements EventStoreProvider {
|
||||||
e.setId(UUID.randomUUID().toString());
|
e.setId(UUID.randomUUID().toString());
|
||||||
e.setTime(o.getTime());
|
e.setTime(o.getTime());
|
||||||
e.setType(o.getType().toString());
|
e.setType(o.getType().toString());
|
||||||
|
e.setEventGroup(o.getEventGroup().toString());
|
||||||
e.setRealmId(o.getRealmId());
|
e.setRealmId(o.getRealmId());
|
||||||
e.setClientId(o.getClientId());
|
e.setClientId(o.getClientId());
|
||||||
e.setUserId(o.getUserId());
|
e.setUserId(o.getUserId());
|
||||||
|
@ -88,6 +91,7 @@ public class JpaEventStoreProvider implements EventStoreProvider {
|
||||||
Event e = new Event();
|
Event e = new Event();
|
||||||
e.setTime(o.getTime());
|
e.setTime(o.getTime());
|
||||||
e.setType(EventType.valueOf(o.getType()));
|
e.setType(EventType.valueOf(o.getType()));
|
||||||
|
e.setEventGroup(EventGroup.valueOf(o.getEventGroup()));
|
||||||
e.setRealmId(o.getRealmId());
|
e.setRealmId(o.getRealmId());
|
||||||
e.setClientId(o.getClientId());
|
e.setClientId(o.getClientId());
|
||||||
e.setUserId(o.getUserId());
|
e.setUserId(o.getUserId());
|
||||||
|
|
|
@ -3,7 +3,9 @@ package org.keycloak.events.mongo;
|
||||||
import com.mongodb.BasicDBObject;
|
import com.mongodb.BasicDBObject;
|
||||||
import com.mongodb.DBCollection;
|
import com.mongodb.DBCollection;
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
|
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventQuery;
|
import org.keycloak.events.EventQuery;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
@ -63,6 +65,7 @@ public class MongoEventStoreProvider implements EventStoreProvider {
|
||||||
BasicDBObject e = new BasicDBObject();
|
BasicDBObject e = new BasicDBObject();
|
||||||
e.put("time", o.getTime());
|
e.put("time", o.getTime());
|
||||||
e.put("type", o.getType().toString());
|
e.put("type", o.getType().toString());
|
||||||
|
e.put("group", o.getEventGroup().toString());
|
||||||
e.put("realmId", o.getRealmId());
|
e.put("realmId", o.getRealmId());
|
||||||
e.put("clientId", o.getClientId());
|
e.put("clientId", o.getClientId());
|
||||||
e.put("userId", o.getUserId());
|
e.put("userId", o.getUserId());
|
||||||
|
@ -85,6 +88,7 @@ public class MongoEventStoreProvider implements EventStoreProvider {
|
||||||
Event e = new Event();
|
Event e = new Event();
|
||||||
e.setTime(o.getLong("time"));
|
e.setTime(o.getLong("time"));
|
||||||
e.setType(EventType.valueOf(o.getString("type")));
|
e.setType(EventType.valueOf(o.getString("type")));
|
||||||
|
e.setEventGroup(EventGroup.valueOf(o.getString("group")));
|
||||||
e.setRealmId(o.getString("realmId"));
|
e.setRealmId(o.getString("realmId"));
|
||||||
e.setClientId(o.getString("clientId"));
|
e.setClientId(o.getString("clientId"));
|
||||||
e.setUserId(o.getString("userId"));
|
e.setUserId(o.getString("userId"));
|
||||||
|
|
|
@ -1239,6 +1239,19 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
|
||||||
|
|
||||||
$scope.eventListeners = serverInfo.eventListeners;
|
$scope.eventListeners = serverInfo.eventListeners;
|
||||||
|
|
||||||
|
// Admin can choose any number of these eventTypes for persistence.
|
||||||
|
// By default, admin view events are not persisted.
|
||||||
|
$scope.enabledEventTypes = [{tag:'LOGIN'}, {tag:'REGISTER'}, {tag:'LOGOUT'}, {tag:'CODE_TO_TOKEN'},
|
||||||
|
{tag:'REFRESH_TOKEN'}, {tag:'VALIDATE_ACCESS_TOKEN'}, {tag:'LOGIN_ERROR'}, {tag:'REGISTER_ERROR'},
|
||||||
|
{tag:'LOGOUT_ERROR'}, {tag:'CODE_TO_TOKEN_ERROR'}, {tag:'REFRESH_TOKEN_ERROR'}, {tag:'VALIDATE_ACCESS_TOKEN_ERROR'},
|
||||||
|
{tag:'UPDATE_EMAIL'}, {tag:'UPDATE_PROFILE'}, {tag:'UPDATE_PASSWORD'}, {tag:'UPDATE_TOTP'},
|
||||||
|
{tag:'UPLOAD_REALM'}, {tag:'IMPORT_REALM'}, {tag:'UPDATE_REALM'}, {tag:'DELETE_REALM'},
|
||||||
|
{tag:'CREATE_USER'}, {tag:'UPDATE_USER'}, {tag:'DELETE_USER'}, {tag:'VIEW_USER_SESSIONS'},
|
||||||
|
{tag:'CREATE_APPLICATION'}, {tag:'UPDATE_APPLICATION'}, {tag:'DELETE_APPLICATION'}, {tag:'VIEW_APPLICATION'},
|
||||||
|
{tag:'CREATE_OAUTH_CLIENT'}, {tag:'UPDATE_OAUTH_CLIENT'}, {tag:'VIEW_OAUTH_CLIENT'}, {tag:'DELETE_OAUTH_CLIENT'},
|
||||||
|
{tag:'CREATE_PROVIDER'}, {tag:'UPDATE_PROVIDER'}, {tag:'DELETE_PROVIDER'}, {tag:'VIEW_ROLE'},
|
||||||
|
{tag:'CREATE_ROLE'}, {tag:'UPDATE_ROLE'}, {tag:'DELETE_ROLE'}, {tag:'VIEW_SERVER_INFO'}]
|
||||||
|
|
||||||
var oldCopy = angular.copy($scope.eventsConfig);
|
var oldCopy = angular.copy($scope.eventsConfig);
|
||||||
$scope.changed = false;
|
$scope.changed = false;
|
||||||
|
|
||||||
|
@ -1282,10 +1295,18 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm) {
|
||||||
$scope.realm = realm;
|
$scope.realm = realm;
|
||||||
$scope.page = 0;
|
$scope.page = 0;
|
||||||
|
|
||||||
$scope.eventTypes = [{tag:'LOGIN'}, {tag:'REGISTER'}, {tag:'LOGOUT'}, {tag:'CODE_TO_TOKEN'}, {tag:'REFRESH_TOKEN'},
|
// Admin can filter events view by selecting any one or multiple of these events.
|
||||||
{tag:'LOGIN_ERROR'}, {tag:'REGISTER_ERROR'}, {tag:'LOGOUT_ERROR'}, {tag:'CODE_TO_TOKEN_ERROR'}, {tag:'REFRESH_TOKEN_ERROR'},
|
$scope.eventTypes = [{tag:'LOGIN'}, {tag:'REGISTER'}, {tag:'LOGOUT'}, {tag:'CODE_TO_TOKEN'},
|
||||||
{tag:'VALIDATE_ACCESS_TOKEN'}, {tag:'VALIDATE_ACCESS_TOKEN_ERROR'}, {tag:'SOCIAL_LINK'}, {tag:'SOCIAL_LINK_ERROR'}, {tag:'REMOVE_FEDERATED_IDENTITY'},
|
{tag:'REFRESH_TOKEN'}, {tag:'LOGIN_ERROR'}, {tag:'REGISTER_ERROR'}, {tag:'LOGOUT_ERROR'},
|
||||||
{tag:'REMOVE_SOCIAL_LINK_ERROR'}, {tag:'UPDATE_EMAIL'}, {tag:'UPDATE_PROFILE'}, {tag:'UPDATE_PASSWORD'}, {tag:'UPDATE_TOTP'}];
|
{tag:'CODE_TO_TOKEN_ERROR'}, {tag:'REFRESH_TOKEN_ERROR'}, {tag:'VALIDATE_ACCESS_TOKEN'}, {tag:'VALIDATE_ACCESS_TOKEN_ERROR'},
|
||||||
|
{tag:'SOCIAL_LINK'}, {tag:'SOCIAL_LINK_ERROR'}, {tag:'REMOVE_FEDERATED_IDENTITY'}, {tag:'REMOVE_SOCIAL_LINK_ERROR'},
|
||||||
|
{tag:'UPDATE_EMAIL'}, {tag:'UPDATE_PROFILE'}, {tag:'UPDATE_PASSWORD'}, {tag:'UPDATE_TOTP'},
|
||||||
|
{tag:'UPLOAD_REALM'}, {tag:'IMPORT_REALM'}, {tag:'UPDATE_REALM'}, {tag:'DELETE_REALM'},
|
||||||
|
{tag:'CREATE_USER'}, {tag:'UPDATE_USER'}, {tag:'DELETE_USER'}, {tag:'VIEW_USER_SESSIONS'},
|
||||||
|
{tag:'CREATE_APPLICATION'}, {tag:'UPDATE_APPLICATION'}, {tag:'DELETE_APPLICATION'}, {tag:'VIEW_APPLICATION'},
|
||||||
|
{tag:'CREATE_OAUTH_CLIENT'}, {tag:'UPDATE_OAUTH_CLIENT'}, {tag:'VIEW_OAUTH_CLIENT'}, {tag:'DELETE_OAUTH_CLIENT'},
|
||||||
|
{tag:'CREATE_PROVIDER'}, {tag:'UPDATE_PROVIDER'}, {tag:'DELETE_PROVIDER'}, {tag:'VIEW_ROLE'},
|
||||||
|
{tag:'CREATE_ROLE'}, {tag:'UPDATE_ROLE'}, {tag:'DELETE_ROLE'}, {tag:'VIEW_SERVER_INFO'}];
|
||||||
|
|
||||||
$scope.query = {
|
$scope.query = {
|
||||||
id : realm.realm,
|
id : realm.realm,
|
||||||
|
|
|
@ -52,6 +52,19 @@
|
||||||
|
|
||||||
<span tooltip-placement="right" tooltip="Configure what listeners receive events for the realm." class="fa fa-info-circle"></span>
|
<span tooltip-placement="right" tooltip="Configure what listeners receive events for the realm." class="fa fa-info-circle"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" data-ng-show="eventsConfig.eventsEnabled">
|
||||||
|
<label class="col-sm-2 control-label" for="enabledEventTypes" class="control-label">Event Types</label>
|
||||||
|
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<select ui-select2 ng-model="eventsConfig.enabledEventTypes" data-placeholder="Select an event type(s)..." multiple>
|
||||||
|
<option ng-repeat="type in enabledEventTypes" value="{{type.tag}}">{{type.tag}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span tooltip-placement="right" tooltip="Configure what event types persist for the realm." class="fa fa-info-circle"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<div class="pull-right form-actions" data-ng-show="access.manageEvents">
|
<div class="pull-right form-actions" data-ng-show="access.manageEvents">
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<label class="col-sm-2 control-label" for="eventType">Event Type</label>
|
<label class="col-sm-2 control-label" for="eventType">Event Type</label>
|
||||||
<div class="col-sm-5">
|
<div class="col-sm-5">
|
||||||
<select ui-select2 id="reqActions" ng-model="query.type" data-placeholder="Select event types..." multiple>
|
<select ui-select2 id="reqActions" ng-model="query.type" data-placeholder="Select event types..." multiple>
|
||||||
<option ng-repeat="event in eventTypes|orderBy:'tag'">{{event.tag}}</option>
|
<option ng-repeat="event in eventTypes">{{event.tag}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -237,6 +237,10 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
|
|
||||||
void setEventsListeners(Set<String> listeners);
|
void setEventsListeners(Set<String> listeners);
|
||||||
|
|
||||||
|
Set<String> getEnabledEventTypes();
|
||||||
|
|
||||||
|
void setEnabledEventTypes(Set<String> enabledEventTypes);
|
||||||
|
|
||||||
ApplicationModel getMasterAdminApp();
|
ApplicationModel getMasterAdminApp();
|
||||||
|
|
||||||
void setMasterAdminApp(ApplicationModel app);
|
void setMasterAdminApp(ApplicationModel app);
|
||||||
|
|
|
@ -62,6 +62,7 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||||
private boolean eventsEnabled;
|
private boolean eventsEnabled;
|
||||||
private long eventsExpiration;
|
private long eventsExpiration;
|
||||||
private List<String> eventsListeners = new ArrayList<String>();
|
private List<String> eventsListeners = new ArrayList<String>();
|
||||||
|
private List<String> enabledEventTypes = new ArrayList<String>();
|
||||||
|
|
||||||
private String adminAppId;
|
private String adminAppId;
|
||||||
|
|
||||||
|
@ -380,6 +381,14 @@ public class RealmEntity extends AbstractIdentifiableEntity {
|
||||||
this.eventsListeners = eventsListeners;
|
this.eventsListeners = eventsListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getEnabledEventTypes() {
|
||||||
|
return enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabledEventTypes(List<String> enabledEventTypes) {
|
||||||
|
this.enabledEventTypes = enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAdminAppId() {
|
public String getAdminAppId() {
|
||||||
return adminAppId;
|
return adminAppId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,9 @@ public class ModelToRepresentation {
|
||||||
if (realm.getEventsListeners() != null) {
|
if (realm.getEventsListeners() != null) {
|
||||||
rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
|
rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
|
||||||
}
|
}
|
||||||
|
if (realm.getEnabledEventTypes() != null) {
|
||||||
|
rep.setEnabledEventTypes(new LinkedList<String>(realm.getEnabledEventTypes()));
|
||||||
|
}
|
||||||
|
|
||||||
rep.setVerifyEmail(realm.isVerifyEmail());
|
rep.setVerifyEmail(realm.isVerifyEmail());
|
||||||
rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
|
rep.setResetPasswordAllowed(realm.isResetPasswordAllowed());
|
||||||
|
@ -182,6 +185,11 @@ public class ModelToRepresentation {
|
||||||
if (realm.getEventsListeners() != null) {
|
if (realm.getEventsListeners() != null) {
|
||||||
rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
|
rep.setEventsListeners(new LinkedList<String>(realm.getEventsListeners()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(realm.getEnabledEventTypes() != null) {
|
||||||
|
rep.setEnabledEventTypes(new LinkedList<String>(realm.getEnabledEventTypes()));
|
||||||
|
}
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -357,6 +357,7 @@ public class RepresentationToModel {
|
||||||
if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
|
if (rep.isEventsEnabled() != null) realm.setEventsEnabled(rep.isEventsEnabled());
|
||||||
if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
|
if (rep.getEventsExpiration() != null) realm.setEventsExpiration(rep.getEventsExpiration());
|
||||||
if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
if (rep.getEventsListeners() != null) realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
||||||
|
if (rep.getEnabledEventTypes() != null) realm.setEnabledEventTypes(new HashSet<String>(rep.getEnabledEventTypes()));
|
||||||
|
|
||||||
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
if (rep.getPasswordPolicy() != null) realm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.keycloak.connections.file.InMemoryModel;
|
import org.keycloak.connections.file.InMemoryModel;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
@ -1039,6 +1040,20 @@ public class RealmAdapter implements RealmModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
return new HashSet<String>(realm.getEnabledEventTypes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabledEventTypes(Set<String> enabledEventTypes) {
|
||||||
|
if (enabledEventTypes != null) {
|
||||||
|
realm.setEnabledEventTypes(new ArrayList<String>(enabledEventTypes));
|
||||||
|
} else {
|
||||||
|
realm.setEnabledEventTypes(Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getMasterAdminApp() {
|
public ApplicationModel getMasterAdminApp() {
|
||||||
return this.masterAdminApp;
|
return this.masterAdminApp;
|
||||||
|
|
|
@ -806,6 +806,18 @@ public class RealmAdapter implements RealmModel {
|
||||||
updated.setEventsListeners(listeners);
|
updated.setEventsListeners(listeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
if (updated != null) return updated.getEnabledEventTypes();
|
||||||
|
return cached.getEnabledEventTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabledEventTypes(Set<String> enabledEventTypes) {
|
||||||
|
getDelegateForUpdate();
|
||||||
|
updated.setEnabledEventTypes(enabledEventTypes);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getMasterAdminApp() {
|
public ApplicationModel getMasterAdminApp() {
|
||||||
return cacheSession.getRealm(Config.getAdminRealm()).getApplicationById(cached.getMasterAdminApp());
|
return cacheSession.getRealm(Config.getAdminRealm()).getApplicationById(cached.getMasterAdminApp());
|
||||||
|
|
|
@ -79,6 +79,7 @@ public class CachedRealm {
|
||||||
private boolean eventsEnabled;
|
private boolean eventsEnabled;
|
||||||
private long eventsExpiration;
|
private long eventsExpiration;
|
||||||
private Set<String> eventsListeners = new HashSet<String>();
|
private Set<String> eventsListeners = new HashSet<String>();
|
||||||
|
private Set<String> enabledEventTypes = new HashSet<String>();
|
||||||
private List<String> defaultRoles = new LinkedList<String>();
|
private List<String> defaultRoles = new LinkedList<String>();
|
||||||
private Map<String, String> realmRoles = new HashMap<String, String>();
|
private Map<String, String> realmRoles = new HashMap<String, String>();
|
||||||
private Map<String, String> applications = new HashMap<String, String>();
|
private Map<String, String> applications = new HashMap<String, String>();
|
||||||
|
@ -146,6 +147,7 @@ public class CachedRealm {
|
||||||
eventsEnabled = model.isEventsEnabled();
|
eventsEnabled = model.isEventsEnabled();
|
||||||
eventsExpiration = model.getEventsExpiration();
|
eventsExpiration = model.getEventsExpiration();
|
||||||
eventsListeners.addAll(model.getEventsListeners());
|
eventsListeners.addAll(model.getEventsListeners());
|
||||||
|
enabledEventTypes.addAll(model.getEnabledEventTypes());
|
||||||
defaultRoles.addAll(model.getDefaultRoles());
|
defaultRoles.addAll(model.getDefaultRoles());
|
||||||
masterAdminApp = model.getMasterAdminApp().getId();
|
masterAdminApp = model.getMasterAdminApp().getId();
|
||||||
|
|
||||||
|
@ -349,6 +351,10 @@ public class CachedRealm {
|
||||||
return eventsListeners;
|
return eventsListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
return enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public List<UserFederationProviderModel> getUserFederationProviders() {
|
public List<UserFederationProviderModel> getUserFederationProviders() {
|
||||||
return userFederationProviders;
|
return userFederationProviders;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
@ -1140,6 +1141,17 @@ public class RealmAdapter implements RealmModel {
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
return realm.getEnabledEventTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabledEventTypes(Set<String> enabledEventTypes) {
|
||||||
|
realm.setEnabledEventTypes(enabledEventTypes);
|
||||||
|
em.flush();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getMasterAdminApp() {
|
public ApplicationModel getMasterAdminApp() {
|
||||||
return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
|
return new ApplicationAdapter(this, em, session, realm.getMasterAdminApp());
|
||||||
|
|
|
@ -130,6 +130,11 @@ public class RealmEntity {
|
||||||
@CollectionTable(name="REALM_EVENTS_LISTENERS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
@CollectionTable(name="REALM_EVENTS_LISTENERS", joinColumns={ @JoinColumn(name="REALM_ID") })
|
||||||
protected Set<String> eventsListeners = new HashSet<String>();
|
protected Set<String> eventsListeners = new HashSet<String>();
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@Column(name="VALUE")
|
||||||
|
@CollectionTable(name="REALM_ENABLED_EVENT_TYPES", joinColumns={ @JoinColumn(name="REALM_ID") })
|
||||||
|
protected Set<String> enabledEventTypes = new HashSet<String>();
|
||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
@JoinColumn(name="MASTER_ADMIN_APP")
|
@JoinColumn(name="MASTER_ADMIN_APP")
|
||||||
protected ApplicationEntity masterAdminApp;
|
protected ApplicationEntity masterAdminApp;
|
||||||
|
@ -419,6 +424,14 @@ public class RealmEntity {
|
||||||
this.eventsListeners = eventsListeners;
|
this.eventsListeners = eventsListeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
return enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabledEventTypes(Set<String> enabledEventTypes) {
|
||||||
|
this.enabledEventTypes = enabledEventTypes;
|
||||||
|
}
|
||||||
|
|
||||||
public ApplicationEntity getMasterAdminApp() {
|
public ApplicationEntity getMasterAdminApp() {
|
||||||
return masterAdminApp;
|
return masterAdminApp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.keycloak.models.mongo.keycloak.adapters;
|
||||||
|
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.mongodb.QueryBuilder;
|
import com.mongodb.QueryBuilder;
|
||||||
|
|
||||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||||
import org.keycloak.enums.SslRequired;
|
import org.keycloak.enums.SslRequired;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
@ -1045,6 +1046,21 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
updateRealm();
|
updateRealm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getEnabledEventTypes() {
|
||||||
|
return new HashSet<String>(realm.getEnabledEventTypes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabledEventTypes(Set<String> enabledEventTypes) {
|
||||||
|
if (enabledEventTypes != null) {
|
||||||
|
realm.setEnabledEventTypes(new ArrayList<String>(enabledEventTypes));
|
||||||
|
} else {
|
||||||
|
realm.setEnabledEventTypes(Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
updateRealm();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApplicationModel getMasterAdminApp() {
|
public ApplicationModel getMasterAdminApp() {
|
||||||
MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext);
|
MongoApplicationEntity appData = getMongoStore().loadEntity(MongoApplicationEntity.class, realm.getAdminAppId(), invocationContext);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
|
@ -185,7 +186,7 @@ public class OIDCLoginProtocol implements LoginProtocol {
|
||||||
public Response finishLogout(UserSessionModel userSession) {
|
public Response finishLogout(UserSessionModel userSession) {
|
||||||
String redirectUri = userSession.getNote(OIDCLoginProtocol.LOGOUT_REDIRECT_URI);
|
String redirectUri = userSession.getNote(OIDCLoginProtocol.LOGOUT_REDIRECT_URI);
|
||||||
String state = userSession.getNote(OIDCLoginProtocol.LOGOUT_STATE_PARAM);
|
String state = userSession.getNote(OIDCLoginProtocol.LOGOUT_STATE_PARAM);
|
||||||
event.event(EventType.LOGOUT);
|
event.eventGroup(EventGroup.USER).event(EventType.LOGOUT);
|
||||||
if (redirectUri != null) {
|
if (redirectUri != null) {
|
||||||
event.detail(Details.REDIRECT_URI, redirectUri);
|
event.detail(Details.REDIRECT_URI, redirectUri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
package org.keycloak.protocol.oidc;
|
package org.keycloak.protocol.oidc;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
|
||||||
import org.jboss.resteasy.spi.HttpRequest;
|
|
||||||
import org.jboss.resteasy.spi.HttpResponse;
|
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.ClientConnection;
|
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.OAuthErrorException;
|
|
||||||
import org.keycloak.RSATokenVerifier;
|
|
||||||
import org.keycloak.events.Details;
|
|
||||||
import org.keycloak.events.Errors;
|
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.jose.jwk.JWK;
|
import org.keycloak.jose.jwk.JWK;
|
||||||
import org.keycloak.jose.jwk.JWKBuilder;
|
import org.keycloak.jose.jwk.JWKBuilder;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
|
@ -25,8 +17,6 @@ import org.keycloak.protocol.oidc.endpoints.TokenEndpoint;
|
||||||
import org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint;
|
import org.keycloak.protocol.oidc.endpoints.UserInfoEndpoint;
|
||||||
import org.keycloak.protocol.oidc.endpoints.ValidateTokenEndpoint;
|
import org.keycloak.protocol.oidc.endpoints.ValidateTokenEndpoint;
|
||||||
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
|
import org.keycloak.protocol.oidc.representations.JSONWebKeySet;
|
||||||
import org.keycloak.representations.AccessToken;
|
|
||||||
import org.keycloak.services.ErrorResponseException;
|
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
import org.keycloak.services.resources.RealmsResource;
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
import org.keycloak.services.resources.flows.Flows;
|
||||||
|
@ -39,12 +29,8 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.SecurityContext;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import javax.ws.rs.ext.Providers;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource class for the oauth/openid connect token service
|
* Resource class for the oauth/openid connect token service
|
||||||
|
@ -73,7 +59,7 @@ public class OIDCLoginProtocolService {
|
||||||
public OIDCLoginProtocolService(RealmModel realm, EventBuilder event, AuthenticationManager authManager) {
|
public OIDCLoginProtocolService(RealmModel realm, EventBuilder event, AuthenticationManager authManager) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.tokenManager = new TokenManager();
|
this.tokenManager = new TokenManager();
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
this.authManager = authManager;
|
this.authManager = authManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.constants.AdapterConstants;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
@ -35,6 +36,7 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,7 +90,7 @@ public class AuthorizationEndpoint {
|
||||||
this.authManager = authManager;
|
this.authManager = authManager;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.event = event;
|
this.event = event;
|
||||||
event.event(EventType.LOGIN);
|
event.eventGroup(EventGroup.USER).event(EventType.LOGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.OAuthErrorException;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
@ -70,7 +71,7 @@ public class LogoutEndpoint {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
this.authManager = authManager;
|
this.authManager = authManager;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.constants.AdapterConstants;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
@ -40,6 +41,7 @@ import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,7 +87,7 @@ public class TokenEndpoint {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
this.authManager = authManager;
|
this.authManager = authManager;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.keycloak.OAuthErrorException;
|
||||||
import org.keycloak.RSATokenVerifier;
|
import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -54,6 +55,7 @@ import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -114,6 +116,7 @@ public class UserInfoEndpoint {
|
||||||
|
|
||||||
private Response issueUserInfo(String tokenString) {
|
private Response issueUserInfo(String tokenString) {
|
||||||
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder()
|
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder()
|
||||||
|
.eventGroup(EventGroup.USER)
|
||||||
.event(EventType.USER_INFO_REQUEST)
|
.event(EventType.USER_INFO_REQUEST)
|
||||||
.detail(Details.AUTH_METHOD, Details.VALIDATE_ACCESS_TOKEN);
|
.detail(Details.AUTH_METHOD, Details.VALIDATE_ACCESS_TOKEN);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.RSATokenVerifier;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -22,6 +23,7 @@ import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.*;
|
import javax.ws.rs.core.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ public class ValidateTokenEndpoint {
|
||||||
public ValidateTokenEndpoint(TokenManager tokenManager, RealmModel realm, EventBuilder event) {
|
public ValidateTokenEndpoint(TokenManager tokenManager, RealmModel realm, EventBuilder event) {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.VerificationException;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.jose.jws.JWSBuilder;
|
import org.keycloak.jose.jws.JWSBuilder;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
|
@ -43,6 +44,7 @@ import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.NewCookie;
|
import javax.ws.rs.core.NewCookie;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -374,7 +376,7 @@ public class AuthenticationManager {
|
||||||
logger.debugv("processAccessCode: go to oauth page?: {0}",
|
logger.debugv("processAccessCode: go to oauth page?: {0}",
|
||||||
!isResource);
|
!isResource);
|
||||||
|
|
||||||
event.detail(Details.CODE_ID, clientSession.getId());
|
event.eventGroup(EventGroup.USER).detail(Details.CODE_ID, clientSession.getId());
|
||||||
|
|
||||||
Set<UserModel.RequiredAction> requiredActions = user.getRequiredActions();
|
Set<UserModel.RequiredAction> requiredActions = user.getRequiredActions();
|
||||||
if (!requiredActions.isEmpty()) {
|
if (!requiredActions.isEmpty()) {
|
||||||
|
|
|
@ -5,11 +5,14 @@ import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventListenerProvider;
|
import org.keycloak.events.EventListenerProvider;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -51,7 +54,12 @@ public class EventsManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EventBuilder(listeners, realm, clientConnection.getRemoteAddr());
|
Set<EventType> enabledEventTypes = new HashSet<EventType>();
|
||||||
|
for(String type : realm.getEnabledEventTypes()) {
|
||||||
|
enabledEventTypes.add(EventType.valueOf(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EventBuilder(listeners, enabledEventTypes, realm, clientConnection.getRemoteAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.timer.TimerProvider;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -161,6 +162,9 @@ public class RealmManager {
|
||||||
if (rep.getEventsListeners() != null) {
|
if (rep.getEventsListeners() != null) {
|
||||||
realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
realm.setEventsListeners(new HashSet<String>(rep.getEventsListeners()));
|
||||||
}
|
}
|
||||||
|
if(rep.getEnabledEventTypes() != null) {
|
||||||
|
realm.setEnabledEventTypes(new HashSet<String>(rep.getEnabledEventTypes()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should be RealmManager moved to model/api instead of referencing methods this way?
|
// Should be RealmManager moved to model/api instead of referencing methods this way?
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.keycloak.account.AccountProvider;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
|
@ -71,6 +72,7 @@ import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import javax.ws.rs.core.Variant;
|
import javax.ws.rs.core.Variant;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -141,7 +143,7 @@ public class AccountService {
|
||||||
public AccountService(RealmModel realm, ApplicationModel application, EventBuilder event) {
|
public AccountService(RealmModel realm, ApplicationModel application, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.application = application;
|
this.application = application;
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
this.authManager = new AppAuthManager();
|
this.authManager = new AppAuthManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
|
@ -61,6 +62,7 @@ import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.*;
|
import javax.ws.rs.core.*;
|
||||||
import javax.ws.rs.core.Response.Status;
|
import javax.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -109,7 +111,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
this.event = new EventsManager(this.realmModel, this.session, this.clientConnection).createEventBuilder().event(EventType.IDENTITY_PROVIDER_LOGIN);
|
this.event = new EventsManager(this.realmModel, this.session, this.clientConnection).createEventBuilder().event(EventType.IDENTITY_PROVIDER_LOGIN).eventGroup(EventGroup.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.keycloak.email.EmailProvider;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.jose.jws.JWSBuilder;
|
import org.keycloak.jose.jws.JWSBuilder;
|
||||||
import org.keycloak.login.LoginFormsProvider;
|
import org.keycloak.login.LoginFormsProvider;
|
||||||
|
@ -63,6 +64,7 @@ import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import javax.ws.rs.ext.Providers;
|
import javax.ws.rs.ext.Providers;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -132,7 +134,7 @@ public class LoginActionsService {
|
||||||
public LoginActionsService(RealmModel realm, AuthenticationManager authManager, EventBuilder event) {
|
public LoginActionsService(RealmModel realm, AuthenticationManager authManager, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.authManager = authManager;
|
this.authManager = authManager;
|
||||||
this.event = event;
|
this.event = event.eventGroup(EventGroup.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkSsl() {
|
private boolean checkSsl() {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -130,6 +131,7 @@ public class RealmsResource {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmManager realmManager = new RealmManager(session);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
RealmModel realm = locateRealm(name, realmManager);
|
||||||
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.USER);
|
||||||
AuthenticationManager authManager = new AuthenticationManager(protector);
|
AuthenticationManager authManager = new AuthenticationManager(protector);
|
||||||
LoginActionsService service = new LoginActionsService(realm, authManager, event);
|
LoginActionsService service = new LoginActionsService(realm, authManager, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(service);
|
ResteasyProviderFactory.getInstance().injectProperties(service);
|
||||||
|
@ -143,6 +145,7 @@ public class RealmsResource {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmManager realmManager = new RealmManager(session);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
RealmModel realm = locateRealm(name, realmManager);
|
||||||
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.USER);
|
||||||
ClientsManagementService service = new ClientsManagementService(realm, event);
|
ClientsManagementService service = new ClientsManagementService(realm, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(service);
|
ResteasyProviderFactory.getInstance().injectProperties(service);
|
||||||
return service;
|
return service;
|
||||||
|
@ -169,6 +172,7 @@ public class RealmsResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.USER);
|
||||||
AccountService accountService = new AccountService(realm, application, event);
|
AccountService accountService = new AccountService(realm, application, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(accountService);
|
ResteasyProviderFactory.getInstance().injectProperties(accountService);
|
||||||
//resourceContext.initResource(accountService);
|
//resourceContext.initResource(accountService);
|
||||||
|
|
|
@ -7,8 +7,10 @@ import org.jboss.resteasy.spi.HttpRequest;
|
||||||
import org.jboss.resteasy.spi.HttpResponse;
|
import org.jboss.resteasy.spi.HttpResponse;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.Version;
|
import org.keycloak.Version;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
import org.keycloak.freemarker.BrowserSecurityHeaderSetup;
|
||||||
import org.keycloak.freemarker.FreeMarkerException;
|
import org.keycloak.freemarker.FreeMarkerException;
|
||||||
import org.keycloak.freemarker.FreeMarkerUtil;
|
import org.keycloak.freemarker.FreeMarkerUtil;
|
||||||
|
@ -28,21 +30,18 @@ import org.keycloak.services.managers.AuthenticationManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.KeycloakApplication;
|
import org.keycloak.services.resources.KeycloakApplication;
|
||||||
import org.keycloak.services.resources.flows.Urls;
|
import org.keycloak.services.resources.flows.Urls;
|
||||||
import org.keycloak.util.MimeTypeUtil;
|
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.CacheControl;
|
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
import javax.ws.rs.ext.Providers;
|
import javax.ws.rs.ext.Providers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -86,9 +85,11 @@ public class AdminConsole {
|
||||||
|
|
||||||
protected AppAuthManager authManager;
|
protected AppAuthManager authManager;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public AdminConsole(RealmModel realm) {
|
public AdminConsole(RealmModel realm, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
|
this.event = event.detail(Details.REALM_NAME, realm.getName());
|
||||||
this.authManager = new AppAuthManager();
|
this.authManager = new AppAuthManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +169,12 @@ public class AdminConsole {
|
||||||
if (consoleApp == null) {
|
if (consoleApp == null) {
|
||||||
throw new NotFoundException("Could not find admin console application");
|
throw new NotFoundException("Could not find admin console application");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.SET_REALM_ADAPTER_CONFIGURATION)
|
||||||
|
.client(consoleApp)
|
||||||
|
.detail(Details.REALM_REQUIRED_SSL, realm.getSslRequired().name().toLowerCase())
|
||||||
|
.success();
|
||||||
|
|
||||||
return new ApplicationManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo));
|
return new ApplicationManager().toInstallationRepresentation(realm, consoleApp, keycloak.getBaseUri(uriInfo));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -213,6 +220,8 @@ public class AdminConsole {
|
||||||
addRealmAccess(realm, user, realmAccess);
|
addRealmAccess(realm, user, realmAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.SET_REALM_USER_PERMISSIONS).user(user).success();
|
||||||
|
|
||||||
return Response.ok(new WhoAmI(user.getId(), realm.getName(), displayName, createRealm, realmAccess)).build();
|
return Response.ok(new WhoAmI(user.getId(), realm.getName(), displayName, createRealm, realmAccess)).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +265,8 @@ public class AdminConsole {
|
||||||
public Response logout() {
|
public Response logout() {
|
||||||
URI redirect = AdminRoot.adminConsoleUrl(uriInfo).build(realm.getName());
|
URI redirect = AdminRoot.adminConsoleUrl(uriInfo).build(realm.getName());
|
||||||
|
|
||||||
|
event.event(EventType.LOGOUT).detail(Details.REDIRECT_URI, redirect.toString()).success();
|
||||||
|
|
||||||
return Response.status(302).location(
|
return Response.status(302).location(
|
||||||
OIDCLoginProtocolService.logoutUrl(uriInfo).queryParam("redirect_uri", redirect.toString()).build(realm.getName())
|
OIDCLoginProtocolService.logoutUrl(uriInfo).queryParam("redirect_uri", redirect.toString()).build(realm.getName())
|
||||||
).build();
|
).build();
|
||||||
|
|
|
@ -8,6 +8,9 @@ import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.jboss.resteasy.spi.UnauthorizedException;
|
import org.jboss.resteasy.spi.UnauthorizedException;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.jose.jws.JWSInput;
|
import org.keycloak.jose.jws.JWSInput;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -16,6 +19,7 @@ import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.services.managers.AppAuthManager;
|
import org.keycloak.services.managers.AppAuthManager;
|
||||||
import org.keycloak.services.managers.AuthenticationManager;
|
import org.keycloak.services.managers.AuthenticationManager;
|
||||||
|
import org.keycloak.services.managers.EventsManager;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.services.resources.Cors;
|
import org.keycloak.services.resources.Cors;
|
||||||
|
|
||||||
|
@ -27,6 +31,7 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,9 +75,6 @@ public class AdminRoot {
|
||||||
return base.path(AdminRoot.class);
|
return base.path(AdminRoot.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience path to master realm admin console
|
* Convenience path to master realm admin console
|
||||||
*
|
*
|
||||||
|
@ -124,7 +126,9 @@ public class AdminRoot {
|
||||||
public AdminConsole getAdminConsole(final @PathParam("realm") String name) {
|
public AdminConsole getAdminConsole(final @PathParam("realm") String name) {
|
||||||
RealmManager realmManager = new RealmManager(session);
|
RealmManager realmManager = new RealmManager(session);
|
||||||
RealmModel realm = locateRealm(name, realmManager);
|
RealmModel realm = locateRealm(name, realmManager);
|
||||||
AdminConsole service = new AdminConsole(realm);
|
EventBuilder event = new EventsManager(realm, session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.ADMIN).detail(Details.REALM_NAME, realm.getName());
|
||||||
|
AdminConsole service = new AdminConsole(realm, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(service);
|
ResteasyProviderFactory.getInstance().injectProperties(service);
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +191,9 @@ public class AdminRoot {
|
||||||
|
|
||||||
Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
|
Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
|
||||||
|
|
||||||
RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager);
|
EventBuilder event = new EventsManager(auth.getRealm(), session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.ADMIN);
|
||||||
|
RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
||||||
//resourceContext.initResource(adminResource);
|
//resourceContext.initResource(adminResource);
|
||||||
return adminResource;
|
return adminResource;
|
||||||
|
@ -209,7 +215,9 @@ public class AdminRoot {
|
||||||
}
|
}
|
||||||
Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
|
Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
|
||||||
|
|
||||||
ServerInfoAdminResource adminResource = new ServerInfoAdminResource();
|
EventBuilder event = new EventsManager(auth.getRealm(), session, clientConnection).createEventBuilder();
|
||||||
|
event.eventGroup(EventGroup.ADMIN);
|
||||||
|
ServerInfoAdminResource adminResource = new ServerInfoAdminResource(event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
||||||
//resourceContext.initResource(adminResource);
|
//resourceContext.initResource(adminResource);
|
||||||
return adminResource;
|
return adminResource;
|
||||||
|
|
|
@ -5,6 +5,9 @@ import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.BadRequestException;
|
import org.jboss.resteasy.spi.BadRequestException;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
|
@ -40,6 +43,7 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -57,8 +61,10 @@ public class ApplicationResource {
|
||||||
protected static final Logger logger = Logger.getLogger(ApplicationResource.class);
|
protected static final Logger logger = Logger.getLogger(ApplicationResource.class);
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
protected ApplicationModel application;
|
protected ApplicationModel application;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected UriInfo uriInfo;
|
protected UriInfo uriInfo;
|
||||||
|
|
||||||
|
@ -69,11 +75,12 @@ public class ApplicationResource {
|
||||||
return (KeycloakApplication)keycloak;
|
return (KeycloakApplication)keycloak;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApplicationResource(RealmModel realm, RealmAuth auth, ApplicationModel applicationModel, KeycloakSession session) {
|
public ApplicationResource(RealmModel realm, RealmAuth auth, ApplicationModel applicationModel, KeycloakSession session, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.application = applicationModel;
|
this.application = applicationModel;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.APPLICATION);
|
auth.init(RealmAuth.Resource.APPLICATION);
|
||||||
}
|
}
|
||||||
|
@ -98,6 +105,9 @@ public class ApplicationResource {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RepresentationToModel.updateApplication(rep, application);
|
RepresentationToModel.updateApplication(rep, application);
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_APPLICATION).client(application).success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Application " + rep.getName() + " already exists");
|
return Flows.errors().exists("Application " + rep.getName() + " already exists");
|
||||||
|
@ -116,6 +126,8 @@ public class ApplicationResource {
|
||||||
public ApplicationRepresentation getApplication() {
|
public ApplicationRepresentation getApplication() {
|
||||||
auth.requireView();
|
auth.requireView();
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_APPLICATION).client(application).success();
|
||||||
|
|
||||||
return ModelToRepresentation.toRepresentation(application);
|
return ModelToRepresentation.toRepresentation(application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +138,7 @@ public class ApplicationResource {
|
||||||
*/
|
*/
|
||||||
@Path("certificates/{attr}")
|
@Path("certificates/{attr}")
|
||||||
public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) {
|
public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) {
|
||||||
return new ClientAttributeCertificateResource(realm, auth, application, session, attributePrefix);
|
return new ClientAttributeCertificateResource(realm, auth, application, session, attributePrefix, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,6 +188,8 @@ public class ApplicationResource {
|
||||||
public void deleteApplication() {
|
public void deleteApplication() {
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_APPLICATION).client(application).success();
|
||||||
|
|
||||||
new ApplicationManager(new RealmManager(session)).removeApplication(realm, application);
|
new ApplicationManager(new RealmManager(session)).removeApplication(realm, application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +242,7 @@ public class ApplicationResource {
|
||||||
|
|
||||||
@Path("roles")
|
@Path("roles")
|
||||||
public RoleContainerResource getRoleContainerResource() {
|
public RoleContainerResource getRoleContainerResource() {
|
||||||
return new RoleContainerResource(realm, auth, application);
|
return new RoleContainerResource(realm, auth, application, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,6 +345,9 @@ public class ApplicationResource {
|
||||||
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);
|
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession);
|
||||||
sessions.add(rep);
|
sessions.add(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_APPLICATION_USER_SESSIONS).client(application).success();
|
||||||
|
|
||||||
return sessions;
|
return sessions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +359,9 @@ public class ApplicationResource {
|
||||||
@POST
|
@POST
|
||||||
public GlobalRequestResult logoutAll() {
|
public GlobalRequestResult logoutAll() {
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
|
|
||||||
|
event.event(EventType.INVALIDATE_APPLICATION_USER_SESSIONS).client(application).success();
|
||||||
|
|
||||||
return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, application);
|
return new ResourceAdminManager().logoutApplication(uriInfo.getRequestUri(), realm, application);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,6 +378,8 @@ public class ApplicationResource {
|
||||||
throw new NotFoundException("User not found");
|
throw new NotFoundException("User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.INVALIDATE_APPLICATION_USER_SESSION).client(application).user(user).success();
|
||||||
|
|
||||||
new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, application, user, session);
|
new ResourceAdminManager().logoutUserFromApplication(uriInfo.getRequestUri(), realm, application, user, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +400,10 @@ public class ApplicationResource {
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) logger.debug("Register node: " + node);
|
if (logger.isDebugEnabled()) logger.debug("Register node: " + node);
|
||||||
application.registerNode(node, Time.currentTime());
|
application.registerNode(node, Time.currentTime());
|
||||||
|
|
||||||
|
event.event(EventType.REGISTER_APPLICATION_CLUSTER_NODE).client(application)
|
||||||
|
.detail(Details.APPLICATION_CLUSTER_NODE, node)
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -398,6 +424,10 @@ public class ApplicationResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
application.unregisterNode(node);
|
application.unregisterNode(node);
|
||||||
|
|
||||||
|
event.event(EventType.UNREGISTER_APPLICATION_CLUSTER_NODE).client(application)
|
||||||
|
.detail(Details.APPLICATION_CLUSTER_NODE, node)
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
|
@ -8,8 +9,8 @@ import org.keycloak.models.RealmModel;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ApplicationsByIdResource extends ApplicationsResource {
|
public class ApplicationsByIdResource extends ApplicationsResource {
|
||||||
public ApplicationsByIdResource(RealmModel realm, RealmAuth auth) {
|
public ApplicationsByIdResource(RealmModel realm, RealmAuth auth, EventBuilder event) {
|
||||||
super(realm, auth);
|
super(realm, auth, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,6 +4,9 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
|
@ -23,6 +26,7 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -36,13 +40,15 @@ public class ApplicationsResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
|
||||||
public ApplicationsResource(RealmModel realm, RealmAuth auth) {
|
public ApplicationsResource(RealmModel realm, RealmAuth auth, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.APPLICATION);
|
auth.init(RealmAuth.Resource.APPLICATION);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +77,9 @@ public class ApplicationsResource {
|
||||||
rep.add(app);
|
rep.add(app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_REALM_APPLICATIONS).success();
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,10 +97,13 @@ public class ApplicationsResource {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ApplicationModel applicationModel = RepresentationToModel.createApplication(session, realm, rep, true);
|
ApplicationModel applicationModel = RepresentationToModel.createApplication(session, realm, rep, true);
|
||||||
|
|
||||||
|
event.event(EventType.CREATE_APPLICATION).client(applicationModel).success();
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(applicationModel)).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(applicationModel)).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Application " + rep.getName() + " already exists");
|
return Flows.errors().exists("Application " + rep.getName() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getApplicationPath(ApplicationModel applicationModel) {
|
protected String getApplicationPath(ApplicationModel applicationModel) {
|
||||||
|
@ -110,7 +122,7 @@ public class ApplicationsResource {
|
||||||
if (applicationModel == null) {
|
if (applicationModel == null) {
|
||||||
throw new NotFoundException("Could not find application: " + name);
|
throw new NotFoundException("Could not find application: " + name);
|
||||||
}
|
}
|
||||||
ApplicationResource applicationResource = new ApplicationResource(realm, auth, applicationModel, session);
|
ApplicationResource applicationResource = new ApplicationResource(realm, auth, applicationModel, session, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(applicationResource);
|
ResteasyProviderFactory.getInstance().injectProperties(applicationResource);
|
||||||
//resourceContext.initResource(applicationResource);
|
//resourceContext.initResource(applicationResource);
|
||||||
return applicationResource;
|
return applicationResource;
|
||||||
|
|
|
@ -6,6 +6,9 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
|
||||||
import org.jboss.resteasy.spi.BadRequestException;
|
import org.jboss.resteasy.spi.BadRequestException;
|
||||||
import org.jboss.resteasy.spi.NotAcceptableException;
|
import org.jboss.resteasy.spi.NotAcceptableException;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -21,6 +24,7 @@ import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -39,18 +43,20 @@ import java.util.Map;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class ClientAttributeCertificateResource {
|
public class ClientAttributeCertificateResource {
|
||||||
|
|
||||||
public static final String PRIVATE_KEY = "private.key";
|
public static final String PRIVATE_KEY = "private.key";
|
||||||
public static final String X509CERTIFICATE = "certificate";
|
public static final String X509CERTIFICATE = "certificate";
|
||||||
|
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
protected ClientModel client;
|
protected ClientModel client;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
protected String attributePrefix;
|
protected String attributePrefix;
|
||||||
protected String privateAttribute;
|
protected String privateAttribute;
|
||||||
protected String certificateAttribute;
|
protected String certificateAttribute;
|
||||||
|
|
||||||
public ClientAttributeCertificateResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, String attributePrefix) {
|
public ClientAttributeCertificateResource(RealmModel realm, RealmAuth auth, ClientModel client, KeycloakSession session, String attributePrefix, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
@ -58,6 +64,7 @@ public class ClientAttributeCertificateResource {
|
||||||
this.attributePrefix = attributePrefix;
|
this.attributePrefix = attributePrefix;
|
||||||
this.privateAttribute = attributePrefix + "." + PRIVATE_KEY;
|
this.privateAttribute = attributePrefix + "." + PRIVATE_KEY;
|
||||||
this.certificateAttribute = attributePrefix + "." + X509CERTIFICATE;
|
this.certificateAttribute = attributePrefix + "." + X509CERTIFICATE;
|
||||||
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClientKeyPairInfo {
|
public static class ClientKeyPairInfo {
|
||||||
|
@ -93,6 +100,9 @@ public class ClientAttributeCertificateResource {
|
||||||
ClientKeyPairInfo info = new ClientKeyPairInfo();
|
ClientKeyPairInfo info = new ClientKeyPairInfo();
|
||||||
info.setCertificate(client.getAttribute(certificateAttribute));
|
info.setCertificate(client.getAttribute(certificateAttribute));
|
||||||
info.setPrivateKey(client.getAttribute(privateAttribute));
|
info.setPrivateKey(client.getAttribute(privateAttribute));
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_CLIENT_CERTIFICATE).client(client).success();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +141,9 @@ public class ClientAttributeCertificateResource {
|
||||||
ClientKeyPairInfo info = new ClientKeyPairInfo();
|
ClientKeyPairInfo info = new ClientKeyPairInfo();
|
||||||
info.setCertificate(client.getAttribute(certificateAttribute));
|
info.setCertificate(client.getAttribute(certificateAttribute));
|
||||||
info.setPrivateKey(client.getAttribute(privateAttribute));
|
info.setPrivateKey(client.getAttribute(privateAttribute));
|
||||||
|
|
||||||
|
event.event(EventType.GENERATE_CLIENT_CERTIFICATE).client(client).success();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +201,7 @@ public class ClientAttributeCertificateResource {
|
||||||
info.setCertificate(certPem);
|
info.setCertificate(certPem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.UPLOAD_CLIENT_CERTIFICATE).client(client).success();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -314,6 +328,9 @@ public class ClientAttributeCertificateResource {
|
||||||
stream.flush();
|
stream.flush();
|
||||||
stream.close();
|
stream.close();
|
||||||
byte[] rtn = stream.toByteArray();
|
byte[] rtn = stream.toByteArray();
|
||||||
|
|
||||||
|
event.event(EventType.DOWNLOAD_CLIENT_CERTIFICATE).client(client).success();
|
||||||
|
|
||||||
return rtn;
|
return rtn;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
|
@ -4,6 +4,9 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientIdentityProviderMappingModel;
|
import org.keycloak.models.ClientIdentityProviderMappingModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.FederatedIdentityModel;
|
import org.keycloak.models.FederatedIdentityModel;
|
||||||
|
@ -29,6 +32,7 @@ import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -43,18 +47,26 @@ public class IdentityProviderResource {
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final KeycloakSession session;
|
private final KeycloakSession session;
|
||||||
private final IdentityProviderModel identityProviderModel;
|
private final IdentityProviderModel identityProviderModel;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel) {
|
public IdentityProviderResource(RealmAuth auth, RealmModel realm, KeycloakSession session, IdentityProviderModel identityProviderModel, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.identityProviderModel = identityProviderModel;
|
this.identityProviderModel = identityProviderModel;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@NoCache
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public IdentityProviderRepresentation getIdentityProvider() {
|
public IdentityProviderRepresentation getIdentityProvider() {
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_IDENTITY_PROVIDER)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER, identityProviderModel.getProviderId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_ALIAS, identityProviderModel.getAlias())
|
||||||
|
.success();
|
||||||
|
|
||||||
return ModelToRepresentation.toRepresentation(this.identityProviderModel);
|
return ModelToRepresentation.toRepresentation(this.identityProviderModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +76,14 @@ public class IdentityProviderResource {
|
||||||
this.auth.requireManage();
|
this.auth.requireManage();
|
||||||
removeClientIdentityProviders(this.realm.getApplications(), this.identityProviderModel);
|
removeClientIdentityProviders(this.realm.getApplications(), this.identityProviderModel);
|
||||||
removeClientIdentityProviders(this.realm.getOAuthClients(), this.identityProviderModel);
|
removeClientIdentityProviders(this.realm.getOAuthClients(), this.identityProviderModel);
|
||||||
|
|
||||||
this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias());
|
this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias());
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_IDENTITY_PROVIDER)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER, identityProviderModel.getProviderId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_ALIAS, identityProviderModel.getAlias())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +109,11 @@ public class IdentityProviderResource {
|
||||||
updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId);
|
updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_IDENTITY_PROVIDER)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER, identityProviderModel.getProviderId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_ALIAS, identityProviderModel.getAlias())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Identity Provider " + providerRep.getAlias() + " already exists");
|
return Flows.errors().exists("Identity Provider " + providerRep.getAlias() + " already exists");
|
||||||
|
|
|
@ -8,8 +8,9 @@ import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||||
import org.keycloak.models.ClientIdentityProviderMappingModel;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
|
@ -32,6 +33,7 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -48,11 +50,13 @@ public class IdentityProvidersResource {
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final KeycloakSession session;
|
private final KeycloakSession session;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth) {
|
public IdentityProvidersResource(RealmModel realm, KeycloakSession session, RealmAuth auth, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
|
this.event = event;
|
||||||
this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
|
this.auth.init(RealmAuth.Resource.IDENTITY_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +69,11 @@ public class IdentityProvidersResource {
|
||||||
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
||||||
|
|
||||||
if (providerFactory != null) {
|
if (providerFactory != null) {
|
||||||
|
event.event(EventType.VIEW_IDENTITY_PROVIDERS)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY, providerFactory.getId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY_IDENTITY, providerFactory.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.ok(providerFactory).build();
|
return Response.ok(providerFactory).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +92,12 @@ public class IdentityProvidersResource {
|
||||||
InputStream inputStream = file.getBody(InputStream.class, null);
|
InputStream inputStream = file.getBody(InputStream.class, null);
|
||||||
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
||||||
Map<String, String> config = providerFactory.parseConfig(inputStream);
|
Map<String, String> config = providerFactory.parseConfig(inputStream);
|
||||||
|
|
||||||
|
event.event(EventType.IMPORT_IDENTITY_PROVIDER_CONFIG)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY, providerFactory.getId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY_IDENTITY, providerFactory.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +119,12 @@ public class IdentityProvidersResource {
|
||||||
}
|
}
|
||||||
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
IdentityProviderFactory providerFactory = getProviderFactorytById(providerId);
|
||||||
Map<String, String> config = providerFactory.parseConfig(inputStream);
|
Map<String, String> config = providerFactory.parseConfig(inputStream);
|
||||||
|
|
||||||
|
event.event(EventType.IMPORT_IDENTITY_PROVIDER_CONFIG)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY, providerFactory.getId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_FACTORY_IDENTITY, providerFactory.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +141,8 @@ public class IdentityProvidersResource {
|
||||||
representations.add(ModelToRepresentation.toRepresentation(identityProviderModel));
|
representations.add(ModelToRepresentation.toRepresentation(identityProviderModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_IDENTITY_PROVIDERS).success();
|
||||||
|
|
||||||
return representations;
|
return representations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +155,11 @@ public class IdentityProvidersResource {
|
||||||
try {
|
try {
|
||||||
this.realm.addIdentityProvider(RepresentationToModel.toModel(representation));
|
this.realm.addIdentityProvider(RepresentationToModel.toModel(representation));
|
||||||
|
|
||||||
|
event.event(EventType.CREATE_IDENTITY_PROVIDER)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER, representation.getProviderId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_ALIAS, representation.getAlias())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Identity Provider " + representation.getAlias() + " already exists");
|
return Flows.errors().exists("Identity Provider " + representation.getAlias() + " already exists");
|
||||||
|
@ -154,9 +182,14 @@ public class IdentityProvidersResource {
|
||||||
throw new NotFoundException("Could not find identity provider: " + alias);
|
throw new NotFoundException("Could not find identity provider: " + alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel);
|
IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
|
ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource);
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_IDENTITY_PROVIDER)
|
||||||
|
.detail(Details.IDENTITY_PROVIDER, identityProviderModel.getProviderId())
|
||||||
|
.detail(Details.IDENTITY_PROVIDER_ALIAS, identityProviderModel.getAlias())
|
||||||
|
.success();
|
||||||
|
|
||||||
return identityProviderResource;
|
return identityProviderResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
|
@ -31,6 +34,7 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +47,7 @@ public class OAuthClientResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
protected OAuthClientModel oauthClient;
|
protected OAuthClientModel oauthClient;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
@Context
|
@Context
|
||||||
|
@ -55,11 +60,12 @@ public class OAuthClientResource {
|
||||||
return (KeycloakApplication)application;
|
return (KeycloakApplication)application;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OAuthClientResource(RealmModel realm, RealmAuth auth, OAuthClientModel oauthClient, KeycloakSession session) {
|
public OAuthClientResource(RealmModel realm, RealmAuth auth, OAuthClientModel oauthClient, KeycloakSession session, EventBuilder event) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.oauthClient = oauthClient;
|
this.oauthClient = oauthClient;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.CLIENT);
|
auth.init(RealmAuth.Resource.CLIENT);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +90,7 @@ public class OAuthClientResource {
|
||||||
*/
|
*/
|
||||||
@Path("certificates/{attr}")
|
@Path("certificates/{attr}")
|
||||||
public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) {
|
public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix) {
|
||||||
return new ClientAttributeCertificateResource(realm, auth, oauthClient, session, attributePrefix);
|
return new ClientAttributeCertificateResource(realm, auth, oauthClient, session, attributePrefix, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,6 +108,8 @@ public class OAuthClientResource {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
RepresentationToModel.updateOAuthClient(session, rep, oauthClient);
|
RepresentationToModel.updateOAuthClient(session, rep, oauthClient);
|
||||||
|
event.event(EventType.UPDATE_OAUTH_CLIENT).client(oauthClient).success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Client " + rep.getName() + " already exists");
|
return Flows.errors().exists("Client " + rep.getName() + " already exists");
|
||||||
|
@ -119,6 +127,8 @@ public class OAuthClientResource {
|
||||||
public OAuthClientRepresentation getOAuthClient() {
|
public OAuthClientRepresentation getOAuthClient() {
|
||||||
auth.requireView();
|
auth.requireView();
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_OAUTH_CLIENT).client(oauthClient).success();
|
||||||
|
|
||||||
return ModelToRepresentation.toRepresentation(oauthClient);
|
return ModelToRepresentation.toRepresentation(oauthClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +161,8 @@ public class OAuthClientResource {
|
||||||
public void deleteOAuthClient() {
|
public void deleteOAuthClient() {
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_OAUTH_CLIENT).client(oauthClient).success();
|
||||||
|
|
||||||
new OAuthClientManager(new RealmManager(session)).removeClient(realm, oauthClient);
|
new OAuthClientManager(new RealmManager(session)).removeClient(realm, oauthClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,17 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
|
||||||
import org.keycloak.representations.idm.OAuthClientRepresentation;
|
|
||||||
import org.keycloak.services.resources.flows.Flows;
|
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.core.Response;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class OAuthClientsByIdResource extends OAuthClientsResource {
|
public class OAuthClientsByIdResource extends OAuthClientsResource {
|
||||||
public OAuthClientsByIdResource(RealmModel realm, RealmAuth auth, KeycloakSession session) {
|
public OAuthClientsByIdResource(RealmModel realm, RealmAuth auth, KeycloakSession session, EventBuilder event) {
|
||||||
super(realm, auth, session);
|
super(realm, auth, session, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -4,6 +4,9 @@ import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
|
@ -23,6 +26,7 @@ import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -33,7 +37,7 @@ import java.util.List;
|
||||||
public class OAuthClientsResource {
|
public class OAuthClientsResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
protected static final Logger logger = Logger.getLogger(RealmAdminResource.class);
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
|
private EventBuilder event;
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,10 +47,11 @@ public class OAuthClientsResource {
|
||||||
*/
|
*/
|
||||||
private RealmAuth auth;
|
private RealmAuth auth;
|
||||||
|
|
||||||
public OAuthClientsResource(RealmModel realm, RealmAuth auth, KeycloakSession session) {
|
public OAuthClientsResource(RealmModel realm, RealmAuth auth, KeycloakSession session, EventBuilder event) {
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.CLIENT);
|
auth.init(RealmAuth.Resource.CLIENT);
|
||||||
}
|
}
|
||||||
|
@ -73,6 +78,9 @@ public class OAuthClientsResource {
|
||||||
rep.add(client);
|
rep.add(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_OAUTH_CLIENTS).success();
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +98,13 @@ public class OAuthClientsResource {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
OAuthClientModel oauth = RepresentationToModel.createOAuthClient(session, rep, realm);
|
OAuthClientModel oauth = RepresentationToModel.createOAuthClient(session, rep, realm);
|
||||||
|
event.event(EventType.CREATE_OAUTH_CLIENT).client(oauth).success();
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(oauth)).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(oauth)).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Client " + rep.getName() + " already exists");
|
return Flows.errors().exists("Client " + rep.getName() + " already exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getClientPath(OAuthClientModel oauth) {
|
protected String getClientPath(OAuthClientModel oauth) {
|
||||||
|
@ -114,7 +125,7 @@ public class OAuthClientsResource {
|
||||||
if (oauth == null) {
|
if (oauth == null) {
|
||||||
throw new NotFoundException("OAuth Client not found");
|
throw new NotFoundException("OAuth Client not found");
|
||||||
}
|
}
|
||||||
OAuthClientResource oAuthClientResource = new OAuthClientResource(realm, auth, oauth, session);
|
OAuthClientResource oAuthClientResource = new OAuthClientResource(realm, auth, oauth, session, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(oAuthClientResource);
|
ResteasyProviderFactory.getInstance().injectProperties(oAuthClientResource);
|
||||||
//resourceContext.initResource(oAuthClientResource);
|
//resourceContext.initResource(oAuthClientResource);
|
||||||
return oAuthClientResource;
|
return oAuthClientResource;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventQuery;
|
import org.keycloak.events.EventQuery;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
|
@ -63,6 +64,7 @@ public class RealmAdminResource {
|
||||||
protected RealmAuth auth;
|
protected RealmAuth auth;
|
||||||
protected RealmModel realm;
|
protected RealmModel realm;
|
||||||
private TokenManager tokenManager;
|
private TokenManager tokenManager;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
@ -76,10 +78,11 @@ public class RealmAdminResource {
|
||||||
@Context
|
@Context
|
||||||
protected HttpHeaders headers;
|
protected HttpHeaders headers;
|
||||||
|
|
||||||
public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager) {
|
public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager, EventBuilder event) {
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.REALM);
|
auth.init(RealmAuth.Resource.REALM);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +105,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("applications")
|
@Path("applications")
|
||||||
public ApplicationsResource getApplications() {
|
public ApplicationsResource getApplications() {
|
||||||
ApplicationsResource applicationsResource = new ApplicationsResource(realm, auth);
|
ApplicationsResource applicationsResource = new ApplicationsResource(realm, auth, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(applicationsResource);
|
ResteasyProviderFactory.getInstance().injectProperties(applicationsResource);
|
||||||
//resourceContext.initResource(applicationsResource);
|
//resourceContext.initResource(applicationsResource);
|
||||||
return applicationsResource;
|
return applicationsResource;
|
||||||
|
@ -115,7 +118,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("applications-by-id")
|
@Path("applications-by-id")
|
||||||
public ApplicationsByIdResource getApplicationsById() {
|
public ApplicationsByIdResource getApplicationsById() {
|
||||||
ApplicationsByIdResource applicationsResource = new ApplicationsByIdResource(realm, auth);
|
ApplicationsByIdResource applicationsResource = new ApplicationsByIdResource(realm, auth, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(applicationsResource);
|
ResteasyProviderFactory.getInstance().injectProperties(applicationsResource);
|
||||||
//resourceContext.initResource(applicationsResource);
|
//resourceContext.initResource(applicationsResource);
|
||||||
return applicationsResource;
|
return applicationsResource;
|
||||||
|
@ -128,7 +131,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("oauth-clients")
|
@Path("oauth-clients")
|
||||||
public OAuthClientsResource getOAuthClients() {
|
public OAuthClientsResource getOAuthClients() {
|
||||||
OAuthClientsResource oauth = new OAuthClientsResource(realm, auth, session);
|
OAuthClientsResource oauth = new OAuthClientsResource(realm, auth, session, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(oauth);
|
ResteasyProviderFactory.getInstance().injectProperties(oauth);
|
||||||
//resourceContext.initResource(oauth);
|
//resourceContext.initResource(oauth);
|
||||||
return oauth;
|
return oauth;
|
||||||
|
@ -141,7 +144,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("oauth-clients-by-id")
|
@Path("oauth-clients-by-id")
|
||||||
public OAuthClientsByIdResource getOAuthClientsById() {
|
public OAuthClientsByIdResource getOAuthClientsById() {
|
||||||
OAuthClientsByIdResource oauth = new OAuthClientsByIdResource(realm, auth, session);
|
OAuthClientsByIdResource oauth = new OAuthClientsByIdResource(realm, auth, session, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(oauth);
|
ResteasyProviderFactory.getInstance().injectProperties(oauth);
|
||||||
//resourceContext.initResource(oauth);
|
//resourceContext.initResource(oauth);
|
||||||
return oauth;
|
return oauth;
|
||||||
|
@ -154,7 +157,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("roles")
|
@Path("roles")
|
||||||
public RoleContainerResource getRoleContainerResource() {
|
public RoleContainerResource getRoleContainerResource() {
|
||||||
return new RoleContainerResource(realm, auth, realm);
|
return new RoleContainerResource(realm, auth, realm, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,6 +180,9 @@ public class RealmAdminResource {
|
||||||
CacheUserProvider cache = (CacheUserProvider)session.userStorage();
|
CacheUserProvider cache = (CacheUserProvider)session.userStorage();
|
||||||
rep.setUserCacheEnabled(cache.isEnabled());
|
rep.setUserCacheEnabled(cache.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_REALM).success();
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
} else {
|
} else {
|
||||||
auth.requireAny();
|
auth.requireAny();
|
||||||
|
@ -184,6 +190,8 @@ public class RealmAdminResource {
|
||||||
RealmRepresentation rep = new RealmRepresentation();
|
RealmRepresentation rep = new RealmRepresentation();
|
||||||
rep.setRealm(realm.getName());
|
rep.setRealm(realm.getName());
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_REALM).success();
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,6 +227,8 @@ public class RealmAdminResource {
|
||||||
usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId());
|
usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_REALM).success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
||||||
|
@ -236,6 +246,8 @@ public class RealmAdminResource {
|
||||||
if (!new RealmManager(session).removeRealm(realm)) {
|
if (!new RealmManager(session).removeRealm(realm)) {
|
||||||
throw new NotFoundException("Realm doesn't exist");
|
throw new NotFoundException("Realm doesn't exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_REALM).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -245,7 +257,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("users")
|
@Path("users")
|
||||||
public UsersResource users() {
|
public UsersResource users() {
|
||||||
UsersResource users = new UsersResource(realm, auth, tokenManager);
|
UsersResource users = new UsersResource(realm, auth, tokenManager, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(users);
|
ResteasyProviderFactory.getInstance().injectProperties(users);
|
||||||
//resourceContext.initResource(users);
|
//resourceContext.initResource(users);
|
||||||
return users;
|
return users;
|
||||||
|
@ -253,7 +265,7 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
@Path("user-federation")
|
@Path("user-federation")
|
||||||
public UserFederationResource userFederation() {
|
public UserFederationResource userFederation() {
|
||||||
UserFederationResource fed = new UserFederationResource(realm, auth);
|
UserFederationResource fed = new UserFederationResource(realm, auth, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(fed);
|
ResteasyProviderFactory.getInstance().injectProperties(fed);
|
||||||
//resourceContext.initResource(fed);
|
//resourceContext.initResource(fed);
|
||||||
return fed;
|
return fed;
|
||||||
|
@ -266,7 +278,7 @@ public class RealmAdminResource {
|
||||||
*/
|
*/
|
||||||
@Path("roles-by-id")
|
@Path("roles-by-id")
|
||||||
public RoleByIdResource rolesById() {
|
public RoleByIdResource rolesById() {
|
||||||
RoleByIdResource resource = new RoleByIdResource(realm, auth);
|
RoleByIdResource resource = new RoleByIdResource(realm, auth, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
ResteasyProviderFactory.getInstance().injectProperties(resource);
|
||||||
//resourceContext.initResource(resource);
|
//resourceContext.initResource(resource);
|
||||||
return resource;
|
return resource;
|
||||||
|
@ -473,6 +485,6 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
@Path("identity-provider")
|
@Path("identity-provider")
|
||||||
public IdentityProvidersResource getIdentityProviderResource() {
|
public IdentityProvidersResource getIdentityProviderResource() {
|
||||||
return new IdentityProvidersResource(realm, session, this.auth);
|
return new IdentityProvidersResource(realm, session, this.auth, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart;
|
||||||
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
|
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.AdminRoles;
|
import org.keycloak.models.AdminRoles;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -33,6 +37,7 @@ import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -49,10 +54,12 @@ public class RealmsAdminResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RealmsAdminResource.class);
|
protected static final Logger logger = Logger.getLogger(RealmsAdminResource.class);
|
||||||
protected AdminAuth auth;
|
protected AdminAuth auth;
|
||||||
protected TokenManager tokenManager;
|
protected TokenManager tokenManager;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager) {
|
public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager, EventBuilder event) {
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final CacheControl noCache = new CacheControl();
|
public static final CacheControl noCache = new CacheControl();
|
||||||
|
@ -72,7 +79,6 @@ public class RealmsAdminResource {
|
||||||
@Context
|
@Context
|
||||||
protected KeycloakApplication keycloak;
|
protected KeycloakApplication keycloak;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of realms. This list is filtered based on what realms the caller is allowed to view.
|
* Returns a list of realms. This list is filtered based on what realms the caller is allowed to view.
|
||||||
*
|
*
|
||||||
|
@ -135,6 +141,9 @@ public class RealmsAdminResource {
|
||||||
|
|
||||||
URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
|
URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
|
||||||
logger.debugv("imported realm success, sending back: {0}", location.toString());
|
logger.debugv("imported realm success, sending back: {0}", location.toString());
|
||||||
|
|
||||||
|
event.event(EventType.IMPORT_REALM).detail(Details.REALM_NAME, realm.getName()).success();
|
||||||
|
|
||||||
return Response.created(location).build();
|
return Response.created(location).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
return Flows.errors().exists("Realm " + rep.getRealm() + " already exists");
|
||||||
|
@ -181,6 +190,8 @@ public class RealmsAdminResource {
|
||||||
URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
|
URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build();
|
||||||
return Response.created(location).build();
|
return Response.created(location).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.UPLOAD_REALM).detail(Details.REALM_NAME, realm.getName()).success();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
|
@ -225,7 +236,8 @@ public class RealmsAdminResource {
|
||||||
realmAuth = new RealmAuth(auth, realm.getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm())));
|
realmAuth = new RealmAuth(auth, realm.getApplicationByName(realmManager.getRealmAdminApplicationName(auth.getRealm())));
|
||||||
}
|
}
|
||||||
|
|
||||||
RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager);
|
event.detail(Details.REALM_NAME, realm.getName());
|
||||||
|
RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager, event);
|
||||||
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
ResteasyProviderFactory.getInstance().injectProperties(adminResource);
|
||||||
//resourceContext.initResource(adminResource);
|
//resourceContext.initResource(adminResource);
|
||||||
return adminResource;
|
return adminResource;
|
||||||
|
|
|
@ -3,7 +3,11 @@ package org.keycloak.services.resources.admin;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.OAuthClientModel;
|
import org.keycloak.models.OAuthClientModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleModel;
|
import org.keycloak.models.RoleModel;
|
||||||
|
@ -18,6 +22,8 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -31,12 +37,17 @@ public class RoleByIdResource extends RoleResource {
|
||||||
protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
|
protected static final Logger logger = Logger.getLogger(RoleByIdResource.class);
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final RealmAuth auth;
|
private final RealmAuth auth;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public RoleByIdResource(RealmModel realm, RealmAuth auth) {
|
@Context
|
||||||
|
protected KeycloakSession session;
|
||||||
|
|
||||||
|
public RoleByIdResource(RealmModel realm, RealmAuth auth, EventBuilder event) {
|
||||||
super(realm);
|
super(realm);
|
||||||
|
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +63,12 @@ public class RoleByIdResource extends RoleResource {
|
||||||
public RoleRepresentation getRole(final @PathParam("role-id") String id) {
|
public RoleRepresentation getRole(final @PathParam("role-id") String id) {
|
||||||
RoleModel roleModel = getRoleModel(id);
|
RoleModel roleModel = getRoleModel(id);
|
||||||
auth.requireView();
|
auth.requireView();
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, roleModel.getId())
|
||||||
|
.detail(Details.ROLE_NAME, roleModel.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return getRole(roleModel);
|
return getRole(roleModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +105,11 @@ public class RoleByIdResource extends RoleResource {
|
||||||
RoleModel role = getRoleModel(id);
|
RoleModel role = getRoleModel(id);
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
deleteRole(role);
|
deleteRole(role);
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,6 +125,11 @@ public class RoleByIdResource extends RoleResource {
|
||||||
RoleModel role = getRoleModel(id);
|
RoleModel role = getRoleModel(id);
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
updateRole(rep, role);
|
updateRole(rep, role);
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +145,11 @@ public class RoleByIdResource extends RoleResource {
|
||||||
RoleModel role = getRoleModel(id);
|
RoleModel role = getRoleModel(id);
|
||||||
auth.requireManage();
|
auth.requireManage();
|
||||||
addComposites(roles, role);
|
addComposites(roles, role);
|
||||||
|
|
||||||
|
event.event(EventType.MAKE_ROLE_COMPOSITE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,9 @@ package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
import org.jboss.resteasy.annotations.cache.NoCache;
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.spi.NotFoundException;
|
import org.jboss.resteasy.spi.NotFoundException;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -22,6 +25,7 @@ import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -34,12 +38,14 @@ public class RoleContainerResource extends RoleResource {
|
||||||
private final RealmModel realm;
|
private final RealmModel realm;
|
||||||
private final RealmAuth auth;
|
private final RealmAuth auth;
|
||||||
protected RoleContainerModel roleContainer;
|
protected RoleContainerModel roleContainer;
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
public RoleContainerResource(RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer) {
|
public RoleContainerResource(RealmModel realm, RealmAuth auth, RoleContainerModel roleContainer, EventBuilder event) {
|
||||||
super(realm);
|
super(realm);
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.roleContainer = roleContainer;
|
this.roleContainer = roleContainer;
|
||||||
|
this.event = event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,6 +64,9 @@ public class RoleContainerResource extends RoleResource {
|
||||||
for (RoleModel roleModel : roleModels) {
|
for (RoleModel roleModel : roleModels) {
|
||||||
roles.add(ModelToRepresentation.toRepresentation(roleModel));
|
roles.add(ModelToRepresentation.toRepresentation(roleModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_ROLES).success();
|
||||||
|
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +85,12 @@ public class RoleContainerResource extends RoleResource {
|
||||||
try {
|
try {
|
||||||
RoleModel role = roleContainer.addRole(rep.getName());
|
RoleModel role = roleContainer.addRole(rep.getName());
|
||||||
role.setDescription(rep.getDescription());
|
role.setDescription(rep.getDescription());
|
||||||
|
|
||||||
|
event.event(EventType.CREATE_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
||||||
|
@ -99,6 +114,12 @@ public class RoleContainerResource extends RoleResource {
|
||||||
if (roleModel == null) {
|
if (roleModel == null) {
|
||||||
throw new NotFoundException("Could not find role: " + roleName);
|
throw new NotFoundException("Could not find role: " + roleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, roleModel.getId())
|
||||||
|
.detail(Details.ROLE_NAME, roleModel.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return getRole(roleModel);
|
return getRole(roleModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +139,11 @@ public class RoleContainerResource extends RoleResource {
|
||||||
throw new NotFoundException("Could not find role: " + roleName);
|
throw new NotFoundException("Could not find role: " + roleName);
|
||||||
}
|
}
|
||||||
deleteRole(role);
|
deleteRole(role);
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,6 +165,12 @@ public class RoleContainerResource extends RoleResource {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
updateRole(rep, role);
|
updateRole(rep, role);
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_ROLE)
|
||||||
|
.detail(Details.ROLE_ID, role.getId())
|
||||||
|
.detail(Details.ROLE_NAME, role.getName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
return Flows.errors().exists("Role with name " + rep.getName() + " already exists");
|
||||||
|
|
|
@ -3,7 +3,10 @@ package org.keycloak.services.resources.admin;
|
||||||
import org.keycloak.Version;
|
import org.keycloak.Version;
|
||||||
import org.keycloak.broker.provider.IdentityProvider;
|
import org.keycloak.broker.provider.IdentityProvider;
|
||||||
import org.keycloak.broker.provider.IdentityProviderFactory;
|
import org.keycloak.broker.provider.IdentityProviderFactory;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventListenerProvider;
|
import org.keycloak.events.EventListenerProvider;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.exportimport.ApplicationImporter;
|
import org.keycloak.exportimport.ApplicationImporter;
|
||||||
import org.keycloak.exportimport.ApplicationImporterFactory;
|
import org.keycloak.exportimport.ApplicationImporterFactory;
|
||||||
import org.keycloak.freemarker.Theme;
|
import org.keycloak.freemarker.Theme;
|
||||||
|
@ -23,6 +26,7 @@ import org.keycloak.social.SocialIdentityProvider;
|
||||||
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -41,6 +45,12 @@ public class ServerInfoAdminResource {
|
||||||
@Context
|
@Context
|
||||||
private KeycloakSession session;
|
private KeycloakSession session;
|
||||||
|
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
|
public ServerInfoAdminResource(EventBuilder event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of themes, social providers, auth providers, and event listeners available on this server
|
* Returns a list of themes, social providers, auth providers, and event listeners available on this server
|
||||||
*
|
*
|
||||||
|
@ -60,6 +70,12 @@ public class ServerInfoAdminResource {
|
||||||
setProviders(info);
|
setProviders(info);
|
||||||
setProtocolMapperTypes(info);
|
setProtocolMapperTypes(info);
|
||||||
setBuiltinProtocolMappers(info);
|
setBuiltinProtocolMappers(info);
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_SERVER_INFO)
|
||||||
|
.detail(Details.SERVER_VERSION, info.version)
|
||||||
|
.detail(Details.SERVER_TIME, info.serverTime)
|
||||||
|
.success();
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ import org.keycloak.models.UserFederationProvider;
|
||||||
import org.keycloak.models.UserFederationProviderFactory;
|
import org.keycloak.models.UserFederationProviderFactory;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.constants.KerberosConstants;
|
import org.keycloak.constants.KerberosConstants;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
|
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
|
||||||
|
@ -30,6 +33,7 @@ import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -46,15 +50,18 @@ public class UserFederationResource {
|
||||||
|
|
||||||
protected RealmAuth auth;
|
protected RealmAuth auth;
|
||||||
|
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected UriInfo uriInfo;
|
protected UriInfo uriInfo;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected KeycloakSession session;
|
protected KeycloakSession session;
|
||||||
|
|
||||||
public UserFederationResource(RealmModel realm, RealmAuth auth) {
|
public UserFederationResource(RealmModel realm, RealmAuth auth, EventBuilder event) {
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.USER);
|
auth.init(RealmAuth.Resource.USER);
|
||||||
}
|
}
|
||||||
|
@ -77,11 +84,14 @@ public class UserFederationResource {
|
||||||
rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions());
|
rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions());
|
||||||
providers.add(rep);
|
providers.add(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_PROVIDER_FACTORIES).success();
|
||||||
|
|
||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get List of available provider factories
|
* Get a provider
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@ -98,6 +108,9 @@ public class UserFederationResource {
|
||||||
UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation();
|
UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation();
|
||||||
rep.setId(factory.getId());
|
rep.setId(factory.getId());
|
||||||
rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions());
|
rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions());
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_PROVIDER).detail(Details.PROVIDER_ID, rep.getId()).success();
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
throw new NotFoundException("Could not find provider");
|
throw new NotFoundException("Could not find provider");
|
||||||
|
@ -123,6 +136,11 @@ public class UserFederationResource {
|
||||||
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||||
checkKerberosCredential(model);
|
checkKerberosCredential(model);
|
||||||
|
|
||||||
|
event.event(EventType.CREATE_PROVIDER)
|
||||||
|
.detail(Details.PROVIDER_ID, model.getId())
|
||||||
|
.detail(Details.PROVIDER_NAME, model.getProviderName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +164,11 @@ public class UserFederationResource {
|
||||||
realm.updateUserFederationProvider(model);
|
realm.updateUserFederationProvider(model);
|
||||||
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||||
checkKerberosCredential(model);
|
checkKerberosCredential(model);
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_PROVIDER)
|
||||||
|
.detail(Details.PROVIDER_ID, model.getId())
|
||||||
|
.detail(Details.PROVIDER_NAME, model.getProviderName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -161,9 +184,16 @@ public class UserFederationResource {
|
||||||
auth.requireView();
|
auth.requireView();
|
||||||
for (UserFederationProviderModel model : realm.getUserFederationProviders()) {
|
for (UserFederationProviderModel model : realm.getUserFederationProviders()) {
|
||||||
if (model.getId().equals(id)) {
|
if (model.getId().equals(id)) {
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_PROVIDER)
|
||||||
|
.detail(Details.PROVIDER_ID, model.getId())
|
||||||
|
.detail(Details.PROVIDER_NAME, model.getProviderName())
|
||||||
|
.success();
|
||||||
|
|
||||||
return ModelToRepresentation.toRepresentation(model);
|
return ModelToRepresentation.toRepresentation(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NotFoundException("could not find provider");
|
throw new NotFoundException("could not find provider");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +209,11 @@ public class UserFederationResource {
|
||||||
UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1, null, -1, -1, 0);
|
UserFederationProviderModel model = new UserFederationProviderModel(id, null, null, -1, null, -1, -1, 0);
|
||||||
realm.removeUserFederationProvider(model);
|
realm.removeUserFederationProvider(model);
|
||||||
new UsersSyncManager().removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), model);
|
new UsersSyncManager().removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), model);
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_PROVIDER)
|
||||||
|
.detail(Details.PROVIDER_ID, model.getId())
|
||||||
|
.detail(Details.PROVIDER_NAME, model.getProviderName())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ import org.jboss.resteasy.spi.NotFoundException;
|
||||||
import org.keycloak.ClientConnection;
|
import org.keycloak.ClientConnection;
|
||||||
import org.keycloak.email.EmailException;
|
import org.keycloak.email.EmailException;
|
||||||
import org.keycloak.email.EmailProvider;
|
import org.keycloak.email.EmailProvider;
|
||||||
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.EventBuilder;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ApplicationModel;
|
import org.keycloak.models.ApplicationModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
|
@ -24,7 +27,6 @@ import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
|
|
||||||
import org.keycloak.protocol.oidc.TokenManager;
|
import org.keycloak.protocol.oidc.TokenManager;
|
||||||
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
import org.keycloak.protocol.oidc.utils.RedirectUtils;
|
||||||
import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
|
import org.keycloak.representations.idm.ApplicationMappingsRepresentation;
|
||||||
|
@ -57,6 +59,7 @@ import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import javax.ws.rs.core.UriBuilder;
|
import javax.ws.rs.core.UriBuilder;
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -80,6 +83,8 @@ public class UsersResource {
|
||||||
|
|
||||||
private TokenManager tokenManager;
|
private TokenManager tokenManager;
|
||||||
|
|
||||||
|
private EventBuilder event;
|
||||||
|
|
||||||
@Context
|
@Context
|
||||||
protected ClientConnection clientConnection;
|
protected ClientConnection clientConnection;
|
||||||
|
|
||||||
|
@ -92,10 +97,11 @@ public class UsersResource {
|
||||||
@Context
|
@Context
|
||||||
protected HttpHeaders headers;
|
protected HttpHeaders headers;
|
||||||
|
|
||||||
public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager) {
|
public UsersResource(RealmModel realm, RealmAuth auth, TokenManager tokenManager, EventBuilder event) {
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
|
this.event = event;
|
||||||
|
|
||||||
auth.init(RealmAuth.Resource.USER);
|
auth.init(RealmAuth.Resource.USER);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +126,11 @@ public class UsersResource {
|
||||||
}
|
}
|
||||||
updateUserFromRep(user, rep);
|
updateUserFromRep(user, rep);
|
||||||
|
|
||||||
|
event.event(EventType.UPDATE_USER)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
if (session.getTransaction().isActive()) {
|
if (session.getTransaction().isActive()) {
|
||||||
session.getTransaction().commit();
|
session.getTransaction().commit();
|
||||||
}
|
}
|
||||||
|
@ -156,6 +167,11 @@ public class UsersResource {
|
||||||
UserModel user = session.users().addUser(realm, rep.getUsername());
|
UserModel user = session.users().addUser(realm, rep.getUsername());
|
||||||
updateUserFromRep(user, rep);
|
updateUserFromRep(user, rep);
|
||||||
|
|
||||||
|
event.event(EventType.CREATE_USER)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
if (session.getTransaction().isActive()) {
|
if (session.getTransaction().isActive()) {
|
||||||
session.getTransaction().commit();
|
session.getTransaction().commit();
|
||||||
}
|
}
|
||||||
|
@ -220,6 +236,12 @@ public class UsersResource {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new NotFoundException("User not found");
|
throw new NotFoundException("User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_USER)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
return ModelToRepresentation.toRepresentation(user);
|
return ModelToRepresentation.toRepresentation(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +267,12 @@ public class UsersResource {
|
||||||
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
|
UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session);
|
||||||
reps.add(rep);
|
reps.add(rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_USER_SESSIONS)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
return reps;
|
return reps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,6 +304,12 @@ public class UsersResource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.VIEW_USER_SOCIAL_LOGINS)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,10 +360,16 @@ public class UsersResource {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new NotFoundException("User not found");
|
throw new NotFoundException("User not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
|
List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
|
||||||
for (UserSessionModel userSession : userSessions) {
|
for (UserSessionModel userSession : userSessions) {
|
||||||
AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event.event(EventType.INVALIDATE_USER_SESSIONS)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -350,6 +390,12 @@ public class UsersResource {
|
||||||
|
|
||||||
boolean removed = new UserManager(session).removeUser(realm, user);
|
boolean removed = new UserManager(session).removeUser(realm, user);
|
||||||
if (removed) {
|
if (removed) {
|
||||||
|
|
||||||
|
event.event(EventType.DELETE_USER)
|
||||||
|
.user(user)
|
||||||
|
.detail(Details.USERNAME, user.getUsername())
|
||||||
|
.success();
|
||||||
|
|
||||||
return Response.noContent().build();
|
return Response.noContent().build();
|
||||||
} else {
|
} else {
|
||||||
return Flows.errors().error("User couldn't be deleted", Response.Status.BAD_REQUEST);
|
return Flows.errors().error("User couldn't be deleted", Response.Status.BAD_REQUEST);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.events.Event;
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventGroup;
|
||||||
import org.keycloak.events.EventStoreProvider;
|
import org.keycloak.events.EventStoreProvider;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
@ -185,6 +186,7 @@ public class EventStoreProviderTest {
|
||||||
Event e = new Event();
|
Event e = new Event();
|
||||||
e.setTime(time);
|
e.setTime(time);
|
||||||
e.setType(event);
|
e.setType(event);
|
||||||
|
e.setEventGroup(EventGroup.USER);
|
||||||
e.setRealmId(realmId);
|
e.setRealmId(realmId);
|
||||||
e.setClientId(clientId);
|
e.setClientId(clientId);
|
||||||
e.setUserId(userId);
|
e.setUserId(userId);
|
||||||
|
|
Loading…
Reference in a new issue