keycloak-aplcache
Changes
examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java 62(+61 -1)
forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js 42(+33 -9)
Details
diff --git a/events/api/src/main/java/org/keycloak/events/Event.java b/events/api/src/main/java/org/keycloak/events/Event.java
index 0099e83..34c992f 100644
--- a/events/api/src/main/java/org/keycloak/events/Event.java
+++ b/events/api/src/main/java/org/keycloak/events/Event.java
@@ -17,6 +17,10 @@ public class Event {
private String clientId;
private String userId;
+
+ private long fromDate;
+
+ private long toDate;
private String sessionId;
@@ -58,6 +62,22 @@ public class Event {
this.clientId = clientId;
}
+ public long getFromDate() {
+ return fromDate;
+ }
+
+ public void setFromDate(long fromDate) {
+ this.fromDate = fromDate;
+ }
+
+ public long getToDate() {
+ return toDate;
+ }
+
+ public void setToDate(long toDate) {
+ this.toDate = toDate;
+ }
+
public String getUserId() {
return userId;
}
@@ -105,6 +125,8 @@ public class Event {
clone.realmId = realmId;
clone.clientId = clientId;
clone.userId = userId;
+ clone.fromDate = fromDate;
+ clone.toDate = toDate;
clone.sessionId = sessionId;
clone.ipAddress = ipAddress;
clone.error = error;
diff --git a/events/api/src/main/java/org/keycloak/events/EventQuery.java b/events/api/src/main/java/org/keycloak/events/EventQuery.java
index 00d9a4f..edc5f27 100644
--- a/events/api/src/main/java/org/keycloak/events/EventQuery.java
+++ b/events/api/src/main/java/org/keycloak/events/EventQuery.java
@@ -15,6 +15,12 @@ public interface EventQuery {
public EventQuery user(String userId);
+ public EventQuery dateRange(String fromDate, String toDate);
+
+ public EventQuery fromDate(String fromDate);
+
+ public EventQuery toDate(String toDate);
+
public EventQuery ipAddress(String ipAddress);
public EventQuery firstResult(int result);
diff --git a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
index 4c7fbe5..621d830 100644
--- a/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
+++ b/events/jpa/src/main/java/org/keycloak/events/jpa/JpaEventQuery.java
@@ -10,6 +10,9 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -63,8 +66,49 @@ public class JpaEventQuery implements EventQuery {
predicates.add(cb.equal(root.get("userId"), userId));
return this;
}
+
+ @Override
+ public EventQuery dateRange(String fromDate, String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null, to = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ predicates.add(cb.greaterThanOrEqualTo(root.<Long>get("time"), from));
+ predicates.add(cb.lessThanOrEqualTo(root.<Long>get("time"), to));
+ return this;
+ }
+
+ @Override
+ public EventQuery fromDate(String fromDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ predicates.add(cb.greaterThanOrEqualTo(root.<Long>get("time"), from));
+ return this;
+ }
@Override
+ public EventQuery toDate(String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long to = null;
+ try {
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ predicates.add(cb.lessThanOrEqualTo(root.<Long>get("time"), to));
+ return this;
+ }
+
+ @Override
public EventQuery ipAddress(String ipAddress) {
predicates.add(cb.equal(root.get("ipAddress"), ipAddress));
return this;
diff --git a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
index fe08949..5f4ff3c 100755
--- a/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
+++ b/events/mongo/src/main/java/org/keycloak/events/mongo/MongoEventQuery.java
@@ -1,12 +1,16 @@
package org.keycloak.events.mongo;
import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
+
import org.keycloak.events.Event;
import org.keycloak.events.EventQuery;
import org.keycloak.events.EventType;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
@@ -52,6 +56,47 @@ public class MongoEventQuery implements EventQuery {
query.put("userId", userId);
return this;
}
+
+
+ @Override
+ public EventQuery dateRange(String fromDate, String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null, to = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ query.put("time", BasicDBObjectBuilder.start("$gte", from).add("$lte", to).get());
+ return this;
+ }
+
+ @Override
+ public EventQuery fromDate(String fromDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ query.put("time", BasicDBObjectBuilder.start("$gte", from).get());
+ return this;
+ }
+
+ @Override
+ public EventQuery toDate(String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long to = null;
+ try {
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ query.put("time", BasicDBObjectBuilder.start("$lte", to).get());
+ return this;
+ }
@Override
public EventQuery ipAddress(String ipAddress) {
diff --git a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java
index 06038c7..e8fbcff 100644
--- a/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java
+++ b/examples/providers/event-store-mem/src/main/java/org/keycloak/examples/providers/events/MemEventQuery.java
@@ -4,6 +4,8 @@ import org.keycloak.events.Event;
import org.keycloak.events.EventQuery;
import org.keycloak.events.EventType;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@@ -73,7 +75,65 @@ public class MemEventQuery implements EventQuery {
}
return this;
}
-
+
+ @Override
+ public EventQuery dateRange(String fromDate, String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null, to = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ Iterator<Event> itr = this.events.iterator();
+ while (itr.hasNext()) {
+ if (!(itr.next().getFromDate() >= from && itr.next().getToDate() <= to)) {
+ itr.remove();
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public EventQuery fromDate(String fromDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long from = null;
+ try {
+ from = df.parse(fromDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ Iterator<Event> itr = this.events.iterator();
+ while (itr.hasNext()) {
+ if (!(itr.next().getFromDate() >= from)) {
+ itr.remove();
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public EventQuery toDate(String toDate) {
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ Long to = null;
+ try {
+ to = df.parse(toDate).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ Iterator<Event> itr = this.events.iterator();
+ while (itr.hasNext()) {
+ if (!(itr.next().getToDate() <= to)) {
+ itr.remove();
+ }
+ }
+ return this;
+ }
+
@Override
public EventQuery ipAddress(String ipAddress) {
Iterator<Event> itr = this.events.iterator();
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
index 7c5090d..d530f09 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/realm.js
@@ -1154,14 +1154,20 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm) {
$scope.realm = realm;
$scope.page = 0;
-
+
+ $scope.eventTypes = [{tag:'LOGIN'}, {tag:'REGISTER'}, {tag:'LOGOUT'}, {tag:'CODE_TO_TOKEN'}, {tag:'REFRESH_TOKEN'},
+ {tag:'LOGIN_ERROR'}, {tag:'REGISTER_ERROR'}, {tag:'LOGOUT_ERROR'}, {tag:'CODE_TO_TOKEN_ERROR'}, {tag:'REFRESH_TOKEN_ERROR'},
+ {tag:'VALIDATE_ACCESS_TOKEN'}, {tag:'VALIDATE_ACCESS_TOKEN_ERROR'}, {tag:'SOCIAL_LINK'}, {tag:'SOCIAL_LINK_ERROR'}, {tag:'REMOVE_FEDERATED_IDENTITY'},
+ {tag:'REMOVE_SOCIAL_LINK_ERROR'}, {tag:'UPDATE_EMAIL'}, {tag:'UPDATE_PROFILE'}, {tag:'UPDATE_PASSWORD'}, {tag:'UPDATE_TOTP'}];
+
$scope.query = {
id : realm.realm,
- max : 5,
+ max : 10,
first : 0
}
$scope.update = function() {
+ $scope.query.first = 0;
for (var i in $scope.query) {
if ($scope.query[i] === '') {
delete $scope.query[i];
@@ -1169,13 +1175,31 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm) {
}
$scope.events = RealmEvents.query($scope.query);
}
-
+
+ $scope.reset = function() {
+ $scope.query.first = 0;
+ $scope.query.max = 10;
+ $scope.query.type = '';
+ $scope.query.client = '';
+ $scope.query.user = '';
+ $scope.query.dateFrom = '';
+ $scope.query.dateTo = '';
+
+ $scope.update();
+ }
+
+ $scope.queryUpdate = function() {
+ for (var i in $scope.query) {
+ if ($scope.query[i] === '') {
+ delete $scope.query[i];
+ }
+ }
+ $scope.events = RealmEvents.query($scope.query);
+ }
+
$scope.firstPage = function() {
$scope.query.first = 0;
- if ($scope.query.first < 0) {
- $scope.query.first = 0;
- }
- $scope.update();
+ $scope.queryUpdate();
}
$scope.previousPage = function() {
@@ -1183,12 +1207,12 @@ module.controller('RealmEventsCtrl', function($scope, RealmEvents, realm) {
if ($scope.query.first < 0) {
$scope.query.first = 0;
}
- $scope.update();
+ $scope.queryUpdate();
}
$scope.nextPage = function() {
$scope.query.first += parseInt($scope.query.max);
- $scope.update();
+ $scope.queryUpdate();
}
$scope.update();
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html
index 7a66013..e810717 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/realm-events.html
@@ -27,14 +27,20 @@
Filter
</button>
<button class="btn btn-default btn-primary" data-ng-click="update()">Update</button>
+ <button class="btn btn-default btn-primary" data-ng-click="reset()">Reset</button>
</div>
<form class="form-horizontal">
<div class="form-group" data-ng-show="filter">
- <label class="col-sm-2 control-label" for="type">Event Type</label>
- <div class="col-sm-4">
- <input class="form-control" type="text" id="type" name="event" data-ng-model="query.type">
- </div>
- </div>
+ <label class="col-sm-2 control-label" for="eventType">Event Type</label>
+ <div class="col-sm-5">
+ <select style="width:230px" data-ui-select2 data-ng-model="query.type" data-placeholder="Select Event Type">
+ <!-- empty option gets placeholder working -->
+ <option value=""></option>
+ <!-- ng-repeat to populate dynamic options -->
+ <option data-ng-repeat="event in eventTypes">{{event.tag}}</option>
+ </select>
+ </div>
+ </div>
<div class="form-group" data-ng-show="filter">
<label class="col-sm-2 control-label" for="client">Client</label>
<div class="col-sm-4">
@@ -47,6 +53,20 @@
<input class="form-control" type="text" id="user" name="user" data-ng-model="query.user">
</div>
</div>
+
+ <div class="form-group" data-ng-show="filter">
+ <label class="col-sm-2 control-label" for="dateFrom">Date (From)</label>
+ <div class="col-sm-4">
+ <input class="form-control" type="date" id="dateFrom" name="dateFrom" data-ng-model="query.dateFrom">
+ </div>
+ </div>
+ <div class="form-group" data-ng-show="filter">
+ <label class="col-sm-2 control-label" for="toDate">Date (To)</label>
+ <div class="col-sm-4">
+ <input class="form-control" type="date" id="dateTo" name="dateTo" data-ng-model="query.dateTo">
+ </div>
+ </div>
+
</form>
</th>
</tr>
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 5b807ca..11c6311 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
@@ -397,8 +397,10 @@ public class RealmAdminResource {
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
- public List<Event> getEvents(@QueryParam("client") String client, @QueryParam("type") String type, @QueryParam("user") String user,
- @QueryParam("ipAddress") String ipAddress, @QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
+ public List<Event> getEvents(@QueryParam("client") String client, @QueryParam("type") String type,
+ @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);
@@ -413,6 +415,15 @@ public class RealmAdminResource {
if (user != null) {
query.user(user);
}
+
+ if (dateFrom != null && dateTo != null) {
+ query.dateRange(dateFrom, dateTo);
+ } else if(dateFrom != null) {
+ query.fromDate(dateFrom);
+ } else if(dateTo != null) {
+ query.toDate(dateTo);
+ }
+
if (ipAddress != null) {
query.ipAddress(ipAddress);
}