keycloak-aplcache
Changes
forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js 2(+1 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js 32(+17 -15)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info.html 254(+92 -162)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info-providers.html 55(+55 -0)
services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java 54(+54 -0)
services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java 17(+17 -0)
services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java 200(+38 -162)
services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java 108(+108 -0)
services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java 39(+39 -0)
Details
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
index 4f02ce6..5e01598 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
@@ -82,8 +82,8 @@ module.config([ '$routeProvider', function($routeProvider) {
realm : function(RealmLoader) {
return RealmLoader();
},
- serverInfo : function(ServerInfoLoader) {
- return ServerInfoLoader();
+ serverInfo : function(ServerInfo) {
+ return ServerInfo.delay;
}
},
controller : 'RealmLoginSettingsCtrl'
@@ -1135,11 +1135,20 @@ module.config([ '$routeProvider', function($routeProvider) {
.when('/server-info', {
templateUrl : resourceUrl + '/partials/server-info.html',
resolve : {
- serverInfoPage : function(ServerInfoPageLoader) {
- return ServerInfoPageLoader();
+ serverInfo : function(ServerInfoLoader) {
+ return ServerInfoLoader();
}
},
- controller : 'ServerInfoPageCtrl'
+ controller : 'ServerInfoCtrl'
+ })
+ .when('/server-info/providers', {
+ templateUrl : resourceUrl + '/partials/server-info-providers.html',
+ resolve : {
+ serverInfo : function(ServerInfoLoader) {
+ return ServerInfoLoader();
+ }
+ },
+ controller : 'ServerInfoCtrl'
})
.when('/logout', {
templateUrl : resourceUrl + '/partials/home.html',
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
index 6331c9d..8ad8ae6 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
@@ -549,7 +549,7 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, $route, se
"bearer-only"
];
- $scope.protocols = serverInfo.protocols;
+ $scope.protocols = Object.keys(serverInfo.providers['login-protocol'].providers);
$scope.signatureAlgorithms = [
"RSA_SHA1",
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 0b5745a..15a8fa9 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
@@ -7,9 +7,6 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, WhoAmI, Current, $
$scope.resourceUrl = resourceUrl;
$scope.auth = Auth;
$scope.serverInfo = ServerInfo.get();
- $scope.serverInfoUpdate = function() {
- $scope.serverInfo = ServerInfo.get();
- };
function hasAnyAccess() {
var realmAccess = Auth.user && Auth.user['realm_access'];
@@ -125,18 +122,23 @@ module.controller('RealmTabCtrl', function(Dialog, $scope, Current, Realm, Notif
};
});
-module.controller('ServerInfoPageCtrl', function($scope, ServerInfoPage) {
- $scope.serverInfoPage = ServerInfoPage.get();
- $scope.serverInfoPageUpdate = function() {
- $scope.serverInfoPage = ServerInfoPage.get();
- };
-});
+module.controller('ServerInfoCtrl', function($scope, ServerInfo) {
+ ServerInfo.reload();
-module.controller('ServerInfoPageCtrl', function($scope, ServerInfoPage) {
- $scope.serverInfoPage = ServerInfoPage.get();
- $scope.serverInfoPageUpdate = function() {
- $scope.serverInfoPage = ServerInfoPage.get();
- };
+ $scope.serverInfo = ServerInfo.get();
+
+ $scope.$watch($scope.serverInfo, function() {
+ $scope.providers = [];
+ for(var spi in $scope.serverInfo.providers) {
+ var p = angular.copy($scope.serverInfo.providers[spi]);
+ p.name = spi;
+ $scope.providers.push(p)
+ }
+ });
+
+ $scope.serverInfoReload = function() {
+ ServerInfo.reload();
+ }
});
module.controller('RealmListCtrl', function($scope, Realm, Current) {
@@ -1231,7 +1233,7 @@ module.controller('RealmEventsConfigCtrl', function($scope, eventsConfig, RealmE
}
});
- $scope.eventListeners = serverInfo.eventListeners;
+ $scope.eventListeners = Object.keys(serverInfo.providers.eventsListener.providers);
$scope.eventSelectOptions = {
'multiple': true,
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
index 2e65b3c..c347759 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/loaders.js
@@ -35,12 +35,10 @@ module.factory('RealmListLoader', function(Loader, Realm, $q) {
return Loader.get(Realm);
});
-module.factory('ServerInfoLoader', function(Loader, ServerInfo, $q) {
- return Loader.get(ServerInfo);
-});
-
-module.factory('ServerInfoPageLoader', function(Loader, ServerInfoPage, $q) {
- return Loader.get(ServerInfoPage);
+module.factory('ServerInfoLoader', function(Loader, ServerInfo) {
+ return function() {
+ return ServerInfo.promise;
+ };
});
module.factory('RealmLoader', function(Loader, Realm, $route, $q) {
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
index b5d8c33..04929ef 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -215,12 +215,26 @@ module.factory('RealmLDAPConnectionTester', function($resource) {
return $resource(authUrl + '/admin/realms/:realm/testLDAPConnection');
});
-module.factory('ServerInfo', function($resource) {
- return $resource(authUrl + '/admin/serverinfo');
-});
+module.service('ServerInfo', function($resource, $q, $http) {
+ var info = {};
+ var delay = $q.defer();
+
+ $http.get(authUrl + '/admin/serverinfo').success(function(data) {
+ info = data;
+ delay.resolve(info);
+ });
-module.factory('ServerInfoPage', function($resource) {
- return $resource(authUrl + '/admin/serverinfopage');
+ return {
+ get: function() {
+ return info;
+ },
+ reload: function() {
+ $http.get(authUrl + '/admin/serverinfo').success(function(data) {
+ angular.copy(data, info);
+ });
+ },
+ promise: delay.promise
+ }
});
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info.html
index 991f208..a92c774 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info.html
@@ -1,174 +1,104 @@
-<div class="col-md-12">
- <h1>Server Info</h1>
+<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
+ <h1>
+ Server Info
+ <i id="serverInfoReload" class="pficon pficon-restart clickable" data-ng-click="serverInfoReload()"></i>
+ </h1>
- <table class="table table-striped table-bordered">
- <tr>
- <td width="20%">Keycloak Version</td>
- <td>{{serverInfoPage.version}}</td>
- </tr>
- <tr>
- <td>Server Time</td>
- <td>{{serverInfoPage.serverTime}} (<a style="cursor: pointer" data-ng-click="serverInfoPageUpdate()">update</a>)</td>
- </tr>
- <tr>
- <td>Server Uptime</td>
- <td>{{serverInfoPage.serverUptime}}</td>
- </tr>
- </table>
+ <ul class="nav nav-tabs">
+ <li class="active"><a href="#/server-info">Info</a></li>
+ <li><a href="#/server-info/providers">Providers</a></li>
+ </ul>
- <fieldset>
- <legend>Java VM Memory Statistics</legend>
- <div class="form-group">
- <table class="table table-striped table-bordered" style="margin-top: 0px;">
- <tr>
- <td width="20%">Total Memory</td>
- <td>{{serverInfoPage.memoryInfo.totalFormated}}</td>
- </tr>
- <tr>
- <td>Free Memory</td>
- <td>{{serverInfoPage.memoryInfo.freeFormated}} ({{serverInfoPage.memoryInfo.freePercentage}}%)</td>
- </tr>
- <tr>
- <td>Used Memory</td>
- <td>{{serverInfoPage.memoryInfo.usedFormated}}</td>
- </tr>
- </table>
- </div>
- </fieldset>
-
- <fieldset>
- <legend collapsed>System Info</legend>
- <div class="form-group">
- <table class="table table-striped table-bordered" style="margin-top: 0px;">
- <tr>
- <td width="20%">Current Working Directory</td>
- <td>{{serverInfoPage.systemInfo.userDir}}</td>
- </tr>
- <tr>
- <td>Java Version</td>
- <td>{{serverInfoPage.systemInfo.javaVersion}}</td>
- </tr>
- <tr>
- <td>Java Vendor</td>
- <td>{{serverInfoPage.systemInfo.javaVendor}}</td>
- </tr>
- <tr>
- <td>Java Runtime</td>
- <td>{{serverInfoPage.systemInfo.javaRuntime}}</td>
- </tr>
- <tr>
- <td>Java VM</td>
- <td>{{serverInfoPage.systemInfo.javaVm}}</td>
- </tr>
- <tr>
- <td>Java VM Version</td>
- <td>{{serverInfoPage.systemInfo.javaVmVersion}}</td>
- </tr>
- <tr>
- <td>Java Home</td>
- <td>{{serverInfoPage.systemInfo.javaHome}}</td>
- </tr>
+ <table class="table table-striped table-bordered">
<tr>
- <td>User Name</td>
- <td>{{serverInfoPage.systemInfo.userName}}</td>
+ <td width="20%">Keycloak Version</td>
+ <td>{{serverInfo.systemInfo.version}}</td>
</tr>
<tr>
- <td>User Timezone</td>
- <td>{{serverInfoPage.systemInfo.userTimezone}}</td>
+ <td>Server Time</td>
+ <td>{{serverInfo.systemInfo.serverTime}}</td>
</tr>
<tr>
- <td>User Locale</td>
- <td>{{serverInfoPage.systemInfo.userLocale}}</td>
+ <td>Server Uptime</td>
+ <td>{{serverInfo.systemInfo.uptime}}</td>
</tr>
- <tr>
- <td>System Encoding</td>
- <td>{{serverInfoPage.systemInfo.fileEncoding}}</td>
- </tr>
- <tr>
- <td>Operating System</td>
- <td>{{serverInfoPage.systemInfo.osName}} {{serverInfoPage.systemInfo.osVersion}}</td>
- </tr>
- <tr>
- <td>OS Architecture</td>
- <td>{{serverInfoPage.systemInfo.osArchitecture}}</td>
- </tr>
- </table>
- </div>
- </fieldset>
+ </table>
<fieldset>
- <legend collapsed>Providers</legend>
-
- <div class="form-group">
- <h3>Public SPIs</h3>
- <kc-tooltip>For public SPIs there are built-in providers, but it's also supported to write your own custom providers.</kc-tooltip>
-
- <table class="table table-striped table-bordered">
- <thead>
- <tr>
- <th width="20%">SPI</th>
- <th>Providers</th>
- </tr>
- </thead>
- <tbody>
- <tr data-ng-repeat="spi in (serverInfoPage.providers | filter:{internal:false} | orderBy:'name')">
- <td>{{spi.name}}</td>
- <td>
- <div data-ng-repeat="provider in (spi.implementations | orderBy:'name')">
- {{provider.name}}
- <span ng-show="provider.operationalInfo">
- <button type="button" class="btn btn-default btn-xs" ng-click="collapseRep = !collapseRep">
- <span class="glyphicon glyphicon-plus" data-ng-show="!collapseRep"></span>
- <span class="glyphicon glyphicon-minus" data-ng-show="collapseRep"></span>
- </button>
- <table ng-show="collapseRep" class="table table-striped table-bordered" style="margin-top: 0px;">
- <tr ng-repeat="(key, value) in provider.operationalInfo">
- <td width="20%">{{key}}</td>
- <td>{{value}}</td>
- </tr>
- </table>
- </span>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
-
- <div class="form-group">
- <h3>Internal SPIs</h3>
- <kc-tooltip>For internal SPIs there are only built-in providers. It's not recommended to write your own custom providers as internal SPIs may change or be removed without notice.</kc-tooltip>
+ <legend>Memory</legend>
+ <table class="table table-striped table-bordered" style="margin-top: 0;">
+ <tr>
+ <td width="20%">Total Memory</td>
+ <td>{{serverInfo.memoryInfo.totalFormated}}</td>
+ </tr>
+ <tr>
+ <td>Free Memory</td>
+ <td>{{serverInfo.memoryInfo.freeFormated}} ({{serverInfo.memoryInfo.freePercentage}}%)</td>
+ </tr>
+ <tr>
+ <td>Used Memory</td>
+ <td>{{serverInfo.memoryInfo.usedFormated}}</td>
+ </tr>
+ </table>
+ </fieldset>
- <table class="table table-striped table-bordered">
- <thead>
- <tr>
- <th width="20%">SPI</th>
- <th>Providers</th>
- </tr>
- </thead>
- <tbody>
- <tr data-ng-repeat="spi in (serverInfoPage.providers | filter:{internal:true} | orderBy:'name')">
- <td>{{spi.name}}</td>
- <td>
- <div data-ng-repeat="provider in (spi.implementations | orderBy:'name')">
- {{provider.name}}
- <span ng-show="provider.operationalInfo">
- <button type="button" class="btn btn-default btn-xs" ng-click="collapseRep = !collapseRep">
- <span class="glyphicon glyphicon-plus" data-ng-show="!collapseRep"></span>
- <span class="glyphicon glyphicon-minus" data-ng-show="collapseRep"></span>
- </button>
- <table ng-show="collapseRep" class="table table-striped table-bordered" style="margin-top: 0px;">
- <tr ng-repeat="(key, value) in provider.operationalInfo">
- <td width="20%">{{key}}</td>
- <td>{{value}}</td>
- </tr>
- </table>
- </span>
- </div>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
+ <fieldset>
+ <legend>System</legend>
+ <table class="table table-striped table-bordered" style="margin-top: 0;">
+ <tr>
+ <td width="20%">Current Working Directory</td>
+ <td>{{serverInfo.systemInfo.userDir}}</td>
+ </tr>
+ <tr>
+ <td>Java Version</td>
+ <td>{{serverInfo.systemInfo.javaVersion}}</td>
+ </tr>
+ <tr>
+ <td>Java Vendor</td>
+ <td>{{serverInfo.systemInfo.javaVendor}}</td>
+ </tr>
+ <tr>
+ <td>Java Runtime</td>
+ <td>{{serverInfo.systemInfo.javaRuntime}}</td>
+ </tr>
+ <tr>
+ <td>Java VM</td>
+ <td>{{serverInfo.systemInfo.javaVm}}</td>
+ </tr>
+ <tr>
+ <td>Java VM Version</td>
+ <td>{{serverInfo.systemInfo.javaVmVersion}}</td>
+ </tr>
+ <tr>
+ <td>Java Home</td>
+ <td>{{serverInfo.systemInfo.javaHome}}</td>
+ </tr>
+ <tr>
+ <td>User Name</td>
+ <td>{{serverInfo.systemInfo.userName}}</td>
+ </tr>
+ <tr>
+ <td>User Timezone</td>
+ <td>{{serverInfo.systemInfo.userTimezone}}</td>
+ </tr>
+ <tr>
+ <td>User Locale</td>
+ <td>{{serverInfo.systemInfo.userLocale}}</td>
+ </tr>
+ <tr>
+ <td>System Encoding</td>
+ <td>{{serverInfo.systemInfo.fileEncoding}}</td>
+ </tr>
+ <tr>
+ <td>Operating System</td>
+ <td>{{serverInfo.systemInfo.osName}} {{serverInfo.systemInfo.osVersion}}</td>
+ </tr>
+ <tr>
+ <td>OS Architecture</td>
+ <td>{{serverInfo.systemInfo.osArchitecture}}</td>
+ </tr>
+ </table>
</fieldset>
-</div>
\ No newline at end of file
+</div>
+
+<kc-menu></kc-menu>
\ No newline at end of file
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info-providers.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info-providers.html
new file mode 100755
index 0000000..6f8bbb4
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/server-info-providers.html
@@ -0,0 +1,55 @@
+<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
+ <h1>
+ Server Info
+ <i id="serverInfoReload" class="pficon pficon-restart clickable" data-ng-click="serverInfoReload()"></i>
+ </h1>
+
+ <ul class="nav nav-tabs">
+ <li><a href="#/server-info">Info</a></li>
+ <li class="active"><a href="#/server-info/providers">Providers</a></li>
+ </ul>
+
+ <table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th class="kc-table-actions" colspan="5">
+ <div class="form-inline">
+ <div class="form-group">
+ <div class="input-group">
+ <input type="text" placeholder="Search..." data-ng-model="search" class="form-control search" onkeyup="if(event.keyCode == 13){$(this).next('I').click();}">
+ </div>
+ </div>
+ </div>
+ </th>
+ </tr>
+ <tr>
+ <th width="20%">SPI</th>
+ <th>Providers</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr data-ng-repeat="spi in (providers | orderBy:'name' | filter:search)">
+ <td>{{spi.name}}</td>
+ <td>
+ <div data-ng-repeat="(providerName, provider) in spi.providers">
+ {{providerName}}
+ <span ng-show="provider.operationalInfo">
+ <button type="button" class="btn btn-default btn-xs" ng-click="collapseRep = !collapseRep">
+ <span class="glyphicon glyphicon-plus" data-ng-show="!collapseRep"></span>
+ <span class="glyphicon glyphicon-minus" data-ng-show="collapseRep"></span>
+ </button>
+ <table ng-show="collapseRep" class="table table-striped table-bordered" style="margin-top: 0px;">
+ <tr ng-repeat="(key, value) in provider.operationalInfo">
+ <td width="20%">{{key}}</td>
+ <td>{{value}}</td>
+ </tr>
+ </table>
+ </span>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+</div>
+
+<kc-menu></kc-menu>
\ No newline at end of file
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 6b3ca3e..97c1472 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
@@ -20,6 +20,7 @@ import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.services.resources.Cors;
+import org.keycloak.services.resources.admin.info.ServerInfoAdminResource;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -218,32 +219,6 @@ public class AdminRoot {
return adminResource;
}
- /**
- * Operational information about the server for "Server Info" page
- *
- * @param headers
- * @return
- */
- @Path("serverinfopage")
- public ServerInfoPageAdminResource getServerInfoPage(@Context final HttpHeaders headers) {
- handlePreflightRequest();
-
- AdminAuth auth = authenticateRealmAdminRequest(headers);
- if (!isAdmin(auth)) {
- throw new ForbiddenException();
- }
-
- if (auth != null) {
- logger.debug("authenticated admin access for: " + auth.getUser().getUsername());
- }
-
- Cors.add(request).allowedOrigins(auth.getToken()).allowedMethods("GET", "PUT", "POST", "DELETE").auth().build(response);
-
- ServerInfoPageAdminResource adminResource = new ServerInfoPageAdminResource();
- ResteasyProviderFactory.getInstance().injectProperties(adminResource);
- return adminResource;
- }
-
protected boolean isAdmin(AdminAuth auth) {
RealmManager realmManager = new RealmManager(session);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java b/services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java
new file mode 100644
index 0000000..56a1110
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java
@@ -0,0 +1,54 @@
+package org.keycloak.services.resources.admin.info;
+
+public class MemoryInfoRepresentation {
+
+ protected long total;
+ protected long used;
+
+ public static MemoryInfoRepresentation create() {
+ MemoryInfoRepresentation rep = new MemoryInfoRepresentation();
+ Runtime runtime = Runtime.getRuntime();
+ rep.total = runtime.maxMemory();
+ rep.used = runtime.totalMemory() - runtime.freeMemory();
+ return rep;
+ }
+
+ public long getTotal() {
+ return total;
+ }
+
+ public String getTotalFormated() {
+ return formatMemory(getTotal());
+ }
+
+ public long getFree() {
+ return getTotal() - getUsed();
+ }
+
+ public String getFreeFormated() {
+ return formatMemory(getFree());
+ }
+
+ public long getUsed() {
+ return used;
+ }
+
+ public String getUsedFormated() {
+ return formatMemory(getUsed());
+ }
+
+ public long getFreePercentage() {
+ return getFree() * 100 / getTotal();
+ }
+
+ private String formatMemory(long bytes) {
+ if (bytes > 1024L * 1024L) {
+ return bytes / (1024L * 1024L) + " MB";
+ } else if (bytes > 1024L) {
+ return bytes / (1024L) + " kB";
+ } else {
+ return bytes + " B";
+ }
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java
new file mode 100644
index 0000000..ffcaeb1
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java
@@ -0,0 +1,17 @@
+package org.keycloak.services.resources.admin.info;
+
+import java.util.Map;
+
+public class ProviderRepresentation {
+
+ private Map<String, String> operationalInfo;
+
+ public Map<String, String> getOperationalInfo() {
+ return operationalInfo;
+ }
+
+ public void setOperationalInfo(Map<String, String> operationalInfo) {
+ this.operationalInfo = operationalInfo;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java
new file mode 100644
index 0000000..9b7f4f5
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java
@@ -0,0 +1,108 @@
+package org.keycloak.services.resources.admin.info;
+
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class ServerInfoRepresentation {
+
+ private SystemInfoRepresentation systemInfo;
+ private MemoryInfoRepresentation memoryInfo;
+
+ private Map<String, List<String>> themes;
+
+ private List<Map<String, String>> socialProviders;
+ private List<Map<String, String>> identityProviders;
+ private List<Map<String, String>> clientImporters;
+
+ private Map<String, SpiInfoRepresentation> providers;
+
+ private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
+ private Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers;
+
+ private Map<String, List<String>> enums;
+
+ public SystemInfoRepresentation getSystemInfo() {
+ return systemInfo;
+ }
+
+ public void setSystemInfo(SystemInfoRepresentation systemInfo) {
+ this.systemInfo = systemInfo;
+ }
+
+ public MemoryInfoRepresentation getMemoryInfo() {
+ return memoryInfo;
+ }
+
+ public void setMemoryInfo(MemoryInfoRepresentation memoryInfo) {
+ this.memoryInfo = memoryInfo;
+ }
+ public Map<String, List<String>> getThemes() {
+ return themes;
+ }
+
+ public void setThemes(Map<String, List<String>> themes) {
+ this.themes = themes;
+ }
+
+ public List<Map<String, String>> getSocialProviders() {
+ return socialProviders;
+ }
+
+ public void setSocialProviders(List<Map<String, String>> socialProviders) {
+ this.socialProviders = socialProviders;
+ }
+
+ public List<Map<String, String>> getIdentityProviders() {
+ return identityProviders;
+ }
+
+ public void setIdentityProviders(List<Map<String, String>> identityProviders) {
+ this.identityProviders = identityProviders;
+ }
+
+ public List<Map<String, String>> getClientImporters() {
+ return clientImporters;
+ }
+
+ public void setClientImporters(List<Map<String, String>> clientImporters) {
+ this.clientImporters = clientImporters;
+ }
+
+ public Map<String, SpiInfoRepresentation> getProviders() {
+ return providers;
+ }
+
+ public void setProviders(Map<String, SpiInfoRepresentation> providers) {
+ this.providers = providers;
+ }
+
+ public Map<String, List<ProtocolMapperTypeRepresentation>> getProtocolMapperTypes() {
+ return protocolMapperTypes;
+ }
+
+ public void setProtocolMapperTypes(Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes) {
+ this.protocolMapperTypes = protocolMapperTypes;
+ }
+
+ public Map<String, List<ProtocolMapperRepresentation>> getBuiltinProtocolMappers() {
+ return builtinProtocolMappers;
+ }
+
+ public void setBuiltinProtocolMappers(Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers) {
+ this.builtinProtocolMappers = builtinProtocolMappers;
+ }
+
+ public Map<String, List<String>> getEnums() {
+ return enums;
+ }
+
+ public void setEnums(Map<String, List<String>> enums) {
+ this.enums = enums;
+ }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java b/services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java
new file mode 100644
index 0000000..3f94a5a
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java
@@ -0,0 +1,39 @@
+package org.keycloak.services.resources.admin.info;
+
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ */
+public class SpiInfoRepresentation {
+
+ private boolean internal;
+ private boolean systemInfo;
+
+ private Map<String, ProviderRepresentation> providers;
+
+ public boolean isInternal() {
+ return internal;
+ }
+
+ public void setInternal(boolean internal) {
+ this.internal = internal;
+ }
+
+ public boolean isSystemInfo() {
+ return systemInfo;
+ }
+
+ public void setSystemInfo(boolean systemInfo) {
+ this.systemInfo = systemInfo;
+ }
+
+ public Map<String, ProviderRepresentation> getProviders() {
+ return providers;
+ }
+
+ public void setProviders(Map<String, ProviderRepresentation> providers) {
+ this.providers = providers;
+ }
+
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java b/services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java
new file mode 100644
index 0000000..bc0329a
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java
@@ -0,0 +1,217 @@
+package org.keycloak.services.resources.admin.info;
+
+import org.keycloak.Version;
+import org.keycloak.models.KeycloakSession;
+
+import java.util.Date;
+import java.util.Locale;
+
+public class SystemInfoRepresentation {
+
+ private String version;
+ private String serverTime;
+ private String uptime;
+ private long uptimeMillis;
+ private String javaVersion;
+ private String javaVendor;
+ private String javaVm;
+ private String javaVmVersion;
+ private String javaRuntime;
+ private String javaHome;
+ private String osName;
+ private String osArchitecture;
+ private String osVersion;
+ private String fileEncoding;
+ private String userName;
+ private String userDir;
+ private String userTimezone;
+ private String userLocale;
+
+ public static SystemInfoRepresentation create(KeycloakSession session) {
+ SystemInfoRepresentation rep = new SystemInfoRepresentation();
+ rep.version = Version.VERSION;
+ rep.serverTime = new Date().toString();
+ rep.uptimeMillis = System.currentTimeMillis() - session.getKeycloakSessionFactory().getServerStartupTimestamp();
+ rep.uptime = formatUptime(rep.uptimeMillis);
+ rep.javaVersion = System.getProperty("java.version");
+ rep.javaVendor = System.getProperty("java.vendor");
+ rep.javaVm = System.getProperty("java.vm.name");
+ rep.javaVmVersion = System.getProperty("java.vm.version");
+ rep.javaRuntime = System.getProperty("java.runtime.name");
+ rep.javaHome = System.getProperty("java.home");
+ rep.osName = System.getProperty("os.name");
+ rep.osArchitecture = System.getProperty("os.arch");
+ rep.osVersion = System.getProperty("os.version");
+ rep.fileEncoding = System.getProperty("file.encoding");
+ rep.userName = System.getProperty("user.name");
+ rep.userDir = System.getProperty("user.dir");
+ rep.userTimezone = System.getProperty("user.timezone");
+ rep.userLocale = (new Locale(System.getProperty("user.country"), System.getProperty("user.language")).toString());
+ return rep;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getServerTime() {
+ return serverTime;
+ }
+
+ public void setServerTime(String serverTime) {
+ this.serverTime = serverTime;
+ }
+
+ public String getUptime() {
+ return uptime;
+ }
+
+ public void setUptime(String uptime) {
+ this.uptime = uptime;
+ }
+
+ public long getUptimeMillis() {
+ return uptimeMillis;
+ }
+
+ public void setUptimeMillis(long uptimeMillis) {
+ this.uptimeMillis = uptimeMillis;
+ }
+
+ public String getJavaVersion() {
+ return javaVersion;
+ }
+
+ public void setJavaVersion(String javaVersion) {
+ this.javaVersion = javaVersion;
+ }
+
+ public String getJavaVendor() {
+ return javaVendor;
+ }
+
+ public void setJavaVendor(String javaVendor) {
+ this.javaVendor = javaVendor;
+ }
+
+ public String getJavaVm() {
+ return javaVm;
+ }
+
+ public void setJavaVm(String javaVm) {
+ this.javaVm = javaVm;
+ }
+
+ public String getJavaVmVersion() {
+ return javaVmVersion;
+ }
+
+ public void setJavaVmVersion(String javaVmVersion) {
+ this.javaVmVersion = javaVmVersion;
+ }
+
+ public String getJavaRuntime() {
+ return javaRuntime;
+ }
+
+ public void setJavaRuntime(String javaRuntime) {
+ this.javaRuntime = javaRuntime;
+ }
+
+ public String getJavaHome() {
+ return javaHome;
+ }
+
+ public void setJavaHome(String javaHome) {
+ this.javaHome = javaHome;
+ }
+
+ public String getOsName() {
+ return osName;
+ }
+
+ public void setOsName(String osName) {
+ this.osName = osName;
+ }
+
+ public String getOsArchitecture() {
+ return osArchitecture;
+ }
+
+ public void setOsArchitecture(String osArchitecture) {
+ this.osArchitecture = osArchitecture;
+ }
+
+ public String getOsVersion() {
+ return osVersion;
+ }
+
+ public void setOsVersion(String osVersion) {
+ this.osVersion = osVersion;
+ }
+
+ public String getFileEncoding() {
+ return fileEncoding;
+ }
+
+ public void setFileEncoding(String fileEncoding) {
+ this.fileEncoding = fileEncoding;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getUserDir() {
+ return userDir;
+ }
+
+ public void setUserDir(String userDir) {
+ this.userDir = userDir;
+ }
+
+ public String getUserTimezone() {
+ return userTimezone;
+ }
+
+ public void setUserTimezone(String userTimezone) {
+ this.userTimezone = userTimezone;
+ }
+
+ public String getUserLocale() {
+ return userLocale;
+ }
+
+ public void setUserLocale(String userLocale) {
+ this.userLocale = userLocale;
+ }
+
+ private static String formatUptime(long uptime) {
+ long diffInSeconds = uptime / 1000;
+ long diff[] = new long[]{0, 0, 0, 0}; // sec
+ diff[3] = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds); // min
+ diff[2] = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds; // hours
+ diff[1] = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds; // days
+ diff[0] = (diffInSeconds = (diffInSeconds / 24));
+
+ return String.format(
+ "%d day%s, %d hour%s, %d minute%s, %d second%s",
+ diff[0],
+ diff[0] != 1 ? "s" : "",
+ diff[1],
+ diff[1] != 1 ? "s" : "",
+ diff[2],
+ diff[2] != 1 ? "s" : "",
+ diff[3],
+ diff[3] != 1 ? "s" : "");
+ }
+
+}