diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml index 70860652e2..9325a40964 100644 --- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml +++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml @@ -6,21 +6,16 @@ - - - + + + + - + - - - - - - @@ -29,6 +24,5 @@ - \ No newline at end of file diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java index 5b12c102f5..5b39f7e2cc 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmEventsConfigRepresentation.java @@ -13,7 +13,6 @@ public class RealmEventsConfigRepresentation { protected List enabledEventTypes; protected Boolean adminEventsEnabled; - protected List adminEnabledEventOperations; protected Boolean adminEventsDetailsEnabled; public boolean isEventsEnabled() { @@ -56,14 +55,6 @@ public class RealmEventsConfigRepresentation { this.adminEventsEnabled = adminEventsEnabled; } - public List getAdminEnabledEventOperations() { - return adminEnabledEventOperations; - } - - public void setAdminEnabledEventOperations(List adminEnabledEventOperations) { - this.adminEnabledEventOperations = adminEnabledEventOperations; - } - public Boolean isAdminEventsDetailsEnabled() { return adminEventsDetailsEnabled; } diff --git a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java index 2c9be559fa..0240a8dbe4 100755 --- a/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/RealmRepresentation.java @@ -64,7 +64,6 @@ public class RealmRepresentation { protected List enabledEventTypes; protected Boolean adminEventsEnabled; - protected List adminEnabledEventOperations; protected Boolean adminEventsDetailsEnabled; private List identityProviders; @@ -521,14 +520,6 @@ public class RealmRepresentation { this.adminEventsEnabled = adminEventsEnabled; } - public List getAdminEnabledEventOperations() { - return adminEnabledEventOperations; - } - - public void setAdminEnabledEventOperations(List adminEnabledEventOperations) { - this.adminEnabledEventOperations = adminEnabledEventOperations; - } - public Boolean isAdminEventsDetailsEnabled() { return adminEventsDetailsEnabled; } diff --git a/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java b/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java index fedd2bfadc..42255010b7 100644 --- a/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java +++ b/events/api/src/main/java/org/keycloak/events/admin/AdminEvent.java @@ -1,13 +1,13 @@ package org.keycloak.events.admin; -import java.util.Map; - /** * @author Stian Thorgersen */ public class AdminEvent { private long time; + + private String realmId; private AuthDetails authDetails; @@ -31,6 +31,19 @@ public class AdminEvent { public void setTime(long time) { this.time = time; } + + /** + * Returns the id of the realm + * + * @return + */ + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } /** * Returns authentication details diff --git a/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java b/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java index 45cd9e272d..d7b5fe4ed0 100644 --- a/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java +++ b/events/api/src/main/java/org/keycloak/events/admin/AdminEventQuery.java @@ -8,28 +8,36 @@ import java.util.List; public interface AdminEventQuery { /** - * Search by authentication realm + * Search by resource realm * - * @param realm realm name + * @param realmId realm id * @return Associated AdminEventQuery for method chaining */ - AdminEventQuery authRealm(String realm); + AdminEventQuery realm(String realmId); + + /** + * Search by authentication realm + * + * @param realmId realm name + * @return Associated AdminEventQuery for method chaining + */ + AdminEventQuery authRealm(String realmId); /** * Search by authenticated client * - * @param client client uuid + * @param clientId client uuid * @return Associated AdminEventQuery for method chaining */ - AdminEventQuery authClient(String client); + AdminEventQuery authClient(String clientId); /** * Search by authenticated user * - * @param user user uuid + * @param userId user uuid * @return Associated AdminEventQuery for method chaining */ - AdminEventQuery authUser(String user); + AdminEventQuery authUser(String userId); /** * Search by request ip address diff --git a/events/api/src/main/java/org/keycloak/events/admin/OperationType.java b/events/api/src/main/java/org/keycloak/events/admin/OperationType.java index ddce0e2694..ca3ae20a09 100755 --- a/events/api/src/main/java/org/keycloak/events/admin/OperationType.java +++ b/events/api/src/main/java/org/keycloak/events/admin/OperationType.java @@ -5,20 +5,9 @@ package org.keycloak.events.admin; */ public enum OperationType { - VIEW(false), - CREATE(true), - UPDATE(true), - DELETE(true), - ACTION(false); - - private boolean saveByDefault; - - OperationType(boolean saveByDefault) { - this.saveByDefault = saveByDefault; - } - - public boolean isSaveByDefault() { - return saveByDefault; - } + CREATE, + UPDATE, + DELETE, + ACTION; } diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java b/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java index f45cd328e0..b814c5a8d7 100644 --- a/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/AdminEventEntity.java @@ -19,16 +19,19 @@ public class AdminEventEntity { @Column(name="ADMIN_EVENT_TIME") private long time; + @Column(name="REALM_ID") + private String realmId; + @Column(name="OPERATION_TYPE") private String operationType; - @Column(name="REALM_ID") + @Column(name="AUTH_REALM_ID") private String authRealmId; - @Column(name="CLIENT_ID") + @Column(name="AUTH_CLIENT_ID") private String authClientId; - @Column(name="USER_ID") + @Column(name="AUTH_USER_ID") private String authUserId; @Column(name="IP_ADDRESS") @@ -59,6 +62,14 @@ public class AdminEventEntity { this.time = time; } + public String getRealmId() { + return realmId; + } + + public void setRealmId(String realmId) { + this.realmId = realmId; + } + public String getOperationType() { return operationType; } diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java index edb19c069b..f9ea14d432 100644 --- a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaAdminEventQuery.java @@ -39,6 +39,12 @@ public class JpaAdminEventQuery implements AdminEventQuery { root = cq.from(AdminEventEntity.class); predicates = new ArrayList(); } + + @Override + public AdminEventQuery realm(String realmId) { + predicates.add(cb.equal(root.get("realmId"), realmId)); + return this; + } @Override public AdminEventQuery operation(OperationType... operations) { @@ -51,20 +57,20 @@ public class JpaAdminEventQuery implements AdminEventQuery { } @Override - public AdminEventQuery authRealm(String realmId) { - predicates.add(cb.equal(root.get("authRealmId"), realmId)); + public AdminEventQuery authRealm(String authRealmId) { + predicates.add(cb.equal(root.get("authRealmId"), authRealmId)); return this; } @Override - public AdminEventQuery authClient(String clientId) { - predicates.add(cb.equal(root.get("authClientId"), clientId)); + public AdminEventQuery authClient(String authClientId) { + predicates.add(cb.equal(root.get("authClientId"), authClientId)); return this; } @Override - public AdminEventQuery authUser(String userId) { - predicates.add(cb.equal(root.get("authUserId"), userId)); + public AdminEventQuery authUser(String authUserId) { + predicates.add(cb.equal(root.get("authUserId"), authUserId)); return this; } @@ -144,5 +150,5 @@ public class JpaAdminEventQuery implements AdminEventQuery { return events; } - + } diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java index 3088f1ea18..d3ff4f8830 100755 --- a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java +++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventStoreProvider.java @@ -70,13 +70,13 @@ public class JpaEventStoreProvider implements EventStoreProvider { } @Override - public void clearAdmin(String authRealmId) { - em.createQuery("delete from AdminEventEntity where authRealmId = :authRealmId").setParameter("authRealmId", authRealmId).executeUpdate(); + public void clearAdmin(String realmId) { + em.createQuery("delete from AdminEventEntity where realmId = :realmId").setParameter("realmId", realmId).executeUpdate(); } @Override - public void clearAdmin(String authRealmId, long olderThan) { - em.createQuery("delete from AdminEventEntity where authRealmId = :authRealmId and time < :time").setParameter("authRealmId", authRealmId).setParameter("time", olderThan).executeUpdate(); + public void clearAdmin(String realmId, long olderThan) { + em.createQuery("delete from AdminEventEntity where realmId = :realmId and time < :time").setParameter("realmId", realmId).setParameter("time", olderThan).executeUpdate(); } @Override @@ -130,6 +130,7 @@ public class JpaEventStoreProvider implements EventStoreProvider { AdminEventEntity adminEventEntity = new AdminEventEntity(); adminEventEntity.setId(UUID.randomUUID().toString()); adminEventEntity.setTime(adminEvent.getTime()); + adminEventEntity.setRealmId(adminEvent.getRealmId()); setAuthDetails(adminEventEntity, adminEvent.getAuthDetails()); adminEventEntity.setOperationType(adminEvent.getOperationType().toString()); adminEventEntity.setResourcePath(adminEvent.getResourcePath()); @@ -144,6 +145,7 @@ public class JpaEventStoreProvider implements EventStoreProvider { static AdminEvent convertAdminEvent(AdminEventEntity adminEventEntity) { AdminEvent adminEvent = new AdminEvent(); adminEvent.setTime(adminEventEntity.getTime()); + adminEvent.setRealmId(adminEventEntity.getRealmId()); setAuthDetails(adminEvent, adminEventEntity); adminEvent.setOperationType(OperationType.valueOf(adminEventEntity.getOperationType())); adminEvent.setResourcePath(adminEventEntity.getResourcePath()); diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java index 4cc366c688..c614d76f08 100644 --- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java +++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoAdminEventQuery.java @@ -26,6 +26,12 @@ public class MongoAdminEventQuery implements AdminEventQuery{ this.audit = audit; query = new BasicDBObject(); } + + @Override + public AdminEventQuery realm(String realmId) { + query.put("realmId", realmId); + return this; + } @Override public AdminEventQuery operation(OperationType... operations) { @@ -38,26 +44,26 @@ public class MongoAdminEventQuery implements AdminEventQuery{ } @Override - public AdminEventQuery authRealm(String realmId) { - query.put("realmId", realmId); + public AdminEventQuery authRealm(String authRealmId) { + query.put("authRealmId", authRealmId); return this; } @Override - public AdminEventQuery authClient(String clientId) { - query.put("clientId", clientId); + public AdminEventQuery authClient(String authClientId) { + query.put("authClientId", authClientId); return this; } @Override - public AdminEventQuery authUser(String userId) { - query.put("userId", userId); + public AdminEventQuery authUser(String authUserId) { + query.put("authUserId", authUserId); return this; } @Override public AdminEventQuery authIpAddress(String ipAddress) { - query.put("ipAddress", ipAddress); + query.put("authIpAddress", ipAddress); return this; } @@ -122,5 +128,5 @@ public class MongoAdminEventQuery implements AdminEventQuery{ return events; } - + } diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java index 4b0dd2c910..27e1ea5645 100755 --- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java +++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventStoreProvider.java @@ -137,6 +137,7 @@ public class MongoEventStoreProvider implements EventStoreProvider { private static DBObject convertAdminEvent(AdminEvent adminEvent, boolean includeRepresentation) { BasicDBObject e = new BasicDBObject(); e.put("time", adminEvent.getTime()); + e.put("realmId", adminEvent.getRealmId()); e.put("operationType", adminEvent.getOperationType().toString()); setAuthDetails(e, adminEvent.getAuthDetails()); e.put("resourcePath", adminEvent.getResourcePath()); @@ -152,6 +153,7 @@ public class MongoEventStoreProvider implements EventStoreProvider { static AdminEvent convertAdminEvent(BasicDBObject o) { AdminEvent adminEvent = new AdminEvent(); adminEvent.setTime(o.getLong("time")); + adminEvent.setRealmId(o.getString("realmId")); adminEvent.setOperationType(OperationType.valueOf(o.getString("operationType"))); setAuthDetails(adminEvent, o); adminEvent.setResourcePath(o.getString("resourcePath")); @@ -164,18 +166,18 @@ public class MongoEventStoreProvider implements EventStoreProvider { } private static void setAuthDetails(BasicDBObject e, AuthDetails authDetails) { - e.put("realmId", authDetails.getRealmId()); - e.put("clientId", authDetails.getClientId()); - e.put("userId", authDetails.getUserId()); - e.put("ipAddress", authDetails.getIpAddress()); + e.put("authRealmId", authDetails.getRealmId()); + e.put("authClientId", authDetails.getClientId()); + e.put("authUserId", authDetails.getUserId()); + e.put("authIpAddress", authDetails.getIpAddress()); } private static void setAuthDetails(AdminEvent adminEvent, BasicDBObject o) { AuthDetails authDetails = new AuthDetails(); - authDetails.setRealmId(o.getString("realmId")); - authDetails.setClientId(o.getString("clientId")); - authDetails.setUserId(o.getString("userId")); - authDetails.setIpAddress(o.getString("ipAddress")); + authDetails.setRealmId(o.getString("authRealmId")); + authDetails.setClientId(o.getString("authClientId")); + authDetails.setUserId(o.getString("authUserId")); + authDetails.setIpAddress(o.getString("authIpAddress")); adminEvent.setAuthDetails(authDetails); } diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java index 830b7b52d7..6b3a5da6c7 100644 --- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemAdminEventQuery.java @@ -25,6 +25,18 @@ public class MemAdminEventQuery implements AdminEventQuery { this.adminEvents = events; } + + @Override + public AdminEventQuery realm(String realmId) { + Iterator itr = adminEvents.iterator(); + while (itr.hasNext()) { + if (!itr.next().getRealmId().equals(realmId)) { + itr.remove(); + } + } + return this; + } + @Override public AdminEventQuery operation(OperationType... operations) { Iterator itr = this.adminEvents.iterator(); @@ -45,10 +57,10 @@ public class MemAdminEventQuery implements AdminEventQuery { } @Override - public AdminEventQuery authRealm(String realmId) { + public AdminEventQuery authRealm(String authRealmId) { Iterator itr = adminEvents.iterator(); while (itr.hasNext()) { - if (!itr.next().getAuthDetails().getRealmId().equals(realmId)) { + if (!itr.next().getAuthDetails().getRealmId().equals(authRealmId)) { itr.remove(); } } @@ -56,10 +68,10 @@ public class MemAdminEventQuery implements AdminEventQuery { } @Override - public AdminEventQuery authClient(String clientId) { + public AdminEventQuery authClient(String authClientId) { Iterator itr = adminEvents.iterator(); while (itr.hasNext()) { - if (!itr.next().getAuthDetails().getClientId().equals(clientId)) { + if (!itr.next().getAuthDetails().getClientId().equals(authClientId)) { itr.remove(); } } @@ -67,10 +79,10 @@ public class MemAdminEventQuery implements AdminEventQuery { } @Override - public AdminEventQuery authUser(String userId) { + public AdminEventQuery authUser(String authUserId) { Iterator itr = adminEvents.iterator(); while (itr.hasNext()) { - if (!itr.next().getAuthDetails().getUserId().equals(userId)) { + if (!itr.next().getAuthDetails().getUserId().equals(authUserId)) { itr.remove(); } } diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java index 7dd46060e8..e0b2d4cc30 100755 --- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java +++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventStoreProvider.java @@ -88,7 +88,7 @@ public class MemEventStoreProvider implements EventStoreProvider { synchronized(adminEvents) { Iterator itr = adminEvents.iterator(); while (itr.hasNext()) { - if (itr.next().getAuthDetails().getRealmId().equals(realmId)) { + if (itr.next().getRealmId().equals(realmId)) { itr.remove(); } } @@ -101,7 +101,7 @@ public class MemEventStoreProvider implements EventStoreProvider { Iterator itr = adminEvents.iterator(); while (itr.hasNext()) { AdminEvent e = itr.next(); - if (e.getAuthDetails().getRealmId().equals(realmId) && e.getTime() < olderThan) { + if (e.getRealmId().equals(realmId) && e.getTime() < olderThan) { itr.remove(); } } diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js index 52e7fac146..f60e20e65f 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js @@ -1197,12 +1197,6 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE 'tags': serverInfo.enums['eventType'] }; - $scope.adminEnabledEventOperationsOptions = { - 'multiple': true, - 'simple_tags': true, - 'tags': serverInfo.enums['operationType'] - }; - var oldCopy = angular.copy($scope.eventsConfig); $scope.changed = false; @@ -1327,7 +1321,6 @@ module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, rea max : 5, first : 0 } - $scope.query.authRealm = 'master'; $scope.adminEnabledEventOperationsOptions = { 'multiple': true, @@ -1350,7 +1343,7 @@ module.controller('RealmAdminEventsCtrl', function($scope, RealmAdminEvents, rea $scope.query.max = 5; $scope.query.operationTypes = ''; $scope.query.resourcePath = ''; - $scope.query.authRealm = 'master'; + $scope.query.authRealm = ''; $scope.query.authClient = ''; $scope.query.authUser = ''; $scope.query.authIpAddress = ''; diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html index 7168aab6af..8469d71f70 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-admin.html @@ -61,12 +61,11 @@
Authentication Details -
+
-
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html index 7d05980b2c..11c2f0074d 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-events-config.html @@ -1,5 +1,8 @@
-

Events {{realm.realm|capitalize}} Events

+

+ Events Config {{realm.realm|capitalize}} + Displays configuration options to enable persistence of user and admin events. +

-
- - -
- -
- - -
-
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java index 34763747fc..dca2067d98 100755 --- a/model/api/src/main/java/org/keycloak/models/RealmModel.java +++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java @@ -237,10 +237,6 @@ public interface RealmModel extends RoleContainerModel { void setAdminEventsEnabled(boolean enabled); - Set getAdminEnabledEventOperations(); - - void setAdminEnabledEventOperations(Set adminEnabledEventOperations); - boolean isAdminEventsDetailsEnabled(); void setAdminEventsDetailsEnabled(boolean enabled); diff --git a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java index cbb4c6d20d..718a1c5ed1 100755 --- a/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java +++ b/model/api/src/main/java/org/keycloak/models/entities/RealmEntity.java @@ -65,7 +65,6 @@ public class RealmEntity extends AbstractIdentifiableEntity { private List enabledEventTypes = new ArrayList(); protected boolean adminEventsEnabled; - protected List adminEnabledEventOperations = new ArrayList();; protected boolean adminEventsDetailsEnabled; private String masterAdminClient; @@ -403,14 +402,6 @@ public class RealmEntity extends AbstractIdentifiableEntity { this.adminEventsEnabled = adminEventsEnabled; } - public List getAdminEnabledEventOperations() { - return adminEnabledEventOperations; - } - - public void setAdminEnabledEventOperations(List adminEnabledEventOperations) { - this.adminEnabledEventOperations = adminEnabledEventOperations; - } - public boolean isAdminEventsDetailsEnabled() { return adminEventsDetailsEnabled; } diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index 144c140bc9..6148f8ebed 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -195,10 +195,6 @@ public class ModelToRepresentation { rep.setAdminEventsEnabled(realm.isAdminEventsEnabled()); - if(realm.getAdminEnabledEventOperations() != null) { - rep.setAdminEnabledEventOperations(new LinkedList(realm.getAdminEnabledEventOperations())); - } - rep.setAdminEventsDetailsEnabled(realm.isAdminEventsDetailsEnabled()); return rep; diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 70976a8583..578ecc9483 100755 --- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -417,7 +417,6 @@ public class RepresentationToModel { if (rep.getEnabledEventTypes() != null) realm.setEnabledEventTypes(new HashSet<>(rep.getEnabledEventTypes())); if (rep.isAdminEventsEnabled() != null) realm.setAdminEventsEnabled(rep.isAdminEventsEnabled()); - if (rep.getAdminEnabledEventOperations() != null) realm.setAdminEnabledEventOperations(new HashSet<>(rep.getAdminEnabledEventOperations())); if (rep.isAdminEventsDetailsEnabled() != null) realm.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled()); diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java index 65019819d4..d8351027b3 100755 --- a/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java +++ b/model/file/src/main/java/org/keycloak/models/file/adapter/RealmAdapter.java @@ -968,20 +968,6 @@ public class RealmAdapter implements RealmModel { realm.setAdminEventsEnabled(enabled); } - @Override - public Set getAdminEnabledEventOperations() { - return new HashSet(realm.getAdminEnabledEventOperations()); - } - - @Override - public void setAdminEnabledEventOperations(Set adminEnabledEventOperations) { - if (adminEnabledEventOperations != null) { - realm.setAdminEnabledEventOperations(new ArrayList(adminEnabledEventOperations)); - } else { - realm.setAdminEnabledEventOperations(Collections.EMPTY_LIST); - } - } - @Override public boolean isAdminEventsDetailsEnabled() { return realm.isAdminEventsDetailsEnabled(); diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java index dfa657f1b8..33f2356106 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java @@ -762,18 +762,6 @@ public class RealmAdapter implements RealmModel { updated.setAdminEventsEnabled(enabled); } - @Override - public Set getAdminEnabledEventOperations() { - if (updated != null) return updated.getAdminEnabledEventOperations(); - return cached.getAdminEnabledEventOperations(); - } - - @Override - public void setAdminEnabledEventOperations(Set adminEnabledEventOperations) { - getDelegateForUpdate(); - updated.setAdminEnabledEventOperations(adminEnabledEventOperations); - } - @Override public boolean isAdminEventsDetailsEnabled() { if (updated != null) return updated.isAdminEventsDetailsEnabled(); diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java index 97f2667bb8..22f57a95df 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedRealm.java @@ -158,7 +158,6 @@ public class CachedRealm { enabledEventTypes.addAll(model.getEnabledEventTypes()); adminEventsEnabled = model.isAdminEventsEnabled(); - adminEnabledEventOperations.addAll(model.getAdminEnabledEventOperations()); adminEventsDetailsEnabled = model.isAdminEventsDetailsEnabled(); defaultRoles.addAll(model.getDefaultRoles()); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index bcad0bb718..66b94d01ac 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -1078,18 +1078,6 @@ public class RealmAdapter implements RealmModel { em.flush(); } - @Override - public Set getAdminEnabledEventOperations() { - return realm.getAdminEnabledEventOperations(); - } - - @Override - public void setAdminEnabledEventOperations(Set adminEnabledEventOperations) { - realm.setAdminEnabledEventOperations(adminEnabledEventOperations); - em.flush(); - - } - @Override public boolean isAdminEventsDetailsEnabled() { return realm.isAdminEventsDetailsEnabled(); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java index 9c69d1db83..cdf314c17c 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/RealmEntity.java @@ -138,11 +138,6 @@ public class RealmEntity { @Column(name="ADMIN_EVENTS_ENABLED") protected boolean adminEventsEnabled; - @ElementCollection - @Column(name="VALUE") - @CollectionTable(name="REALM_ENABLED_ADMIN_EVENT_OPERATIONS", joinColumns={ @JoinColumn(name="REALM_ID") }) - protected Set adminEnabledEventOperations = new HashSet(); - @Column(name="ADMIN_EVENTS_DETAILS_ENABLED") protected boolean adminEventsDetailsEnabled; @@ -456,14 +451,6 @@ public class RealmEntity { this.adminEventsEnabled = adminEventsEnabled; } - public Set getAdminEnabledEventOperations() { - return adminEnabledEventOperations; - } - - public void setAdminEnabledEventOperations(Set adminEnabledEventOperations) { - this.adminEnabledEventOperations = adminEnabledEventOperations; - } - public boolean isAdminEventsDetailsEnabled() { return adminEventsDetailsEnabled; } diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index c5b999ef22..d797de9fa3 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -999,21 +999,6 @@ public class RealmAdapter extends AbstractMongoAdapter impleme } - @Override - public Set getAdminEnabledEventOperations() { - return new HashSet(realm.getAdminEnabledEventOperations()); - } - - @Override - public void setAdminEnabledEventOperations(Set adminEnabledEventOperations) { - if (adminEnabledEventOperations != null) { - realm.setAdminEnabledEventOperations(new ArrayList(adminEnabledEventOperations)); - } else { - realm.setAdminEnabledEventOperations(Collections.EMPTY_LIST); - } - updateRealm(); - } - @Override public boolean isAdminEventsDetailsEnabled() { return realm.isAdminEventsDetailsEnabled(); diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index e3a36517e9..f2caef83f9 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -170,9 +170,6 @@ public class RealmManager { } realm.setAdminEventsEnabled(rep.isAdminEventsEnabled()); - if(rep.getAdminEnabledEventOperations() != null) { - realm.setAdminEnabledEventOperations(new HashSet(rep.getAdminEnabledEventOperations())); - } realm.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled()); } diff --git a/events/api/src/main/java/org/keycloak/events/AdminEventBuilder.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java similarity index 51% rename from events/api/src/main/java/org/keycloak/events/AdminEventBuilder.java rename to services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java index e822217ef3..a0c15f334c 100644 --- a/events/api/src/main/java/org/keycloak/events/AdminEventBuilder.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminEventBuilder.java @@ -1,4 +1,4 @@ -package org.keycloak.events; +package org.keycloak.services.resources.admin; import java.io.IOException; import java.util.LinkedList; @@ -6,13 +6,22 @@ import java.util.List; import org.jboss.logging.Logger; import org.keycloak.ClientConnection; +import org.keycloak.broker.provider.IdentityProviderFactory; +import org.keycloak.events.EventListenerProvider; +import org.keycloak.events.EventStoreProvider; import org.keycloak.events.admin.AdminEvent; import org.keycloak.events.admin.AuthDetails; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; +import org.keycloak.models.IdentityProviderMapperModel; +import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; +import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.util.JsonSerialization; import org.keycloak.util.Time; @@ -25,9 +34,8 @@ public class AdminEventBuilder { private RealmModel realm; private AdminEvent adminEvent; - public AdminEventBuilder(RealmModel realm, KeycloakSession session, ClientConnection clientConnection) { + public AdminEventBuilder(RealmModel realm, AdminAuth auth, KeycloakSession session, ClientConnection clientConnection) { this.realm = realm; - adminEvent = new AdminEvent(); if (realm.isAdminEventsEnabled()) { @@ -51,8 +59,20 @@ public class AdminEventBuilder { } } - realm(realm); - ipAddress(clientConnection.getRemoteAddr()); + authRealm(auth.getRealm()); + authClient(auth.getClient()); + authUser(auth.getUser()); + authIpAddress(clientConnection.getRemoteAddr()); + } + + public AdminEventBuilder realm(RealmModel realm) { + adminEvent.setRealmId(realm.getId()); + return this; + } + + public AdminEventBuilder realm(String realmId) { + adminEvent.setRealmId(realmId); + return this; } public AdminEventBuilder operation(OperationType e) { @@ -60,7 +80,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder realm(RealmModel realm) { + public AdminEventBuilder authRealm(RealmModel realm) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -72,7 +92,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder realm(String realmId) { + public AdminEventBuilder authRealm(String realmId) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -84,7 +104,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder client(ClientModel client) { + public AdminEventBuilder authClient(ClientModel client) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -96,7 +116,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder client(String clientId) { + public AdminEventBuilder authClient(String clientId) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -108,7 +128,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder user(UserModel user) { + public AdminEventBuilder authUser(UserModel user) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -120,7 +140,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder user(String userId) { + public AdminEventBuilder authUser(String userId) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -132,7 +152,7 @@ public class AdminEventBuilder { return this; } - public AdminEventBuilder ipAddress(String ipAddress) { + public AdminEventBuilder authIpAddress(String ipAddress) { AuthDetails authDetails = adminEvent.getAuthDetails(); if(authDetails == null) { authDetails = new AuthDetails(); @@ -148,6 +168,54 @@ public class AdminEventBuilder { adminEvent.setResourcePath(resourcePath); return this; } + + public AdminEventBuilder resourcePath(String resourcePath, boolean segment) { + if(segment) { + int index = resourcePath.lastIndexOf('/'); + int subIndex = resourcePath.lastIndexOf('/', index - 1); + adminEvent.setResourcePath(resourcePath.substring(subIndex)); + } else { + adminEvent.setResourcePath(resourcePath.substring(resourcePath.lastIndexOf('/'))); + } + return this; + } + + public AdminEventBuilder resourcePath(Object model) { + StringBuilder sb = new StringBuilder(); + sb.append(getResourcePath(model)); + adminEvent.setResourcePath(sb.toString()); + return this; + } + + public AdminEventBuilder resourcePath(Object model, String resourcePath) { + StringBuilder sb = new StringBuilder(); + sb.append(getResourcePath(model)); + sb.append(resourcePath.substring(resourcePath.lastIndexOf('/'))); + adminEvent.setResourcePath(sb.toString()); + return this; + } + + public AdminEventBuilder resourcePath(Object model, String resourcePath, boolean segment) { + StringBuilder sb = new StringBuilder(); + sb.append(getResourcePath(model)); + int index = resourcePath.lastIndexOf('/'); + int subIndex = resourcePath.lastIndexOf('/', index - 1); + sb.append(resourcePath.substring(subIndex)); + adminEvent.setResourcePath(sb.toString()); + return this; + } + + public AdminEventBuilder resourcePath(Object model, Object subModel, String resourcePath) { + StringBuilder sb = new StringBuilder(); + sb.append(getResourcePath(model)); + int index = resourcePath.lastIndexOf('/'); + int subIndex = resourcePath.lastIndexOf('/', index - 1); + sb.append(resourcePath.substring(subIndex, index+1)); + sb.append(getResourcePath(subModel)); + adminEvent.setResourcePath(sb.toString()); + return this; + } + public void error(String error) { adminEvent.setOperationType(OperationType.valueOf(adminEvent.getOperationType().name() + "_ERROR")); @@ -183,12 +251,10 @@ public class AdminEventBuilder { adminEvent.setTime(Time.toMillis(Time.currentTime())); if (store != null) { - if (realm.getAdminEnabledEventOperations() != null && !realm.getAdminEnabledEventOperations().isEmpty() ? realm.getAdminEnabledEventOperations().contains(adminEvent.getOperationType().name()) : adminEvent.getOperationType().isSaveByDefault()) { - try { - store.onEvent(adminEvent, includeRepresentation); - } catch (Throwable t) { - log.error("Failed to save event", t); - } + try { + store.onEvent(adminEvent, includeRepresentation); + } catch (Throwable t) { + log.error("Failed to save event", t); } } @@ -202,4 +268,47 @@ public class AdminEventBuilder { } } } + + private String getResourcePath(Object model) { + + StringBuilder sb = new StringBuilder(); + + if (model instanceof RealmModel) { + RealmModel realm = (RealmModel) model; + sb.append("realms/" + realm.getId()); + } else if (model instanceof ClientModel) { + ClientModel client = (ClientModel) model; + sb.append("clients/" + client.getId()); + } else if (model instanceof UserModel) { + UserModel user = (UserModel) model; + sb.append("users/" + user.getId()); + + } else if (model instanceof IdentityProviderModel) { + IdentityProviderModel provider = (IdentityProviderModel) model; + sb.append("identity-Providers/" + provider.getProviderId()); + } else if (model instanceof IdentityProviderRepresentation) { + IdentityProviderRepresentation provider = (IdentityProviderRepresentation) model; + sb.append("identity-Providers/" + provider.getProviderId()); + } else if (model instanceof IdentityProviderMapperModel) { + IdentityProviderMapperModel provider = (IdentityProviderMapperModel) model; + sb.append("identity-Provider-Mappers/" + provider.getId()); + } else if (model instanceof IdentityProviderFactory) { + IdentityProviderFactory provider = (IdentityProviderFactory) model; + sb.append("identity-Provider-Factory/" + provider.getId()); + + } else if (model instanceof ProtocolMapperModel) { + ProtocolMapperModel mapper = (ProtocolMapperModel) model; + sb.append("protocol-Mappers/" + mapper.getId()); + + } else if (model instanceof UserFederationProviderModel) { + UserFederationProviderModel provider = (UserFederationProviderModel) model; + sb.append("user-Federation-Providers/" + provider.getId()); + + } else if (model instanceof RoleModel) { + RoleModel role = (RoleModel) model; + sb.append("roles/" + role.getId()); + } + + return sb.toString(); + } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java index 8b8253fd6c..55861d0bb4 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminRoot.java @@ -8,7 +8,6 @@ import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.UnauthorizedException; import org.keycloak.ClientConnection; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.jose.jws.JWSInput; import org.keycloak.models.AdminRoles; import org.keycloak.models.ClientModel; @@ -188,10 +187,7 @@ public class AdminRoot { Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response); - AdminEventBuilder adminEvent = new AdminEventBuilder(auth.getRealm(), session, clientConnection); - adminEvent.user(auth.getUser()).client(auth.getClient()); - - RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager, adminEvent); + RealmsAdminResource adminResource = new RealmsAdminResource(auth, tokenManager); ResteasyProviderFactory.getInstance().injectProperties(adminResource); return adminResource; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java index 4e75efb60b..3b91e3ec8f 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java @@ -6,7 +6,6 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.NotAcceptableException; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -99,7 +98,6 @@ public class ClientAttributeCertificateResource { ClientKeyPairInfo info = new ClientKeyPairInfo(); info.setCertificate(client.getAttribute(certificateAttribute)); info.setPrivateKey(client.getAttribute(privateAttribute)); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return info; } @@ -135,12 +133,14 @@ public class ClientAttributeCertificateResource { client.setAttribute(privateAttribute, privateKeyPem); client.setAttribute(certificateAttribute, certPem); - KeycloakModelUtils.generateClientKeyPairCertificate(client); ClientKeyPairInfo info = new ClientKeyPairInfo(); info.setCertificate(client.getAttribute(certificateAttribute)); info.setPrivateKey(client.getAttribute(privateAttribute)); - adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri().getPath()).representation(info).success(); + + adminEvent.operation(OperationType.ACTION) + .resourcePath(client, session.getContext().getUri().getPath()).representation(info).success(); + return info; } @@ -198,7 +198,7 @@ public class ClientAttributeCertificateResource { info.setCertificate(certPem); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(info).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).representation(info).success(); return info; } @@ -325,7 +325,8 @@ public class ClientAttributeCertificateResource { stream.close(); byte[] rtn = stream.toByteArray(); - adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri().getPath()).success(); + adminEvent.operation(OperationType.ACTION) + .resourcePath(client, session.getContext().getUri().getPath()).success(); return rtn; } catch (Exception e) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java index 3f0d0ea2e4..d9ab8dcd32 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java @@ -5,7 +5,6 @@ import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.BadRequestException; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -88,7 +87,6 @@ public class ClientResource { public ProtocolMappersResource getProtocolMappers() { ProtocolMappersResource mappers = new ProtocolMappersResource(client, auth, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(mappers); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return mappers; } @@ -104,7 +102,7 @@ public class ClientResource { try { RepresentationToModel.updateClient(rep, client); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(client).representation(rep).success(); return Response.noContent().build(); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Client " + rep.getClientId() + " already exists"); @@ -122,7 +120,6 @@ public class ClientResource { @Produces(MediaType.APPLICATION_JSON) public ClientRepresentation getClient() { auth.requireView(); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return ModelToRepresentation.toRepresentation(client); } @@ -153,7 +150,7 @@ public class ClientResource { ClientManager clientManager = new ClientManager(new RealmManager(session)); Object rep = clientManager.toInstallationRepresentation(realm, client, getKeycloakApplication().getBaseUri(uriInfo)); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success(); // TODO Temporary solution to pretty-print return JsonSerialization.mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rep); @@ -174,7 +171,7 @@ public class ClientResource { ClientManager clientManager = new ClientManager(new RealmManager(session)); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success(); return clientManager.toJBossSubsystemConfig(realm, client, getKeycloakApplication().getBaseUri(uriInfo)); } @@ -188,7 +185,7 @@ public class ClientResource { public void deleteClient() { auth.requireManage(); new ClientManager(new RealmManager(session)).removeClient(realm, client); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client).success(); } @@ -207,7 +204,7 @@ public class ClientResource { logger.debug("regenerateSecret"); UserCredentialModel cred = KeycloakModelUtils.generateSecret(client); CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).representation(rep).success(); return rep; } @@ -226,7 +223,6 @@ public class ClientResource { logger.debug("getClientSecret"); UserCredentialModel model = UserCredentialModel.secret(client.getSecret()); if (model == null) throw new NotFoundException("Client does not have a secret"); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return ModelToRepresentation.toRepresentation(model); } @@ -258,7 +254,6 @@ public class ClientResource { public Set getAllowedOrigins() { auth.requireView(); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return client.getWebOrigins(); } @@ -276,7 +271,7 @@ public class ClientResource { auth.requireManage(); client.setWebOrigins(allowedOrigins); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(client).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(client, uriInfo.getPath()).representation(client).success(); } /** @@ -295,7 +290,7 @@ public class ClientResource { for (String origin : allowedOrigins) { client.removeWebOrigin(origin); } - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client, uriInfo.getPath()).success(); } /** @@ -306,7 +301,7 @@ public class ClientResource { @POST public GlobalRequestResult pushRevocation() { auth.requireManage(); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success(); return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client); } @@ -328,7 +323,6 @@ public class ClientResource { auth.requireView(); Map map = new HashMap(); map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client)); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return map; } @@ -350,7 +344,6 @@ public class ClientResource { UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(userSession); sessions.add(rep); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return sessions; } @@ -362,7 +355,7 @@ public class ClientResource { @POST public GlobalRequestResult logoutAll() { auth.requireManage(); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success(); return new ResourceAdminManager(session).logoutClient(uriInfo.getRequestUri(), realm, client); } @@ -379,7 +372,7 @@ public class ClientResource { if (user == null) { throw new NotFoundException("User not found"); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath(), true).success(); new ResourceAdminManager(session).logoutUserFromClient(uriInfo.getRequestUri(), realm, client, user); } @@ -401,7 +394,7 @@ public class ClientResource { } if (logger.isDebugEnabled()) logger.debug("Register node: " + node); client.registerNode(node, Time.currentTime()); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success(); } /** @@ -421,7 +414,7 @@ public class ClientResource { throw new NotFoundException("Client does not have a node " + node); } client.unregisterNode(node); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client, uriInfo.getPath(), true).success(); } /** @@ -435,7 +428,7 @@ public class ClientResource { public GlobalRequestResult testNodesAvailable() { auth.requireManage(); logger.debug("Test availability of cluster nodes"); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(client, uriInfo.getPath()).success(); return new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java index bb9ae8dfa3..3b273e08bd 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsByIdResource.java @@ -1,6 +1,5 @@ package org.keycloak.services.resources.admin; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.models.ClientModel; import org.keycloak.models.RealmModel; diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java index 2d19c512dd..51c509f74a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java @@ -4,7 +4,6 @@ import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -77,7 +76,6 @@ public class ClientsResource { rep.add(client); } } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return rep; } @@ -95,9 +93,9 @@ public class ClientsResource { try { ClientModel clientModel = RepresentationToModel.createClient(session, realm, rep, true); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(getClientPath(clientModel)).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(rep).success(); + + adminEvent.operation(OperationType.CREATE).resourcePath(clientModel).representation(rep).success(); + return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(clientModel)).build()).build(); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Client " + rep.getClientId() + " already exists"); @@ -122,7 +120,6 @@ public class ClientsResource { } ClientResource clientResource = new ClientResource(realm, auth, clientModel, session, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(clientResource); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return clientResource; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java index d70cfd9c4a..9b058a50d6 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java @@ -6,7 +6,6 @@ import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.broker.provider.IdentityProviderMapper; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.FederatedIdentityModel; @@ -77,9 +76,6 @@ public class IdentityProviderResource { public IdentityProviderRepresentation getIdentityProvider() { this.auth.requireView(); IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(this.identityProviderModel); - - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); - return rep; } @@ -90,7 +86,7 @@ public class IdentityProviderResource { this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias()); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(identityProviderModel).success(); return Response.noContent().build(); } @@ -116,7 +112,7 @@ public class IdentityProviderResource { updateUsersAfterProviderAliasChange(this.session.users().getUsers(this.realm), oldProviderId, newProviderId); } - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(providerRep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(providerRep).representation(providerRep).success(); return Response.noContent().build(); } catch (ModelDuplicateException e) { @@ -173,7 +169,7 @@ public class IdentityProviderResource { try { this.auth.requireView(); IdentityProviderFactory factory = getIdentityProviderFactory(); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(identityProviderModel, uriInfo.getPath()).success(); return factory.create(identityProviderModel).export(uriInfo, realm, format); } catch (Exception e) { return ErrorResponse.error("Could not export public broker configuration for identity provider [" + identityProviderModel.getProviderId() + "].", Response.Status.NOT_FOUND); @@ -212,7 +208,6 @@ public class IdentityProviderResource { } } } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return types; } @@ -226,7 +221,6 @@ public class IdentityProviderResource { for (IdentityProviderMapperModel model : realm.getIdentityProviderMappersByAlias(identityProviderModel.getAlias())) { mappers.add(ModelToRepresentation.toRepresentation(model)); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return mappers; } @@ -237,9 +231,10 @@ public class IdentityProviderResource { auth.requireManage(); IdentityProviderMapperModel model = RepresentationToModel.toModel(mapper); model = realm.addIdentityProviderMapper(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(model.getId()).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(mapper).success(); + + adminEvent.operation(OperationType.CREATE).resourcePath(model, uriInfo.getPath()) + .representation(mapper).success(); + return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); } @@ -252,7 +247,6 @@ public class IdentityProviderResource { auth.requireView(); IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return ModelToRepresentation.toRepresentation(model); } @@ -266,7 +260,7 @@ public class IdentityProviderResource { if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(rep); realm.updateIdentityProviderMapper(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success(); } @@ -278,7 +272,7 @@ public class IdentityProviderResource { IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); realm.removeIdentityProviderMapper(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(model).success(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java index 84ffe2fcbc..3617631245 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java @@ -8,7 +8,6 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.broker.provider.IdentityProvider; import org.keycloak.broker.provider.IdentityProviderFactory; import org.keycloak.connections.httpclient.HttpClientProvider; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.KeycloakSession; @@ -65,12 +64,9 @@ public class IdentityProvidersResource { public Response getIdentityProviders(@PathParam("provider_id") String providerId) { this.auth.requireView(); IdentityProviderFactory providerFactory = getProviderFactorytById(providerId); - if (providerFactory != null) { - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return Response.ok(providerFactory).build(); } - return Response.status(BAD_REQUEST).build(); } @@ -87,7 +83,7 @@ public class IdentityProvidersResource { IdentityProviderFactory providerFactory = getProviderFactorytById(providerId); Map config = providerFactory.parseConfig(inputStream); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(config).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(providerFactory, uriInfo.getPath()).representation(config).success(); return config; } @@ -106,7 +102,7 @@ public class IdentityProvidersResource { IdentityProviderFactory providerFactory = getProviderFactorytById(providerId); Map config; config = providerFactory.parseConfig(inputStream); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(config).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(providerFactory, uriInfo.getPath()).representation(config).success(); return config; } finally { try { @@ -128,7 +124,6 @@ public class IdentityProvidersResource { for (IdentityProviderModel identityProviderModel : realm.getIdentityProviders()) { representations.add(ModelToRepresentation.toRepresentation(identityProviderModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return representations; } @@ -142,8 +137,7 @@ public class IdentityProvidersResource { IdentityProviderModel identityProvider = RepresentationToModel.toModel(representation); this.realm.addIdentityProvider(identityProvider); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(representation.getProviderId()).build().toString().substring(uriInfo.getBaseUri().toString().length())) + adminEvent.operation(OperationType.CREATE).resourcePath(identityProvider) .representation(representation).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(representation.getProviderId()).build()).build(); @@ -171,7 +165,6 @@ public class IdentityProvidersResource { IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return identityProviderResource; } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java index a211087cfe..1f59b68e59 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java @@ -3,11 +3,11 @@ package org.keycloak.services.resources.admin; import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.RealmModel; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.idm.ProtocolMapperRepresentation; @@ -36,7 +36,7 @@ import java.util.List; */ public class ProtocolMappersResource { protected static final Logger logger = Logger.getLogger(ProtocolMappersResource.class); - + protected ClientModel client; protected RealmAuth auth; @@ -73,7 +73,6 @@ public class ProtocolMappersResource { for (ProtocolMapperModel mapper : client.getProtocolMappers()) { if (mapper.getProtocol().equals(protocol)) mappers.add(ModelToRepresentation.toRepresentation(mapper)); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return mappers; } @@ -90,9 +89,7 @@ public class ProtocolMappersResource { auth.requireManage(); ProtocolMapperModel model = RepresentationToModel.toModel(rep); model = client.addProtocolMapper(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(model.getId()).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(model).representation(rep).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); } /** @@ -110,7 +107,7 @@ public class ProtocolMappersResource { model = RepresentationToModel.toModel(rep); model = client.addProtocolMapper(model); } - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getPath()).representation(reps).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getPath(), false).representation(reps).success(); } @GET @@ -123,7 +120,6 @@ public class ProtocolMappersResource { for (ProtocolMapperModel mapper : client.getProtocolMappers()) { mappers.add(ModelToRepresentation.toRepresentation(mapper)); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return mappers; } @@ -135,7 +131,6 @@ public class ProtocolMappersResource { auth.requireView(); ProtocolMapperModel model = client.getProtocolMapperById(id); if (model == null) throw new NotFoundException("Model not found"); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return ModelToRepresentation.toRepresentation(model); } @@ -149,7 +144,7 @@ public class ProtocolMappersResource { if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(rep); client.updateProtocolMapper(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success(); } @DELETE @@ -160,7 +155,7 @@ public class ProtocolMappersResource { ProtocolMapperModel model = client.getProtocolMapperById(id); if (model == null) throw new NotFoundException("Model not found"); client.removeProtocolMapper(model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(model).success(); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index 1ab3c5b497..9f2a12fc81 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -1,565 +1,554 @@ -package org.keycloak.services.resources.admin; - -import org.jboss.logging.Logger; -import org.jboss.resteasy.annotations.cache.NoCache; -import org.jboss.resteasy.spi.NotFoundException; -import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.ClientConnection; -import org.keycloak.Config; -import org.keycloak.events.AdminEventBuilder; -import org.keycloak.events.Event; -import org.keycloak.events.EventQuery; -import org.keycloak.events.EventStoreProvider; -import org.keycloak.events.EventType; -import org.keycloak.events.admin.AdminEvent; -import org.keycloak.events.admin.AdminEventQuery; -import org.keycloak.events.admin.OperationType; -import org.keycloak.exportimport.ClientImporter; -import org.keycloak.models.ClientModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelDuplicateException; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserSessionModel; -import org.keycloak.models.cache.CacheRealmProvider; -import org.keycloak.models.cache.CacheUserProvider; -import org.keycloak.models.utils.ModelToRepresentation; -import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.protocol.oidc.TokenManager; -import org.keycloak.representations.adapters.action.GlobalRequestResult; -import org.keycloak.representations.idm.RealmEventsConfigRepresentation; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.services.managers.AuthenticationManager; -import org.keycloak.services.managers.LDAPConnectionTestManager; -import org.keycloak.services.managers.RealmManager; -import org.keycloak.services.managers.ResourceAdminManager; -import org.keycloak.services.managers.UsersSyncManager; -import org.keycloak.services.ErrorResponse; -import org.keycloak.timer.TimerProvider; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.regex.PatternSyntaxException; - -/** - * Base resource class for the admin REST api of one realm - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class RealmAdminResource { - protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); - protected RealmAuth auth; - protected RealmModel realm; - private TokenManager tokenManager; - private AdminEventBuilder adminEvent; - - @Context - protected KeycloakSession session; - - @Context - protected UriInfo uriInfo; - - @Context - protected ClientConnection connection; - - @Context - protected HttpHeaders headers; - - public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager, AdminEventBuilder adminEvent) { - this.auth = auth; - this.realm = realm; - this.tokenManager = tokenManager; - this.adminEvent = adminEvent; - - auth.init(RealmAuth.Resource.REALM); - } - - /** - * Base path for importing clients under this realm. - * - * @return - */ - @Path("client-importers/{formatId}") - public Object getClientImporter(@PathParam("formatId") String formatId) { - ClientImporter importer = session.getProvider(ClientImporter.class, formatId); - return importer.createJaxrsService(realm, auth); - } - - /** - * Base path for managing clients under this realm. - * - * @return - */ - @Path("clients") - public ClientsResource getClients() { - ClientsResource clientsResource = new ClientsResource(realm, auth, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(clientsResource); - return clientsResource; - } - - /** - * Base path for managing clients under this realm. - * - * @return - */ - @Path("clients-by-id") - public ClientsByIdResource getClientsById() { - ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(clientsResource); - return clientsResource; - } - - /** - * base path for managing realm-level roles of this realm - * - * @return - */ - @Path("roles") - public RoleContainerResource getRoleContainerResource() { - return new RoleContainerResource(realm, auth, realm, adminEvent); - } - - /** - * Get the top-level representation of the realm. It will not include nested information like User and Client representations. - * - * @return - */ - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public RealmRepresentation getRealm() { - if (auth.hasView()) { - RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false); - if (session.realms() instanceof CacheRealmProvider) { - CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms(); - rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled()); - } - if (session.userStorage() instanceof CacheUserProvider) { - CacheUserProvider cache = (CacheUserProvider)session.userStorage(); - rep.setUserCacheEnabled(cache.isEnabled()); - } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); - return rep; - } else { - auth.requireAny(); - - RealmRepresentation rep = new RealmRepresentation(); - rep.setRealm(realm.getName()); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); - return rep; - } - } - - /** - * Update the top-level information of this realm. Any user, roles or client information in the representation - * will be ignored. This will only update top-level attributes of the realm. - * - * @param rep - * @return - */ - @PUT - @Consumes(MediaType.APPLICATION_JSON) - public Response updateRealm(final RealmRepresentation rep) { - auth.requireManage(); - - logger.debug("updating realm: " + realm.getName()); - try { - RepresentationToModel.updateRealm(rep, realm); - if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) { - CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms(); - cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled()); - } - if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) { - CacheUserProvider cache = (CacheUserProvider)session.userStorage(); - cache.setEnabled(rep.isUserCacheEnabled()); - } - - // Refresh periodic sync tasks for configured federationProviders - List federationProviders = realm.getUserFederationProviders(); - UsersSyncManager usersSyncManager = new UsersSyncManager(); - for (final UserFederationProviderModel fedProvider : federationProviders) { - usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId()); - } - - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); - return Response.noContent().build(); - } catch (PatternSyntaxException e) { - return ErrorResponse.error("Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST); - } catch (ModelDuplicateException e) { - return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists."); - } catch (Exception e) { - return ErrorResponse.error("Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR); - } - } - - /** - * Delete this realm. - * - */ - @DELETE - public void deleteRealm() { - auth.requireManage(); - - if (!new RealmManager(session).removeRealm(realm)) { - throw new NotFoundException("Realm doesn't exist"); - } else { - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); - } - } - - /** - * Base path for managing users in this realm. - * - * @return - */ - @Path("users") - public UsersResource users() { - UsersResource users = new UsersResource(realm, auth, tokenManager, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(users); - //resourceContext.initResource(users); - return users; - } - - @Path("user-federation") - public UserFederationResource userFederation() { - UserFederationResource fed = new UserFederationResource(realm, auth, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(fed); - //resourceContext.initResource(fed); - return fed; - } - - /** - * Path for managing all realm-level or client-level roles defined in this realm by it's id. - * - * @return - */ - @Path("roles-by-id") - public RoleByIdResource rolesById() { - RoleByIdResource resource = new RoleByIdResource(realm, auth, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(resource); - //resourceContext.initResource(resource); - return resource; - } - - /** - * Push the realm's revocation policy to any client that has an admin url associated with it. - * - */ - @Path("push-revocation") - @POST - public GlobalRequestResult pushRevocation() { - auth.requireManage(); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); - return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm); - } - - /** - * Removes all user sessions. Any client that has an admin url will also be told to invalidate any sessions - * they have. - * - */ - @Path("logout-all") - @POST - public GlobalRequestResult logoutAll() { - session.sessions().removeUserSessions(realm); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); - return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm); - } - - /** - * Remove a specific user session. Any client that has an admin url will also be told to invalidate this - * particular session. - * - * @param sessionId - */ - @Path("sessions/{session}") - @DELETE - public void deleteSession(@PathParam("session") String sessionId) { - UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId); - if (userSession == null) throw new NotFoundException("Sesssion not found"); - AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); - - } - - /** - * Returns a JSON map. The key is the client name, the value is the number of sessions that currently are active - * with that client. Only client's that actually have a session associated with them will be in this map. - * - * @return - */ - @Path("client-session-stats") - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - @Deprecated - public Map getClientSessionStats() { - auth.requireView(); - Map stats = new HashMap(); - for (ClientModel client : realm.getClients()) { - int size = session.sessions().getActiveUserSessions(client.getRealm(), client); - if (size == 0) continue; - stats.put(client.getClientId(), size); - } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(stats).success(); - return stats; - } - - /** - * Returns a JSON map. The key is the client id, the value is the number of sessions that currently are active - * with that client. Only client's that actually have a session associated with them will be in this map. - * - * @return - */ - @Path("client-by-id-session-stats") - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public List> getClientByIdSessionStats() { - auth.requireView(); - List> data = new LinkedList>(); - for (ClientModel client : realm.getClients()) { - int size = session.sessions().getActiveUserSessions(client.getRealm(), client); - if (size == 0) continue; - Map map = new HashMap(); - map.put("id", client.getId()); - map.put("clientId", client.getClientId()); - map.put("active", size + ""); - data.add(map); - } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(data).success(); - return data; - } - - /** - * View the events provider and how it is configured. - * - * @return - */ - @GET - @NoCache - @Path("events/config") - @Produces(MediaType.APPLICATION_JSON) - public RealmEventsConfigRepresentation getRealmEventsConfig() { - auth.init(RealmAuth.Resource.EVENTS).requireView(); - - return ModelToRepresentation.toEventsConfigReprensetation(realm); - } - - /** - * Change the events provider and/or it's configuration - * - * @param rep - */ - @PUT - @Path("events/config") - @Consumes(MediaType.APPLICATION_JSON) - public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) { - auth.init(RealmAuth.Resource.EVENTS).requireManage(); - - logger.debug("updating realm events config: " + realm.getName()); - new RealmManager(session).updateRealmEventsConfig(rep, realm); - } - - /** - * Query events. Returns all events, or will query based on URL query parameters listed here - * - * @param client app or oauth client name - * @param user user id - * @param ipAddress - * @param dateTo - * @param dateFrom - * @param firstResult - * @param maxResults - * @return - */ - @Path("events") - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public List getEvents(@QueryParam("client") String client, - @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo, - @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, - @QueryParam("max") Integer maxResults) { - auth.init(RealmAuth.Resource.EVENTS).requireView(); - - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - - EventQuery query = eventStore.createQuery().realm(realm.getId()); - if (client != null) { - query.client(client); - } - - List types = uriInfo.getQueryParameters().get("type"); - if (types != null) { - EventType[] t = new EventType[types.size()]; - for (int i = 0; i < t.length; i++) { - t[i] = EventType.valueOf(types.get(i)); - } - query.type(t); - } - - if (user != null) { - query.user(user); - } - - if(dateFrom != null) { - query.fromDate(dateFrom); - } - if(dateTo != null) { - query.toDate(dateTo); - } - - if (ipAddress != null) { - query.ipAddress(ipAddress); - } - if (firstResult != null) { - query.firstResult(firstResult); - } - if (maxResults != null) { - query.maxResults(maxResults); - } - - return query.getResultList(); - } - - /** - * Query admin events. Returns all admin events, or will query based on URL query parameters listed here - * - * @param client app or oauth client name - * @param operationTypes operation type - * @param authUser user id - * @param authIpAddress - * @param resourcePath - * @param dateTo - * @param dateFrom - * @param resourcePath - * @param firstResult - * @param maxResults - * @return - */ - @Path("admin-events") - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public List getEvents(@QueryParam("authRealm") String authRealm, @QueryParam("authClient") String authClient, - @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress, - @QueryParam("resourcePath") String resourcePath, @QueryParam("dateFrom") String dateFrom, - @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult, - @QueryParam("max") Integer maxResults) { - auth.init(RealmAuth.Resource.EVENTS).requireView(); - - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - AdminEventQuery query = null; - - if(realm.getName().equals(Config.getAdminRealm())) { - query = eventStore.createAdminQuery(); - if(authRealm != null) { - query.authRealm(authRealm); - } - } else { - query = eventStore.createAdminQuery().authRealm(realm.getId()); - } - - if (authClient != null) { - query.authClient(authClient); - } - - if (authUser != null) { - query.authUser(authUser); - } - - if (authIpAddress != null) { - query.authIpAddress(authIpAddress); - } - - if (resourcePath != null) { - query.resourcePath(resourcePath); - } - - List operationTypes = uriInfo.getQueryParameters().get("operationTypes"); - if (operationTypes != null) { - OperationType[] t = new OperationType[operationTypes.size()]; - for (int i = 0; i < t.length; i++) { - t[i] = OperationType.valueOf(operationTypes.get(i)); - } - query.operation(t); - } - - if(dateFrom != null) { - query.fromTime(dateFrom); - } - if(dateTo != null) { - query.toTime(dateTo); - } - - if (firstResult != null) { - query.firstResult(firstResult); - } - if (maxResults != null) { - query.maxResults(maxResults); - } - - return query.getResultList(); - } - - /** - * Delete all events. - * - */ - @Path("events") - @DELETE - public void clearEvents() { - auth.init(RealmAuth.Resource.EVENTS).requireManage(); - - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - eventStore.clear(realm.getId()); - } - - /** - * Delete all admin events. - * - */ - @Path("admin-events") - @DELETE - public void clearAdminEvents() { - auth.init(RealmAuth.Resource.EVENTS).requireManage(); - - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - eventStore.clearAdmin(realm.getId()); - } - - @Path("testLDAPConnection") - @GET - @NoCache - public Response testLDAPConnection(@QueryParam("action") String action, @QueryParam("connectionUrl") String connectionUrl, - @QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential) { - auth.init(RealmAuth.Resource.REALM).requireManage(); - - boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential); - return result ? Response.noContent().build() : ErrorResponse.error("LDAP test error", Response.Status.BAD_REQUEST); - } - - @Path("identity-provider") - public IdentityProvidersResource getIdentityProviderResource() { - return new IdentityProvidersResource(realm, session, this.auth, adminEvent); - } -} +package org.keycloak.services.resources.admin; + +import org.jboss.logging.Logger; +import org.jboss.resteasy.annotations.cache.NoCache; +import org.jboss.resteasy.spi.NotFoundException; +import org.jboss.resteasy.spi.ResteasyProviderFactory; +import org.keycloak.ClientConnection; +import org.keycloak.events.Event; +import org.keycloak.events.EventQuery; +import org.keycloak.events.EventStoreProvider; +import org.keycloak.events.EventType; +import org.keycloak.events.admin.AdminEvent; +import org.keycloak.events.admin.AdminEventQuery; +import org.keycloak.events.admin.OperationType; +import org.keycloak.exportimport.ClientImporter; +import org.keycloak.models.ClientModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.ModelDuplicateException; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserFederationProviderModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.models.cache.CacheRealmProvider; +import org.keycloak.models.cache.CacheUserProvider; +import org.keycloak.models.utils.ModelToRepresentation; +import org.keycloak.models.utils.RepresentationToModel; +import org.keycloak.protocol.oidc.TokenManager; +import org.keycloak.representations.adapters.action.GlobalRequestResult; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.LDAPConnectionTestManager; +import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.managers.ResourceAdminManager; +import org.keycloak.services.managers.UsersSyncManager; +import org.keycloak.services.ErrorResponse; +import org.keycloak.timer.TimerProvider; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.PatternSyntaxException; + +/** + * Base resource class for the admin REST api of one realm + * + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class RealmAdminResource { + protected static final Logger logger = Logger.getLogger(RealmAdminResource.class); + protected RealmAuth auth; + protected RealmModel realm; + private TokenManager tokenManager; + private AdminEventBuilder adminEvent; + + @Context + protected KeycloakSession session; + + @Context + protected UriInfo uriInfo; + + @Context + protected ClientConnection connection; + + @Context + protected HttpHeaders headers; + + public RealmAdminResource(RealmAuth auth, RealmModel realm, TokenManager tokenManager, AdminEventBuilder adminEvent) { + this.auth = auth; + this.realm = realm; + this.tokenManager = tokenManager; + this.adminEvent = adminEvent.realm(realm); + + auth.init(RealmAuth.Resource.REALM); + } + + /** + * Base path for importing clients under this realm. + * + * @return + */ + @Path("client-importers/{formatId}") + public Object getClientImporter(@PathParam("formatId") String formatId) { + ClientImporter importer = session.getProvider(ClientImporter.class, formatId); + return importer.createJaxrsService(realm, auth); + } + + /** + * Base path for managing clients under this realm. + * + * @return + */ + @Path("clients") + public ClientsResource getClients() { + ClientsResource clientsResource = new ClientsResource(realm, auth, adminEvent); + ResteasyProviderFactory.getInstance().injectProperties(clientsResource); + return clientsResource; + } + + /** + * Base path for managing clients under this realm. + * + * @return + */ + @Path("clients-by-id") + public ClientsByIdResource getClientsById() { + ClientsByIdResource clientsResource = new ClientsByIdResource(realm, auth, adminEvent); + ResteasyProviderFactory.getInstance().injectProperties(clientsResource); + return clientsResource; + } + + /** + * base path for managing realm-level roles of this realm + * + * @return + */ + @Path("roles") + public RoleContainerResource getRoleContainerResource() { + return new RoleContainerResource(realm, auth, realm, adminEvent); + } + + /** + * Get the top-level representation of the realm. It will not include nested information like User and Client representations. + * + * @return + */ + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + public RealmRepresentation getRealm() { + if (auth.hasView()) { + RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false); + if (session.realms() instanceof CacheRealmProvider) { + CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms(); + rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled()); + } + if (session.userStorage() instanceof CacheUserProvider) { + CacheUserProvider cache = (CacheUserProvider)session.userStorage(); + rep.setUserCacheEnabled(cache.isEnabled()); + } + return rep; + } else { + auth.requireAny(); + + RealmRepresentation rep = new RealmRepresentation(); + rep.setRealm(realm.getName()); + return rep; + } + } + + /** + * Update the top-level information of this realm. Any user, roles or client information in the representation + * will be ignored. This will only update top-level attributes of the realm. + * + * @param rep + * @return + */ + @PUT + @Consumes(MediaType.APPLICATION_JSON) + public Response updateRealm(final RealmRepresentation rep) { + auth.requireManage(); + + logger.debug("updating realm: " + realm.getName()); + try { + RepresentationToModel.updateRealm(rep, realm); + if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) { + CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms(); + cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled()); + } + if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) { + CacheUserProvider cache = (CacheUserProvider)session.userStorage(); + cache.setEnabled(rep.isUserCacheEnabled()); + } + + // Refresh periodic sync tasks for configured federationProviders + List federationProviders = realm.getUserFederationProviders(); + UsersSyncManager usersSyncManager = new UsersSyncManager(); + for (final UserFederationProviderModel fedProvider : federationProviders) { + usersSyncManager.refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), fedProvider, realm.getId()); + } + + adminEvent.operation(OperationType.UPDATE).representation(rep).success(); + return Response.noContent().build(); + } catch (PatternSyntaxException e) { + return ErrorResponse.error("Specified regex pattern(s) is invalid.", Response.Status.BAD_REQUEST); + } catch (ModelDuplicateException e) { + return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists."); + } catch (Exception e) { + return ErrorResponse.error("Failed to update " + rep.getRealm() + " Realm.", Response.Status.INTERNAL_SERVER_ERROR); + } + } + + /** + * Delete this realm. + * + */ + @DELETE + public void deleteRealm() { + auth.requireManage(); + + if (!new RealmManager(session).removeRealm(realm)) { + throw new NotFoundException("Realm doesn't exist"); + } else { + clearAdminEvents(); + } + } + + /** + * Base path for managing users in this realm. + * + * @return + */ + @Path("users") + public UsersResource users() { + UsersResource users = new UsersResource(realm, auth, tokenManager, adminEvent); + ResteasyProviderFactory.getInstance().injectProperties(users); + //resourceContext.initResource(users); + return users; + } + + @Path("user-federation") + public UserFederationResource userFederation() { + UserFederationResource fed = new UserFederationResource(realm, auth, adminEvent); + ResteasyProviderFactory.getInstance().injectProperties(fed); + //resourceContext.initResource(fed); + return fed; + } + + /** + * Path for managing all realm-level or client-level roles defined in this realm by it's id. + * + * @return + */ + @Path("roles-by-id") + public RoleByIdResource rolesById() { + RoleByIdResource resource = new RoleByIdResource(realm, auth, adminEvent); + ResteasyProviderFactory.getInstance().injectProperties(resource); + //resourceContext.initResource(resource); + return resource; + } + + /** + * Push the realm's revocation policy to any client that has an admin url associated with it. + * + */ + @Path("push-revocation") + @POST + public GlobalRequestResult pushRevocation() { + auth.requireManage(); + adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath(), false).success(); + return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm); + } + + /** + * Removes all user sessions. Any client that has an admin url will also be told to invalidate any sessions + * they have. + * + */ + @Path("logout-all") + @POST + public GlobalRequestResult logoutAll() { + session.sessions().removeUserSessions(realm); + adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath(), false).success(); + return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm); + } + + /** + * Remove a specific user session. Any client that has an admin url will also be told to invalidate this + * particular session. + * + * @param sessionId + */ + @Path("sessions/{session}") + @DELETE + public void deleteSession(@PathParam("session") String sessionId) { + UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId); + if (userSession == null) throw new NotFoundException("Sesssion not found"); + AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true); + adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath(), true).success(); + + } + + /** + * Returns a JSON map. The key is the client name, the value is the number of sessions that currently are active + * with that client. Only client's that actually have a session associated with them will be in this map. + * + * @return + */ + @Path("client-session-stats") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + @Deprecated + public Map getClientSessionStats() { + auth.requireView(); + Map stats = new HashMap(); + for (ClientModel client : realm.getClients()) { + int size = session.sessions().getActiveUserSessions(client.getRealm(), client); + if (size == 0) continue; + stats.put(client.getClientId(), size); + } + return stats; + } + + /** + * Returns a JSON map. The key is the client id, the value is the number of sessions that currently are active + * with that client. Only client's that actually have a session associated with them will be in this map. + * + * @return + */ + @Path("client-by-id-session-stats") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + public List> getClientByIdSessionStats() { + auth.requireView(); + List> data = new LinkedList>(); + for (ClientModel client : realm.getClients()) { + int size = session.sessions().getActiveUserSessions(client.getRealm(), client); + if (size == 0) continue; + Map map = new HashMap(); + map.put("id", client.getId()); + map.put("clientId", client.getClientId()); + map.put("active", size + ""); + data.add(map); + } + return data; + } + + /** + * View the events provider and how it is configured. + * + * @return + */ + @GET + @NoCache + @Path("events/config") + @Produces(MediaType.APPLICATION_JSON) + public RealmEventsConfigRepresentation getRealmEventsConfig() { + auth.init(RealmAuth.Resource.EVENTS).requireView(); + + return ModelToRepresentation.toEventsConfigReprensetation(realm); + } + + /** + * Change the events provider and/or it's configuration + * + * @param rep + */ + @PUT + @Path("events/config") + @Consumes(MediaType.APPLICATION_JSON) + public void updateRealmEventsConfig(final RealmEventsConfigRepresentation rep) { + auth.init(RealmAuth.Resource.EVENTS).requireManage(); + + logger.debug("updating realm events config: " + realm.getName()); + new RealmManager(session).updateRealmEventsConfig(rep, realm); + } + + /** + * Query events. Returns all events, or will query based on URL query parameters listed here + * + * @param client app or oauth client name + * @param user user id + * @param ipAddress + * @param dateTo + * @param dateFrom + * @param firstResult + * @param maxResults + * @return + */ + @Path("events") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + public List getEvents(@QueryParam("client") String client, + @QueryParam("user") String user, @QueryParam("dateFrom") String dateFrom, @QueryParam("dateTo") String dateTo, + @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults) { + auth.init(RealmAuth.Resource.EVENTS).requireView(); + + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + + EventQuery query = eventStore.createQuery().realm(realm.getId()); + if (client != null) { + query.client(client); + } + + List types = uriInfo.getQueryParameters().get("type"); + if (types != null) { + EventType[] t = new EventType[types.size()]; + for (int i = 0; i < t.length; i++) { + t[i] = EventType.valueOf(types.get(i)); + } + query.type(t); + } + + if (user != null) { + query.user(user); + } + + if(dateFrom != null) { + query.fromDate(dateFrom); + } + if(dateTo != null) { + query.toDate(dateTo); + } + + if (ipAddress != null) { + query.ipAddress(ipAddress); + } + if (firstResult != null) { + query.firstResult(firstResult); + } + if (maxResults != null) { + query.maxResults(maxResults); + } + + return query.getResultList(); + } + + /** + * Query admin events. Returns all admin events, or will query based on URL query parameters listed here + * + * @param client app or oauth client name + * @param operationTypes operation type + * @param authUser user id + * @param authIpAddress + * @param resourcePath + * @param dateTo + * @param dateFrom + * @param resourcePath + * @param firstResult + * @param maxResults + * @return + */ + @Path("admin-events") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + public List getEvents(@QueryParam("authRealm") String authRealm, @QueryParam("authClient") String authClient, + @QueryParam("authUser") String authUser, @QueryParam("authIpAddress") String authIpAddress, + @QueryParam("resourcePath") String resourcePath, @QueryParam("dateFrom") String dateFrom, + @QueryParam("dateTo") String dateTo, @QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults) { + auth.init(RealmAuth.Resource.EVENTS).requireView(); + + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + AdminEventQuery query = eventStore.createAdminQuery().realm(realm.getId());; + + if (authRealm != null) { + query.authRealm(authRealm); + } + + if (authClient != null) { + query.authClient(authClient); + } + + if (authUser != null) { + query.authUser(authUser); + } + + if (authIpAddress != null) { + query.authIpAddress(authIpAddress); + } + + if (resourcePath != null) { + query.resourcePath(resourcePath); + } + + List operationTypes = uriInfo.getQueryParameters().get("operationTypes"); + if (operationTypes != null) { + OperationType[] t = new OperationType[operationTypes.size()]; + for (int i = 0; i < t.length; i++) { + t[i] = OperationType.valueOf(operationTypes.get(i)); + } + query.operation(t); + } + + if(dateFrom != null) { + query.fromTime(dateFrom); + } + if(dateTo != null) { + query.toTime(dateTo); + } + + if (firstResult != null) { + query.firstResult(firstResult); + } + if (maxResults != null) { + query.maxResults(maxResults); + } + + return query.getResultList(); + } + + /** + * Delete all events. + * + */ + @Path("events") + @DELETE + public void clearEvents() { + auth.init(RealmAuth.Resource.EVENTS).requireManage(); + + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + eventStore.clear(realm.getId()); + } + + /** + * Delete all admin events. + * + */ + @Path("admin-events") + @DELETE + public void clearAdminEvents() { + auth.init(RealmAuth.Resource.EVENTS).requireManage(); + + EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); + eventStore.clearAdmin(realm.getId()); + } + + @Path("testLDAPConnection") + @GET + @NoCache + public Response testLDAPConnection(@QueryParam("action") String action, @QueryParam("connectionUrl") String connectionUrl, + @QueryParam("bindDn") String bindDn, @QueryParam("bindCredential") String bindCredential) { + auth.init(RealmAuth.Resource.REALM).requireManage(); + + boolean result = new LDAPConnectionTestManager().testLDAP(action, connectionUrl, bindDn, bindCredential); + return result ? Response.noContent().build() : ErrorResponse.error("LDAP test error", Response.Status.BAD_REQUEST); + } + + @Path("identity-provider") + public IdentityProvidersResource getIdentityProviderResource() { + return new IdentityProvidersResource(realm, session, this.auth, adminEvent); + } +} diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java index e50c25c834..fbe401c138 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java @@ -6,8 +6,7 @@ import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.events.AdminEventBuilder; -import org.keycloak.events.admin.OperationType; +import org.keycloak.ClientConnection; import org.keycloak.models.AdminRoles; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -52,18 +51,19 @@ public class RealmsAdminResource { protected static final Logger logger = Logger.getLogger(RealmsAdminResource.class); protected AdminAuth auth; protected TokenManager tokenManager; - protected AdminEventBuilder adminEvent; @Context protected KeycloakSession session; @Context protected KeycloakApplication keycloak; + + @Context + protected ClientConnection clientConnection; - public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager, AdminEventBuilder adminEvent) { + public RealmsAdminResource(AdminAuth auth, TokenManager tokenManager) { this.auth = auth; this.tokenManager = tokenManager; - this.adminEvent = adminEvent; } public static final CacheControl noCache = new CacheControl(); @@ -92,7 +92,6 @@ public class RealmsAdminResource { ClientModel adminApp = auth.getRealm().getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm())); addRealmRep(reps, auth.getRealm(), adminApp); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); logger.debug(("getRealms()")); return reps; } @@ -135,8 +134,6 @@ public class RealmsAdminResource { URI location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build(); logger.debugv("imported realm success, sending back: {0}", location.toString()); - adminEvent.operation(OperationType.CREATE).resourcePath(location.toString()).representation(rep).success(); - return Response.created(location).build(); } catch (ModelDuplicateException e) { return ErrorResponse.exists("Realm " + rep.getRealm() + " already exists"); @@ -183,7 +180,6 @@ public class RealmsAdminResource { URI location = null; if (inputParts.size() == 1) { location = AdminRoot.realmsUrl(uriInfo).path(realm.getName()).build(); - adminEvent.operation(OperationType.CREATE).resourcePath(location.toString()).representation(rep).success(); return Response.created(location).build(); } } @@ -229,7 +225,9 @@ public class RealmsAdminResource { } else { realmAuth = new RealmAuth(auth, realm.getClientByClientId(realmManager.getRealmAdminClientId(auth.getRealm()))); } - + + AdminEventBuilder adminEvent = new AdminEventBuilder(realm, auth, session, clientConnection); + RealmAdminResource adminResource = new RealmAdminResource(realmAuth, realm, tokenManager, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(adminResource); //resourceContext.initResource(adminResource); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java index b54d44f198..4ca16676a6 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleByIdResource.java @@ -3,7 +3,6 @@ package org.keycloak.services.resources.admin; import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -63,9 +62,6 @@ public class RoleByIdResource extends RoleResource { public RoleRepresentation getRole(final @PathParam("role-id") String id) { RoleModel roleModel = getRoleModel(id); auth.requireView(); - - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); - return getRole(roleModel); } @@ -84,9 +80,6 @@ public class RoleByIdResource extends RoleResource { r = RealmAuth.Resource.USER; } auth.init(r); - - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); - return roleModel; } @@ -102,7 +95,7 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); auth.requireManage(); deleteRole(role); - adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri().getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(role).success(); } /** @@ -118,7 +111,7 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); auth.requireManage(); updateRole(rep, role); - adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri().getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(role).representation(rep).success(); } /** @@ -134,7 +127,9 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); auth.requireManage(); addComposites(roles, role); - adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri().getPath()).representation(roles).success(); + + adminEvent.operation(OperationType.ACTION) + .resourcePath(role, session.getContext().getUri().getPath()).representation(roles).success(); } @@ -153,7 +148,6 @@ public class RoleByIdResource extends RoleResource { if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'"); RoleModel role = getRoleModel(id); auth.requireView(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getRoleComposites(role); } @@ -170,7 +164,6 @@ public class RoleByIdResource extends RoleResource { public Set getRealmRoleComposites(final @PathParam("role-id") String id) { RoleModel role = getRoleModel(id); auth.requireView(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getRealmRoleComposites(role); } @@ -194,7 +187,6 @@ public class RoleByIdResource extends RoleResource { throw new NotFoundException("Could not find client: " + appName); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getClientRoleComposites(app, role); } @@ -218,7 +210,6 @@ public class RoleByIdResource extends RoleResource { throw new NotFoundException("Could not find client: " + appId); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getClientRoleComposites(app, role); } @@ -235,7 +226,9 @@ public class RoleByIdResource extends RoleResource { RoleModel role = getRoleModel(id); auth.requireManage(); deleteComposites(roles, role); - adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri().getPath()).success(); + + adminEvent.operation(OperationType.DELETE) + .resourcePath(role, session.getContext().getUri().getPath()).representation(roles).success(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index 43a41f6421..de2e3b425f 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -2,7 +2,6 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -65,7 +64,6 @@ public class RoleContainerResource extends RoleResource { for (RoleModel roleModel : roleModels) { roles.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return roles; } @@ -85,9 +83,7 @@ public class RoleContainerResource extends RoleResource { RoleModel role = roleContainer.addRole(rep.getName()); role.setDescription(rep.getDescription()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(role.getName()).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(role).representation(rep).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build(); } catch (ModelDuplicateException e) { @@ -113,8 +109,6 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find role: " + roleName); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); - return getRole(roleModel); } @@ -136,7 +130,7 @@ public class RoleContainerResource extends RoleResource { } deleteRole(role); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(role).success(); } @@ -160,7 +154,7 @@ public class RoleContainerResource extends RoleResource { try { updateRole(rep, role); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(role).representation(rep).success(); return Response.noContent().build(); } catch (ModelDuplicateException e) { @@ -185,7 +179,7 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find role: " + roleName); } addComposites(roles, role); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(roles).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(role, uriInfo.getPath()).representation(roles).success(); } @@ -206,7 +200,6 @@ public class RoleContainerResource extends RoleResource { if (role == null) { throw new NotFoundException("Could not find role: " + roleName); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return getRoleComposites(role); } @@ -227,7 +220,6 @@ public class RoleContainerResource extends RoleResource { if (role == null) { throw new NotFoundException("Could not find role: " + roleName); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return getRealmRoleComposites(role); } @@ -256,7 +248,6 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find client: " + clientId); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return getClientRoleComposites(app, role); } @@ -286,7 +277,6 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find client: " + id); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return getClientRoleComposites(client, role); } @@ -310,8 +300,7 @@ public class RoleContainerResource extends RoleResource { throw new NotFoundException("Could not find role: " + roleName); } deleteComposites(roles, role); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(role, uriInfo.getPath()).success(); } - } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java index 2825dac99d..7f195c59f2 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java @@ -2,7 +2,6 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -17,9 +16,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.UriInfo; import java.util.ArrayList; import java.util.List; @@ -62,7 +59,6 @@ public class ScopeMappedClientResource { for (RoleModel roleModel : mappings) { mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return mapRep; } @@ -79,7 +75,6 @@ public class ScopeMappedClientResource { auth.requireView(); Set roles = scopedClient.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return ScopeMappedResource.getAvailable(client, roles); } @@ -96,7 +91,6 @@ public class ScopeMappedClientResource { auth.requireView(); Set roles = scopedClient.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return ScopeMappedResource.getComposite(client, roles); } @@ -116,9 +110,8 @@ public class ScopeMappedClientResource { throw new NotFoundException("Role not found"); } client.addScopeMapping(roleModel); + adminEvent.operation(OperationType.CREATE).resourcePath(client, "/roles").representation(roles).success(); } - adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri().getPath()).representation(roles).success(); - } /** @@ -146,6 +139,6 @@ public class ScopeMappedClientResource { client.deleteScopeMapping(roleModel); } } - adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri().getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client, "/roles").representation(roles).success(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 16b87440b5..97b5e3b8e9 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -2,7 +2,6 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -91,7 +90,6 @@ public class ScopeMappedResource { } } } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return all; } @@ -112,7 +110,6 @@ public class ScopeMappedResource { for (RoleModel roleModel : realmMappings) { realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return realmMappingsRep; } @@ -129,7 +126,6 @@ public class ScopeMappedResource { auth.requireView(); Set roles = realm.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getAvailable(client, roles); } @@ -157,7 +153,6 @@ public class ScopeMappedResource { auth.requireView(); Set roles = realm.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getComposite(client, roles); } @@ -187,7 +182,7 @@ public class ScopeMappedResource { } client.addScopeMapping(roleModel); } - adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri().getPath()).representation(roles).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(client, "/roles").representation(roles).success(); } @@ -217,7 +212,7 @@ public class ScopeMappedResource { client.deleteScopeMapping(roleModel); } } - adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri().getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client, "/roles").representation(roles).success(); } @@ -228,7 +223,6 @@ public class ScopeMappedResource { if (app == null) { throw new NotFoundException("Role not found"); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return new ScopeMappedClientResource(realm, auth, client, session, app, adminEvent); } @@ -239,7 +233,6 @@ public class ScopeMappedResource { if (app == null) { throw new NotFoundException("Client not found"); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return new ScopeMappedClientResource(realm, auth, client, session, app, adminEvent); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java index 39e180a68d..9bd8160e57 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserClientRoleMappingsResource.java @@ -3,7 +3,6 @@ package org.keycloak.services.resources.admin; import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; @@ -69,7 +68,6 @@ public class UserClientRoleMappingsResource { for (RoleModel roleModel : mappings) { mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return mapRep; } @@ -90,7 +88,6 @@ public class UserClientRoleMappingsResource { for (RoleModel roleModel : roles) { if (user.hasRole(roleModel)) mapRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return mapRep; } @@ -107,7 +104,6 @@ public class UserClientRoleMappingsResource { auth.requireView(); Set available = client.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(session.getContext().getUri().getPath()).success(); return getAvailableRoles(user, available); } @@ -142,7 +138,7 @@ public class UserClientRoleMappingsResource { } user.grantRole(roleModel); } - adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri().getPath()).representation(roles).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(client, user, "/roles/").representation(roles).success(); } @@ -175,6 +171,6 @@ public class UserClientRoleMappingsResource { user.deleteRoleMapping(roleModel); } } - adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri().getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(client, user, "/roles/").representation(roles).success(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java index a1d6851a9f..7bc54a95fd 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationResource.java @@ -4,7 +4,6 @@ import org.jboss.logging.Logger; import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.constants.KerberosConstants; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -84,7 +83,6 @@ public class UserFederationResource { rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions()); providers.add(rep); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return providers; } @@ -107,7 +105,6 @@ public class UserFederationResource { rep.setId(factory.getId()); rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions()); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return rep; } @@ -134,9 +131,7 @@ public class UserFederationResource { new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId()); checkKerberosCredential(model); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(model.getId()).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(model).representation(rep).success(); return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); } @@ -162,7 +157,7 @@ public class UserFederationResource { new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId()); checkKerberosCredential(model); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(model).representation(rep).success(); } @@ -179,7 +174,6 @@ public class UserFederationResource { auth.requireView(); for (UserFederationProviderModel model : realm.getUserFederationProviders()) { if (model.getId().equals(id)) { - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return ModelToRepresentation.toRepresentation(model); } } @@ -201,7 +195,7 @@ public class UserFederationResource { realm.removeUserFederationProvider(model); new UsersSyncManager().removePeriodicSyncForProvider(session.getProvider(TimerProvider.class), model); - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(model).success(); } @@ -222,7 +216,6 @@ public class UserFederationResource { UserFederationProviderRepresentation rep = ModelToRepresentation.toRepresentation(model); reps.add(rep); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return reps; } @@ -246,7 +239,7 @@ public class UserFederationResource { } else if ("triggerChangedUsersSync".equals(action)) { syncManager.syncChangedUsers(session.getKeycloakSessionFactory(), realm.getId(), model); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(model, "/sync").success(); return Response.noContent().build(); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index 291387e4b7..c84b635e7a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -7,7 +7,6 @@ import org.jboss.resteasy.spi.NotFoundException; import org.keycloak.ClientConnection; import org.keycloak.email.EmailException; import org.keycloak.email.EmailProvider; -import org.keycloak.events.AdminEventBuilder; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientSessionModel; @@ -122,7 +121,7 @@ public class UsersResource { throw new NotFoundException("User not found"); } updateUserFromRep(user, rep); - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.UPDATE).resourcePath(user).representation(rep).success(); if (session.getTransaction().isActive()) { session.getTransaction().commit(); @@ -159,9 +158,7 @@ public class UsersResource { UserModel user = session.users().addUser(realm, rep.getUsername()); updateUserFromRep(user, rep); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo.getAbsolutePathBuilder() - .path(user.getUsername()).build().toString().substring(uriInfo.getBaseUri().toString().length())) - .representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(user).representation(rep).success(); if (session.getTransaction().isActive()) { session.getTransaction().commit(); @@ -228,8 +225,6 @@ public class UsersResource { throw new NotFoundException("User not found"); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); - UserRepresentation rep = ModelToRepresentation.toRepresentation(user); if (realm.isIdentityFederationEnabled()) { @@ -268,7 +263,6 @@ public class UsersResource { UserSessionRepresentation rep = ModelToRepresentation.toRepresentation(session); reps.add(rep); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return reps; } @@ -300,7 +294,6 @@ public class UsersResource { } } } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return result; } @@ -319,7 +312,7 @@ public class UsersResource { FederatedIdentityModel socialLink = new FederatedIdentityModel(provider, rep.getUserId(), rep.getUserName()); session.users().addFederatedIdentity(realm, user, socialLink); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(rep).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(user, uriInfo.getPath(), true).representation(rep).success(); return Response.noContent().build(); } @@ -335,7 +328,7 @@ public class UsersResource { if (!session.users().removeFederatedIdentity(realm, user, provider)) { throw new NotFoundException("Link not found"); } - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(user, uriInfo.getPath(), true).success(); } /** @@ -362,7 +355,6 @@ public class UsersResource { UserConsentRepresentation rep = ModelToRepresentation.toRepresentation(consent); result.add(rep); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return result; } @@ -390,7 +382,7 @@ public class UsersResource { } else { throw new NotFoundException("Consent not found for user " + username + " and client " + clientId); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(user, client, uriInfo.getPath()).success(); } /** @@ -412,7 +404,7 @@ public class UsersResource { for (UserSessionModel userSession : userSessions) { AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, clientConnection, headers, true); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success(); } /** @@ -434,7 +426,7 @@ public class UsersResource { boolean removed = new UserManager(session).removeUser(realm, user); if (removed) { - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(user).success(); return Response.noContent().build(); } else { return ErrorResponse.error("User couldn't be deleted", Response.Status.BAD_REQUEST); @@ -543,7 +535,6 @@ public class UsersResource { } } } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return all; } @@ -570,7 +561,6 @@ public class UsersResource { for (RoleModel roleModel : realmMappings) { realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel)); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return realmMappingsRep; } @@ -599,7 +589,6 @@ public class UsersResource { realmMappingsRep.add(ModelToRepresentation.toRepresentation(roleModel)); } } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return realmMappingsRep; } @@ -622,7 +611,6 @@ public class UsersResource { } Set available = realm.getRoles(); - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return UserClientRoleMappingsResource.getAvailableRoles(user, available); } @@ -652,7 +640,7 @@ public class UsersResource { user.grantRole(roleModel); } - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).representation(roles).success(); + adminEvent.operation(OperationType.CREATE).resourcePath(user, realm, uriInfo.getPath()).representation(roles).success(); } @@ -690,7 +678,7 @@ public class UsersResource { } } - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.DELETE).resourcePath(user, realm, uriInfo.getPath()).representation(roles).success(); } @Path("{username}/role-mappings/clients/{clientId}") @@ -705,7 +693,6 @@ public class UsersResource { if (client == null) { throw new NotFoundException("Client not found"); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return new UserClientRoleMappingsResource(realm, auth, user, client, adminEvent); } @@ -722,7 +709,6 @@ public class UsersResource { throw new NotFoundException("Client not found"); } - adminEvent.operation(OperationType.VIEW).resourcePath(uriInfo.getPath()).success(); return new UserClientRoleMappingsResource(realm, auth, user, client, adminEvent); } @@ -757,7 +743,7 @@ public class UsersResource { } if (pass.isTemporary()) user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success(); } /** @@ -777,7 +763,7 @@ public class UsersResource { } user.setTotp(false); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success(); } /** @@ -854,7 +840,7 @@ public class UsersResource { //audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID, accessCode.getCodeId()).success(); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo.getPath()).success(); + adminEvent.operation(OperationType.ACTION).resourcePath(user, uriInfo.getPath()).success(); return Response.ok().build(); } catch (EmailException e) { diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java index dacf7c5e3d..58c569899e 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/events/AdminEventStoreProviderTest.java @@ -42,7 +42,7 @@ public class AdminEventStoreProviderTest { @Test public void save() { - eventStore.onEvent(create(OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); } @Test @@ -50,19 +50,19 @@ public class AdminEventStoreProviderTest { long oldest = System.currentTimeMillis() - 30000; long newest = System.currentTimeMillis() + 30000; - eventStore.onEvent(create(OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(newest, OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(newest, OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(OperationType.VIEW, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(oldest, OperationType.VIEW, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(OperationType.VIEW, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(oldest, "realmId", OperationType.CREATE, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); resetSession(); Assert.assertEquals(5, eventStore.createAdminQuery().authClient("clientId").getResultList().size()); Assert.assertEquals(5, eventStore.createAdminQuery().authRealm("realmId").getResultList().size()); - Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.VIEW).getResultList().size()); - Assert.assertEquals(6, eventStore.createAdminQuery().operation(OperationType.VIEW, OperationType.ACTION).getResultList().size()); + Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.CREATE).getResultList().size()); + Assert.assertEquals(6, eventStore.createAdminQuery().operation(OperationType.CREATE, OperationType.ACTION).getResultList().size()); Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId").getResultList().size()); Assert.assertEquals(1, eventStore.createAdminQuery().authUser("userId").operation(OperationType.ACTION).getResultList().size()); @@ -95,14 +95,14 @@ public class AdminEventStoreProviderTest { e.printStackTrace(); } - eventStore.onEvent(create(date1, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date1, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date2, OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date2, OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date3, OperationType.UPDATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date3, OperationType.DELETE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date4, OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(date4, OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date1, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date1, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date2, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date2, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date3, "realmId", OperationType.UPDATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date3, "realmId", OperationType.DELETE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date4, "realmId2", OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(date4, "realmId2", OperationType.CREATE, "realmId2", "clientId2", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); resetSession(); @@ -115,12 +115,11 @@ public class AdminEventStoreProviderTest { Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId").getResultList().size()); Assert.assertEquals(4, eventStore.createAdminQuery().authUser("userId2").getResultList().size()); - Assert.assertEquals(2, eventStore.createAdminQuery().operation(OperationType.VIEW).getResultList().size()); Assert.assertEquals(2, eventStore.createAdminQuery().operation(OperationType.ACTION).getResultList().size()); - Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.VIEW, OperationType.ACTION).getResultList().size()); + Assert.assertEquals(6, eventStore.createAdminQuery().operation(OperationType.CREATE, OperationType.ACTION).getResultList().size()); Assert.assertEquals(1, eventStore.createAdminQuery().operation(OperationType.UPDATE).getResultList().size()); Assert.assertEquals(1, eventStore.createAdminQuery().operation(OperationType.DELETE).getResultList().size()); - Assert.assertEquals(2, eventStore.createAdminQuery().operation(OperationType.CREATE).getResultList().size()); + Assert.assertEquals(4, eventStore.createAdminQuery().operation(OperationType.CREATE).getResultList().size()); Assert.assertEquals(8, eventStore.createAdminQuery().fromTime("2015-03-04").getResultList().size()); Assert.assertEquals(8, eventStore.createAdminQuery().toTime("2015-03-07").getResultList().size()); @@ -146,12 +145,12 @@ public class AdminEventStoreProviderTest { long oldest = System.currentTimeMillis() - 30000; long newest = System.currentTimeMillis() + 30000; - eventStore.onEvent(create(OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(newest, OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(newest, OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(OperationType.VIEW, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(oldest, OperationType.VIEW, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(OperationType.VIEW, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(newest, "realmId", OperationType.ACTION, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(oldest, "realmId", OperationType.CREATE, "realmId", "clientId2", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create("realmId", OperationType.CREATE, "realmId", "clientId", "userId2", "127.0.0.1", "/admin/realms/master", "error"), false); resetSession(); @@ -165,11 +164,11 @@ public class AdminEventStoreProviderTest { @Test public void clear() { - eventStore.onEvent(create(System.currentTimeMillis() - 30000, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis() - 20000, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis(), OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis(), OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis() - 30000, OperationType.VIEW, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 20000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId2", OperationType.CREATE, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); resetSession(); @@ -180,36 +179,37 @@ public class AdminEventStoreProviderTest { @Test public void clearOld() { - eventStore.onEvent(create(System.currentTimeMillis() - 30000, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis() - 20000, OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis(), OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis(), OperationType.VIEW, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); - eventStore.onEvent(create(System.currentTimeMillis() - 30000, OperationType.VIEW, "realmId2", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 20000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis(), "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); + eventStore.onEvent(create(System.currentTimeMillis() - 30000, "realmId", OperationType.CREATE, "realmId", "clientId", "userId", "127.0.0.1", "/admin/realms/master", "error"), false); resetSession(); eventStore.clearAdmin("realmId", System.currentTimeMillis() - 10000); - Assert.assertEquals(3, eventStore.createAdminQuery().getResultList().size()); + Assert.assertEquals(2, eventStore.createAdminQuery().getResultList().size()); } - private AdminEvent create(OperationType operation, String realmId, String clientId, String userId, String ipAddress, String resourcePath, String error) { - return create(System.currentTimeMillis(), operation, realmId, clientId, userId, ipAddress, resourcePath, error); + private AdminEvent create(String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) { + return create(System.currentTimeMillis(), realmId, operation, authRealmId, authClientId, authUserId, authIpAddress, resourcePath, error); } - private AdminEvent create(Date date, OperationType operation, String realmId, String clientId, String userId, String ipAddress, String resourcePath, String error) { - return create(date.getTime(), operation, realmId, clientId, userId, ipAddress, resourcePath, error); + private AdminEvent create(Date date, String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) { + return create(date.getTime(), realmId, operation, authRealmId, authClientId, authUserId, authIpAddress, resourcePath, error); } - private AdminEvent create(long time, OperationType operation, String realmId, String clientId, String userId, String ipAddress, String resourcePath, String error) { + private AdminEvent create(long time, String realmId, OperationType operation, String authRealmId, String authClientId, String authUserId, String authIpAddress, String resourcePath, String error) { AdminEvent e = new AdminEvent(); e.setTime(time); + e.setRealmId(realmId); e.setOperationType(operation); AuthDetails authDetails = new AuthDetails(); - authDetails.setRealmId(realmId); - authDetails.setClientId(clientId); - authDetails.setUserId(userId); - authDetails.setIpAddress(ipAddress); + authDetails.setRealmId(authRealmId); + authDetails.setClientId(authClientId); + authDetails.setUserId(authUserId); + authDetails.setIpAddress(authIpAddress); e.setAuthDetails(authDetails); e.setResourcePath(resourcePath); e.setError(error);