diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java b/core/src/main/java/org/keycloak/representations/info/MemoryInfoRepresentation.java
similarity index 59%
rename from services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java
rename to core/src/main/java/org/keycloak/representations/info/MemoryInfoRepresentation.java
index 56a1110d72..7490de167a 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/MemoryInfoRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/MemoryInfoRepresentation.java
@@ -1,15 +1,25 @@
-package org.keycloak.services.resources.admin.info;
+package org.keycloak.representations.info;
public class MemoryInfoRepresentation {
protected long total;
+ protected String totalFormated;
protected long used;
+ protected String usedFormated;
+ protected long free;
+ protected long freePercentage;
+ protected String freeFormated;
public static MemoryInfoRepresentation create() {
MemoryInfoRepresentation rep = new MemoryInfoRepresentation();
Runtime runtime = Runtime.getRuntime();
rep.total = runtime.maxMemory();
+ rep.totalFormated = formatMemory(rep.total);
rep.used = runtime.totalMemory() - runtime.freeMemory();
+ rep.usedFormated = formatMemory(rep.used);
+ rep.free = rep.total - rep.used;
+ rep.freeFormated = formatMemory(rep.free);
+ rep.freePercentage = rep.free * 100 / rep.total;
return rep;
}
@@ -18,15 +28,15 @@ public class MemoryInfoRepresentation {
}
public String getTotalFormated() {
- return formatMemory(getTotal());
+ return totalFormated;
}
public long getFree() {
- return getTotal() - getUsed();
+ return free;
}
public String getFreeFormated() {
- return formatMemory(getFree());
+ return freeFormated;
}
public long getUsed() {
@@ -34,14 +44,14 @@ public class MemoryInfoRepresentation {
}
public String getUsedFormated() {
- return formatMemory(getUsed());
+ return usedFormated;
}
public long getFreePercentage() {
- return getFree() * 100 / getTotal();
+ return freePercentage;
}
- private String formatMemory(long bytes) {
+ private static String formatMemory(long bytes) {
if (bytes > 1024L * 1024L) {
return bytes / (1024L * 1024L) + " MB";
} else if (bytes > 1024L) {
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java b/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
similarity index 86%
rename from services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java
rename to core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
index ffcaeb1651..e247ff1005 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/ProviderRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/ProviderRepresentation.java
@@ -1,4 +1,4 @@
-package org.keycloak.services.resources.admin.info;
+package org.keycloak.representations.info;
import java.util.Map;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java b/core/src/main/java/org/keycloak/representations/info/ServerInfoRepresentation.java
similarity index 98%
rename from services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java
rename to core/src/main/java/org/keycloak/representations/info/ServerInfoRepresentation.java
index 9b7f4f5bbb..01547901f1 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/ServerInfoRepresentation.java
@@ -1,4 +1,4 @@
-package org.keycloak.services.resources.admin.info;
+package org.keycloak.representations.info;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java b/core/src/main/java/org/keycloak/representations/info/SpiInfoRepresentation.java
similarity index 92%
rename from services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java
rename to core/src/main/java/org/keycloak/representations/info/SpiInfoRepresentation.java
index 1277f8c949..7daefb9daa 100644
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/SpiInfoRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/SpiInfoRepresentation.java
@@ -1,4 +1,4 @@
-package org.keycloak.services.resources.admin.info;
+package org.keycloak.representations.info;
import java.util.Map;
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java b/core/src/main/java/org/keycloak/representations/info/SystemInfoRepresentation.java
similarity index 95%
rename from services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java
rename to core/src/main/java/org/keycloak/representations/info/SystemInfoRepresentation.java
index 620e25eee0..97593864c3 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/SystemInfoRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/info/SystemInfoRepresentation.java
@@ -1,7 +1,6 @@
-package org.keycloak.services.resources.admin.info;
+package org.keycloak.representations.info;
import org.keycloak.common.Version;
-import org.keycloak.models.KeycloakSession;
import java.util.Date;
import java.util.Locale;
@@ -27,11 +26,11 @@ public class SystemInfoRepresentation {
private String userTimezone;
private String userLocale;
- public static SystemInfoRepresentation create(KeycloakSession session) {
+ public static SystemInfoRepresentation create(long serverStartupTime) {
SystemInfoRepresentation rep = new SystemInfoRepresentation();
rep.version = Version.VERSION;
rep.serverTime = new Date().toString();
- rep.uptimeMillis = System.currentTimeMillis() - session.getKeycloakSessionFactory().getServerStartupTimestamp();
+ rep.uptimeMillis = System.currentTimeMillis() - serverStartupTime;
rep.uptime = formatUptime(rep.uptimeMillis);
rep.javaVersion = System.getProperty("java.version");
rep.javaVendor = System.getProperty("java.vendor");
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
index b92f65bf1f..eca236fc13 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
+++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -63,9 +63,9 @@ supported-locales=Supported Locales
supported-locales.placeholder=Type a locale and enter
default-locale=Default Locale
realm-cache-enabled=Realm Cache Enabled
-realm-cache-enabled.tooltip=Enable/disable cache for realm, client and role data.
+realm-cache-enabled.tooltip=Enable/disable cache for realms, clients and roles.
user-cache-enabled=User Cache Enabled
-user-cache-enabled.tooltip=Enable/disable user and user role mapping cache.
+user-cache-enabled.tooltip=Enable/disable cache for users and user role mappings.
revoke-refresh-token=Revoke Refresh Token
revoke-refresh-token.tooltip=If enabled refresh tokens can only be used once. Otherwise refresh tokens are not revoked when used and can be used multiple times.
sso-session-idle=SSO Session Idle
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java
index 431a64664e..bc75fa9559 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/Keycloak.java
@@ -6,6 +6,7 @@ import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.keycloak.admin.client.resource.BearerAuthFilter;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RealmsResource;
+import org.keycloak.admin.client.resource.ServerInfoResource;
import org.keycloak.admin.client.token.TokenManager;
/**
@@ -51,6 +52,10 @@ public class Keycloak {
return realms().realm(realmName);
}
+ public ServerInfoResource serverInfo(){
+ return target.proxy(ServerInfoResource.class);
+ }
+
public TokenManager tokenManager(){
return tokenManager;
}
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ServerInfoResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ServerInfoResource.java
new file mode 100644
index 0000000000..6ebd642464
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ServerInfoResource.java
@@ -0,0 +1,20 @@
+package org.keycloak.admin.client.resource;
+
+import org.keycloak.representations.info.ServerInfoRepresentation;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * @author Stian Thorgersen
+ */
+@Path("/admin/serverinfo")
+public interface ServerInfoResource {
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ ServerInfoRepresentation getInfo();
+
+}
diff --git a/model/api/src/main/java/org/keycloak/models/OTPPolicy.java b/model/api/src/main/java/org/keycloak/models/OTPPolicy.java
index 1c6665aead..157842e94e 100755
--- a/model/api/src/main/java/org/keycloak/models/OTPPolicy.java
+++ b/model/api/src/main/java/org/keycloak/models/OTPPolicy.java
@@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
import org.keycloak.models.utils.Base32;
import org.keycloak.models.utils.HmacOTP;
+import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
@@ -13,7 +14,7 @@ import java.util.Map;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public class OTPPolicy {
+public class OTPPolicy implements Serializable {
protected static final Logger logger = Logger.getLogger(OTPPolicy.class);
diff --git a/model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java b/model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java
index e1c356b030..0ecf8787e7 100755
--- a/model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RequiredActionProviderModel.java
@@ -1,5 +1,6 @@
package org.keycloak.models;
+import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
@@ -7,7 +8,7 @@ import java.util.Map;
* @author Bill Burke
* @version $Revision: 1 $
*/
-public class RequiredActionProviderModel {
+public class RequiredActionProviderModel implements Serializable {
private String id;
private String alias;
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
index 20c87251a1..2f7e61f0f3 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java
@@ -29,7 +29,7 @@ public class ClientAdapter implements ClientModel {
private void getDelegateForUpdate() {
if (updated == null) {
cacheSession.registerApplicationInvalidation(getId());
- updated = updated = cacheSession.getDelegate().getClientById(getId(), cachedRealm);
+ updated = cacheSession.getDelegate().getClientById(getId(), cachedRealm);
if (updated == null) throw new IllegalStateException("Not found in database");
}
}
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
index 4b96241fbe..5a76153793 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheRealmProviderFactory.java
@@ -1,6 +1,16 @@
package org.keycloak.models.cache.infinispan;
import org.infinispan.Cache;
+import org.infinispan.notifications.Listener;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntriesEvicted;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryCreated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryInvalidated;
+import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved;
+import org.infinispan.notifications.cachelistener.event.CacheEntriesEvictedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryCreatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryInvalidatedEvent;
+import org.infinispan.notifications.cachelistener.event.CacheEntryRemovedEvent;
+import org.jboss.logging.Logger;
import org.keycloak.Config;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
@@ -8,6 +18,8 @@ import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.cache.CacheRealmProvider;
import org.keycloak.models.cache.CacheRealmProviderFactory;
import org.keycloak.models.cache.RealmCache;
+import org.keycloak.models.cache.entities.CachedRealm;
+import org.keycloak.models.cache.entities.CachedUser;
import java.util.concurrent.ConcurrentHashMap;
@@ -17,15 +29,43 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFactory {
- protected final ConcurrentHashMap realmLookup = new ConcurrentHashMap();
+ private static final Logger log = Logger.getLogger(InfinispanCacheRealmProviderFactory.class);
+
+ protected volatile InfinispanRealmCache realmCache;
+
+ protected final ConcurrentHashMap realmLookup = new ConcurrentHashMap<>();
+
+ private boolean isNewInfinispan;
@Override
public CacheRealmProvider create(KeycloakSession session) {
- Cache cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
- RealmCache realmCache = new InfinispanRealmCache(cache, realmLookup);
+ lazyInit(session);
return new DefaultCacheRealmProvider(realmCache, session);
}
+ private void lazyInit(KeycloakSession session) {
+ if (realmCache == null) {
+ synchronized (this) {
+ if (realmCache == null) {
+ checkIspnVersion();
+
+ Cache cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
+ cache.addListener(new CacheListener());
+ realmCache = new InfinispanRealmCache(cache, realmLookup);
+ }
+ }
+ }
+ }
+
+ protected void checkIspnVersion() {
+ try {
+ CacheEntryCreatedEvent.class.getMethod("getValue");
+ isNewInfinispan = true;
+ } catch (NoSuchMethodException nsme) {
+ isNewInfinispan = false;
+ }
+ }
+
@Override
public void init(Config.Scope config) {
}
@@ -44,4 +84,71 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
return "infinispan";
}
+ @Listener
+ public class CacheListener {
+
+ @CacheEntryCreated
+ public void created(CacheEntryCreatedEvent event) {
+ if (!event.isPre()) {
+ Object object;
+
+ // Try optimized version if available
+ if (isNewInfinispan) {
+ object = event.getValue();
+ } else {
+ String id = event.getKey();
+ object = event.getCache().get(id);
+ }
+
+ if (object != null) {
+ if (object instanceof CachedRealm) {
+ CachedRealm realm = (CachedRealm) object;
+ realmLookup.put(realm.getName(), realm.getId());
+ log.tracev("Realm added realm={0}", realm.getName());
+ }
+ }
+ }
+ }
+
+ @CacheEntryRemoved
+ public void removed(CacheEntryRemovedEvent event) {
+ if (event.isPre()) {
+ Object object = event.getValue();
+ if (object != null) {
+ remove(object);
+ }
+ }
+ }
+
+ @CacheEntryInvalidated
+ public void removed(CacheEntryInvalidatedEvent event) {
+ if (event.isPre()) {
+ Object object = event.getValue();
+ if (object != null) {
+ remove(object);
+ }
+ }
+ }
+
+ @CacheEntriesEvicted
+ public void userEvicted(CacheEntriesEvictedEvent event) {
+ for (Object object : event.getEntries().values()) {
+ remove(object);
+ }
+ }
+
+ private void remove(Object object) {
+ if (object instanceof CachedRealm) {
+ CachedRealm realm = (CachedRealm) object;
+
+ realmLookup.remove(realm.getName());
+
+ for (String c : realm.getClients().values()) {
+ realmCache.evictCachedApplicationById(c);
+ }
+
+ log.tracev("Realm removed realm={0}", realm.getName());
+ }
+ }
+ }
}
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
index 4eb0bdf8ee..ec699127c4 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanCacheUserProviderFactory.java
@@ -26,7 +26,7 @@ public class InfinispanCacheUserProviderFactory implements CacheUserProviderFact
private static final Logger log = Logger.getLogger(InfinispanCacheUserProviderFactory.class);
- protected InfinispanUserCache userCache;
+ protected volatile InfinispanUserCache userCache;
protected final RealmLookup usernameLookup = new RealmLookup();
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
index a5239fbcf5..81558012b4 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanRealmCache.java
@@ -38,9 +38,10 @@ public class InfinispanRealmCache implements RealmCache {
@Override
public void setEnabled(boolean enabled) {
- clear();
+ if (this.enabled && !enabled) {
+ clear();
+ }
this.enabled = enabled;
- clear();
}
@Override
@@ -66,7 +67,7 @@ public class InfinispanRealmCache implements RealmCache {
public void addCachedRealm(CachedRealm realm) {
if (!enabled) return;
logger.tracev("Adding realm {0}", realm.getId());
- cache.put(realm.getId(), realm);
+ cache.putForExternalRead(realm.getId(), realm);
realmLookup.put(realm.getName(), realm.getId());
}
@@ -93,7 +94,7 @@ public class InfinispanRealmCache implements RealmCache {
public void addCachedClient(CachedClient app) {
if (!enabled) return;
logger.tracev("Adding application {0}", app.getId());
- cache.put(app.getId(), app);
+ cache.putForExternalRead(app.getId(), app);
}
@Override
@@ -102,6 +103,12 @@ public class InfinispanRealmCache implements RealmCache {
cache.remove(id);
}
+ @Override
+ public void evictCachedApplicationById(String id) {
+ logger.tracev("Evicting application {0}", id);
+ cache.evict(id);
+ }
+
@Override
public CachedGroup getGroup(String id) {
if (!enabled) return null;
@@ -112,15 +119,13 @@ public class InfinispanRealmCache implements RealmCache {
public void invalidateGroup(CachedGroup role) {
logger.tracev("Removing group {0}", role.getId());
cache.remove(role.getId());
-
}
@Override
public void addCachedGroup(CachedGroup role) {
if (!enabled) return;
logger.tracev("Adding group {0}", role.getId());
- cache.put(role.getId(), role);
-
+ cache.putForExternalRead(role.getId(), role);
}
@Override
@@ -134,7 +139,6 @@ public class InfinispanRealmCache implements RealmCache {
public void invalidateGroupById(String id) {
logger.tracev("Removing group {0}", id);
cache.remove(id);
-
}
@Override
@@ -143,8 +147,6 @@ public class InfinispanRealmCache implements RealmCache {
return get(id, CachedRole.class);
}
-
-
@Override
public void invalidateRole(CachedRole role) {
logger.tracev("Removing role {0}", role.getId());
@@ -161,7 +163,7 @@ public class InfinispanRealmCache implements RealmCache {
public void addCachedRole(CachedRole role) {
if (!enabled) return;
logger.tracev("Adding role {0}", role.getId());
- cache.put(role.getId(), role);
+ cache.putForExternalRead(role.getId(), role);
}
@Override
diff --git a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCache.java b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCache.java
index fbb36c54d4..c5e960c0e1 100755
--- a/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCache.java
+++ b/model/invalidation-cache/infinispan/src/main/java/org/keycloak/models/cache/infinispan/InfinispanUserCache.java
@@ -35,9 +35,10 @@ public class InfinispanUserCache implements UserCache {
@Override
public void setEnabled(boolean enabled) {
- clear();
+ if (this.enabled && !enabled) {
+ clear();
+ }
this.enabled = enabled;
- clear();
}
@Override
@@ -62,7 +63,7 @@ public class InfinispanUserCache implements UserCache {
@Override
public void addCachedUser(String realmId, CachedUser user) {
logger.tracev("Adding user {0}", user.getId());
- cache.put(user.getId(), user);
+ cache.putForExternalRead(user.getId(), user);
}
@Override
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
index df74b536af..007daac779 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmCache.java
@@ -26,6 +26,8 @@ public interface RealmCache {
void invalidateApplication(CachedClient app);
+ void evictCachedApplicationById(String id);
+
void addCachedClient(CachedClient app);
void invalidateCachedApplicationById(String id);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java
index 660b1c4396..672745cb66 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/info/ServerInfoAdminResource.java
@@ -31,6 +31,7 @@ import org.keycloak.provider.Spi;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
+import org.keycloak.representations.info.*;
import org.keycloak.social.SocialIdentityProvider;
/**
@@ -51,7 +52,7 @@ public class ServerInfoAdminResource {
@GET
public ServerInfoRepresentation getInfo() {
ServerInfoRepresentation info = new ServerInfoRepresentation();
- info.setSystemInfo(SystemInfoRepresentation.create(session));
+ info.setSystemInfo(SystemInfoRepresentation.create(session.getKeycloakSessionFactory().getServerStartupTimestamp()));
info.setMemoryInfo(MemoryInfoRepresentation.create());
setSocialProviders(info);
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
deleted file mode 100755
index e0471df8de..0000000000
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/AdminAPITest.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2012, Red Hat, Inc., and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.keycloak.testsuite.admin;
-
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.keycloak.Config;
-import org.keycloak.common.Version;
-import org.keycloak.models.ClientModel;
-import org.keycloak.models.ClientSessionModel;
-import org.keycloak.models.Constants;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.models.UserModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.protocol.oidc.OIDCLoginProtocol;
-import org.keycloak.protocol.oidc.TokenManager;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.CredentialRepresentation;
-import org.keycloak.representations.idm.RealmRepresentation;
-import org.keycloak.services.managers.RealmManager;
-import org.keycloak.services.resources.admin.AdminRoot;
-import org.keycloak.testsuite.rule.AbstractKeycloakRule;
-import org.keycloak.testsuite.KeycloakServer;
-
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.ClientRequestContext;
-import javax.ws.rs.client.ClientRequestFilter;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Tests Undertow Adapter
- *
- * @author Bill Burke
- */
-public class AdminAPITest {
-
- @ClassRule
- public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule() {
- @Override
- protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
- }
- };
-
- private static String createToken() {
- KeycloakSession session = keycloakRule.startSession();
- try {
- RealmManager manager = new RealmManager(session);
-
- RealmModel adminRealm = manager.getRealm(Config.getAdminRealm());
- ClientModel adminConsole = adminRealm.getClientByClientId(Constants.ADMIN_CLI_CLIENT_ID);
- TokenManager tm = new TokenManager();
- UserModel admin = session.users().getUserByUsername("admin", adminRealm);
- ClientSessionModel clientSession = session.sessions().createClientSession(adminRealm, adminConsole);
- clientSession.setNote(OIDCLoginProtocol.ISSUER, "http://localhost:8081/auth/realms/master");
- UserSessionModel userSession = session.sessions().createUserSession(adminRealm, admin, "admin", null, "form", false, null, null);
- AccessToken token = tm.createClientAccessToken(session, tm.getAccess(null, true, adminConsole, admin), adminRealm, adminConsole, admin, userSession, clientSession);
- return tm.encodeToken(adminRealm, token);
- } finally {
- keycloakRule.stopSession(session, true);
- }
- }
-
- protected void testCreateRealm(RealmRepresentation rep) {
- String token = createToken();
- final String authHeader = "Bearer " + token;
- ClientRequestFilter authFilter = new ClientRequestFilter() {
- @Override
- public void filter(ClientRequestContext requestContext) throws IOException {
- requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
- }
- };
- Client client = ClientBuilder.newBuilder().register(authFilter).build();
- UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
- WebTarget adminRealms = client.target(AdminRoot.realmsUrl(authBase));
- String realmName = rep.getRealm();
- WebTarget realmTarget = adminRealms.path(realmName);
-
-
- // create with just name, enabled, and id, just like admin console
- RealmRepresentation newRep = new RealmRepresentation();
- newRep.setRealm(rep.getRealm());
- newRep.setEnabled(rep.isEnabled());
- {
- Response response = adminRealms.request().post(Entity.json(newRep));
- Assert.assertEquals(201, response.getStatus());
- response.close();
- }
- // todo test with full import with initial create
- RealmRepresentation storedRealm = realmTarget.request().get(RealmRepresentation.class);
- checkRealmRep(newRep, storedRealm);
-
- Response updateResponse = realmTarget.request().put(Entity.json(rep));
- Assert.assertEquals(204, updateResponse.getStatus());
- updateResponse.close();
- storedRealm = realmTarget.request().get(RealmRepresentation.class);
- checkRealmRep(rep, storedRealm);
-
- if (rep.getClients() != null) {
- WebTarget applicationsTarget = realmTarget.path("applications");
- for (ClientRepresentation appRep : rep.getClients()) {
- ClientRepresentation newApp = new ClientRepresentation();
- if (appRep.getId() != null) newApp.setId(appRep.getId());
- newApp.setClientId(appRep.getClientId());
- if (appRep.getClientAuthenticatorType() != null) {
- newApp.setClientAuthenticatorType(appRep.getClientAuthenticatorType());
- }
- if (appRep.getSecret() != null) {
- newApp.setSecret(appRep.getSecret());
- }
- Response appCreateResponse = applicationsTarget.request().post(Entity.json(newApp));
- Assert.assertEquals(201, appCreateResponse.getStatus());
- appCreateResponse.close();
- WebTarget appTarget = applicationsTarget.path(appRep.getClientId());
- CredentialRepresentation cred = appTarget.path("client-secret").request().get(CredentialRepresentation.class);
- if (appRep.getSecret() != null) Assert.assertEquals(appRep.getSecret(), cred.getValue());
- CredentialRepresentation newCred = appTarget.path("client-secret").request().post(null, CredentialRepresentation.class);
- Assert.assertNotEquals(newCred.getValue(), cred.getValue());
-
- Response appUpdateResponse = appTarget.request().put(Entity.json(appRep));
- Assert.assertEquals(204, appUpdateResponse.getStatus());
- appUpdateResponse.close();
-
-
- ClientRepresentation storedApp = appTarget.request().get(ClientRepresentation.class);
-
- checkAppUpdate(appRep, storedApp);
-
- }
- }
-
- // delete realm
- {
- Response response = adminRealms.path(realmName).request().delete();
- Assert.assertEquals(204, response.getStatus());
- response.close();
-
- }
- client.close();
- }
-
- protected void checkAppUpdate(ClientRepresentation appRep, ClientRepresentation storedApp) {
- if (appRep.getClientId() != null) Assert.assertEquals(appRep.getClientId(), storedApp.getClientId());
- if (appRep.getName() != null) Assert.assertEquals(appRep.getName(), storedApp.getName());
- if (appRep.isEnabled() != null) Assert.assertEquals(appRep.isEnabled(), storedApp.isEnabled());
- if (appRep.isBearerOnly() != null) Assert.assertEquals(appRep.isBearerOnly(), storedApp.isBearerOnly());
- if (appRep.isPublicClient() != null) Assert.assertEquals(appRep.isPublicClient(), storedApp.isPublicClient());
- if (appRep.isFullScopeAllowed() != null) Assert.assertEquals(appRep.isFullScopeAllowed(), storedApp.isFullScopeAllowed());
- if (appRep.getRootUrl() != null) Assert.assertEquals(appRep.getRootUrl(), storedApp.getRootUrl());
- if (appRep.getAdminUrl() != null) Assert.assertEquals(appRep.getAdminUrl(), storedApp.getAdminUrl());
- if (appRep.getBaseUrl() != null) Assert.assertEquals(appRep.getBaseUrl(), storedApp.getBaseUrl());
- if (appRep.isSurrogateAuthRequired() != null) Assert.assertEquals(appRep.isSurrogateAuthRequired(), storedApp.isSurrogateAuthRequired());
- if (appRep.getClientAuthenticatorType() != null) Assert.assertEquals(appRep.getClientAuthenticatorType(), storedApp.getClientAuthenticatorType());
-
- if (appRep.getNotBefore() != null) {
- Assert.assertEquals(appRep.getNotBefore(), storedApp.getNotBefore());
- }
- if (appRep.getDefaultRoles() != null) {
- Set set = new HashSet();
- for (String val : appRep.getDefaultRoles()) {
- set.add(val);
- }
- Set storedSet = new HashSet();
- for (String val : storedApp.getDefaultRoles()) {
- storedSet.add(val);
- }
-
- Assert.assertEquals(set, storedSet);
- }
-
- List redirectUris = appRep.getRedirectUris();
- if (redirectUris != null) {
- Set set = new HashSet();
- for (String val : appRep.getRedirectUris()) {
- set.add(val);
- }
- Set storedSet = new HashSet();
- for (String val : storedApp.getRedirectUris()) {
- storedSet.add(val);
- }
-
- Assert.assertEquals(set, storedSet);
- }
-
- List webOrigins = appRep.getWebOrigins();
- if (webOrigins != null) {
- Set set = new HashSet();
- for (String val : appRep.getWebOrigins()) {
- set.add(val);
- }
- Set storedSet = new HashSet();
- for (String val : storedApp.getWebOrigins()) {
- storedSet.add(val);
- }
-
- Assert.assertEquals(set, storedSet);
- }
- }
-
- protected void checkRealmRep(RealmRepresentation rep, RealmRepresentation storedRealm) {
- if (rep.getId() != null) {
- Assert.assertEquals(rep.getId(), storedRealm.getId());
- }
- if (rep.getRealm() != null) {
- Assert.assertEquals(rep.getRealm(), storedRealm.getRealm());
- }
- if (rep.isEnabled() != null) Assert.assertEquals(rep.isEnabled(), storedRealm.isEnabled());
- if (rep.isBruteForceProtected() != null) Assert.assertEquals(rep.isBruteForceProtected(), storedRealm.isBruteForceProtected());
- if (rep.getMaxFailureWaitSeconds() != null) Assert.assertEquals(rep.getMaxFailureWaitSeconds(), storedRealm.getMaxFailureWaitSeconds());
- if (rep.getMinimumQuickLoginWaitSeconds() != null) Assert.assertEquals(rep.getMinimumQuickLoginWaitSeconds(), storedRealm.getMinimumQuickLoginWaitSeconds());
- if (rep.getWaitIncrementSeconds() != null) Assert.assertEquals(rep.getWaitIncrementSeconds(), storedRealm.getWaitIncrementSeconds());
- if (rep.getQuickLoginCheckMilliSeconds() != null) Assert.assertEquals(rep.getQuickLoginCheckMilliSeconds(), storedRealm.getQuickLoginCheckMilliSeconds());
- if (rep.getMaxDeltaTimeSeconds() != null) Assert.assertEquals(rep.getMaxDeltaTimeSeconds(), storedRealm.getMaxDeltaTimeSeconds());
- if (rep.getFailureFactor() != null) Assert.assertEquals(rep.getFailureFactor(), storedRealm.getFailureFactor());
- if (rep.isRegistrationAllowed() != null) Assert.assertEquals(rep.isRegistrationAllowed(), storedRealm.isRegistrationAllowed());
- if (rep.isRegistrationEmailAsUsername() != null) Assert.assertEquals(rep.isRegistrationEmailAsUsername(), storedRealm.isRegistrationEmailAsUsername());
- if (rep.isRememberMe() != null) Assert.assertEquals(rep.isRememberMe(), storedRealm.isRememberMe());
- if (rep.isVerifyEmail() != null) Assert.assertEquals(rep.isVerifyEmail(), storedRealm.isVerifyEmail());
- if (rep.isResetPasswordAllowed() != null) Assert.assertEquals(rep.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
- if (rep.isEditUsernameAllowed() != null) Assert.assertEquals(rep.isEditUsernameAllowed(), storedRealm.isEditUsernameAllowed());
- if (rep.getSslRequired() != null) Assert.assertEquals(rep.getSslRequired(), storedRealm.getSslRequired());
- if (rep.getAccessCodeLifespan() != null) Assert.assertEquals(rep.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
- if (rep.getAccessCodeLifespanUserAction() != null)
- Assert.assertEquals(rep.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());
- if (rep.getNotBefore() != null) Assert.assertEquals(rep.getNotBefore(), storedRealm.getNotBefore());
- if (rep.getAccessTokenLifespan() != null) Assert.assertEquals(rep.getAccessTokenLifespan(), storedRealm.getAccessTokenLifespan());
- if (rep.getAccessTokenLifespanForImplicitFlow() != null) Assert.assertEquals(rep.getAccessTokenLifespanForImplicitFlow(), storedRealm.getAccessTokenLifespanForImplicitFlow());
- if (rep.getSsoSessionIdleTimeout() != null) Assert.assertEquals(rep.getSsoSessionIdleTimeout(), storedRealm.getSsoSessionIdleTimeout());
- if (rep.getSsoSessionMaxLifespan() != null) Assert.assertEquals(rep.getSsoSessionMaxLifespan(), storedRealm.getSsoSessionMaxLifespan());
- if (rep.getRequiredCredentials() != null) {
- Assert.assertNotNull(storedRealm.getRequiredCredentials());
- for (String cred : rep.getRequiredCredentials()) {
- Assert.assertTrue(storedRealm.getRequiredCredentials().contains(cred));
- }
- }
- if (rep.getLoginTheme() != null) Assert.assertEquals(rep.getLoginTheme(), storedRealm.getLoginTheme());
- if (rep.getAccountTheme() != null) Assert.assertEquals(rep.getAccountTheme(), storedRealm.getAccountTheme());
- if (rep.getAdminTheme() != null) Assert.assertEquals(rep.getAdminTheme(), storedRealm.getAdminTheme());
- if (rep.getEmailTheme() != null) Assert.assertEquals(rep.getEmailTheme(), storedRealm.getEmailTheme());
-
- if (rep.getPasswordPolicy() != null) Assert.assertEquals(rep.getPasswordPolicy(), storedRealm.getPasswordPolicy());
-
- if (rep.getDefaultRoles() != null) {
- Assert.assertNotNull(storedRealm.getDefaultRoles());
- for (String role : rep.getDefaultRoles()) {
- Assert.assertTrue(storedRealm.getDefaultRoles().contains(role));
- }
- }
-
- if (rep.getSmtpServer() != null) {
- Assert.assertEquals(rep.getSmtpServer(), storedRealm.getSmtpServer());
- }
-
- if (rep.getBrowserSecurityHeaders() != null) {
- Assert.assertEquals(rep.getBrowserSecurityHeaders(), storedRealm.getBrowserSecurityHeaders());
- }
-
- }
-
- protected void testCreateRealm(String path) {
- RealmRepresentation rep = KeycloakServer.loadJson(getClass().getResourceAsStream(path), RealmRepresentation.class);
- Assert.assertNotNull(rep);
- testCreateRealm(rep);
- }
-
- @Test
- public void testAdminApi() {
- RealmRepresentation empty = new RealmRepresentation();
- empty.setEnabled(true);
- empty.setRealm("empty");
- testCreateRealm(empty);
- testCreateRealm("/admin-test/testrealm.json");
- }
-
- @Test
- public void testServerInfo() {
- String token = createToken();
- final String authHeader = "Bearer " + token;
- ClientRequestFilter authFilter = new ClientRequestFilter() {
- @Override
- public void filter(ClientRequestContext requestContext) throws IOException {
- requestContext.getHeaders().add(HttpHeaders.AUTHORIZATION, authHeader);
- }
- };
- Client client = ClientBuilder.newBuilder().register(authFilter).build();
- UriBuilder authBase = UriBuilder.fromUri("http://localhost:8081/auth");
- WebTarget target = client.target(AdminRoot.adminBaseUrl(authBase).path("serverinfo"));
-
- Map, ?> response = target.request().accept("application/json").get(Map.class);
-
-
- System.out.println(response.keySet().toString());
-
- Assert.assertNotNull(response);
- Assert.assertNotNull(response.get("providers"));
- Assert.assertNotNull(response.get("themes"));
- Assert.assertNotNull(response.get("enums"));
-
- Assert.assertNotNull(response.get("memoryInfo"));
- Assert.assertNotNull(response.get("systemInfo"));
-
- Map, ?> systemInfo = (Map, ?>) response.get("systemInfo");
- Assert.assertEquals(Version.VERSION, systemInfo.get("version"));
- Assert.assertNotNull(systemInfo.get("serverTime"));
- Assert.assertNotNull(systemInfo.get("uptime"));
- }
-
-}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
index dd575b1d64..31f88bcf71 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ClientTest.java
@@ -1,24 +1,26 @@
package org.keycloak.testsuite.admin;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.models.Constants;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
-import org.keycloak.representations.idm.ClientRepresentation;
-import org.keycloak.representations.idm.ProtocolMapperRepresentation;
-import org.keycloak.representations.idm.RoleRepresentation;
-import org.keycloak.representations.idm.UserSessionRepresentation;
+import org.keycloak.representations.idm.*;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.NotFoundException;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -46,19 +48,21 @@ public class ClientTest extends AbstractClientTest {
assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "broker", Constants.ADMIN_CLI_CLIENT_ID);
}
- private String createClient() {
+ private ClientRepresentation createClient() {
ClientRepresentation rep = new ClientRepresentation();
rep.setClientId("my-app");
rep.setDescription("my-app description");
rep.setEnabled(true);
Response response = realm.clients().create(rep);
response.close();
- return ApiUtil.getCreatedId(response);
+ String id = ApiUtil.getCreatedId(response);
+ rep.setId(id);
+ return rep;
}
@Test
public void createClientVerify() {
- String id = createClient();
+ String id = createClient().getId();
assertNotNull(realm.clients().get(id));
assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "broker", "my-app", Constants.ADMIN_CLI_CLIENT_ID);
@@ -66,14 +70,14 @@ public class ClientTest extends AbstractClientTest {
@Test
public void removeClient() {
- String id = createClient();
+ String id = createClient().getId();
realm.clients().get(id).remove();
}
@Test
public void getClientRepresentation() {
- String id = createClient();
+ String id = createClient().getId();
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
assertEquals(id, rep.getId());
@@ -86,8 +90,7 @@ public class ClientTest extends AbstractClientTest {
*/
@Test
public void getClientDescription() {
-
- String id = createClient();
+ String id = createClient().getId();
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
assertEquals(id, rep.getId());
@@ -145,6 +148,28 @@ public class ClientTest extends AbstractClientTest {
protocolMappersTest(mappersResource);
}
+ @Test
+ public void updateClient() {
+ ClientRepresentation client = createClient();
+
+ ClientRepresentation newClient = new ClientRepresentation();
+ newClient.setId(client.getId());
+ newClient.setClientId(client.getClientId());
+ newClient.setBaseUrl("http://baseurl");
+
+ realm.clients().get(client.getId()).update(newClient);
+
+ ClientRepresentation storedClient = realm.clients().get(client.getId()).toRepresentation();
+
+ assertClient(client, storedClient);
+
+ newClient.setSecret("new-secret");
+
+ realm.clients().get(client.getId()).update(newClient);
+
+ storedClient = realm.clients().get(client.getId()).toRepresentation();
+ assertClient(client, storedClient);
+ }
public static void protocolMappersTest(ProtocolMappersResource mappersResource) {
// assert default mappers found
@@ -197,4 +222,62 @@ public class ClientTest extends AbstractClientTest {
}
}
+ public static void assertClient(ClientRepresentation client, ClientRepresentation storedClient) {
+ if (client.getClientId() != null) Assert.assertEquals(client.getClientId(), storedClient.getClientId());
+ if (client.getName() != null) Assert.assertEquals(client.getName(), storedClient.getName());
+ if (client.isEnabled() != null) Assert.assertEquals(client.isEnabled(), storedClient.isEnabled());
+ if (client.isBearerOnly() != null) Assert.assertEquals(client.isBearerOnly(), storedClient.isBearerOnly());
+ if (client.isPublicClient() != null) Assert.assertEquals(client.isPublicClient(), storedClient.isPublicClient());
+ if (client.isFullScopeAllowed() != null) Assert.assertEquals(client.isFullScopeAllowed(), storedClient.isFullScopeAllowed());
+ if (client.getRootUrl() != null) Assert.assertEquals(client.getRootUrl(), storedClient.getRootUrl());
+ if (client.getAdminUrl() != null) Assert.assertEquals(client.getAdminUrl(), storedClient.getAdminUrl());
+ if (client.getBaseUrl() != null) Assert.assertEquals(client.getBaseUrl(), storedClient.getBaseUrl());
+ if (client.isSurrogateAuthRequired() != null) Assert.assertEquals(client.isSurrogateAuthRequired(), storedClient.isSurrogateAuthRequired());
+ if (client.getClientAuthenticatorType() != null) Assert.assertEquals(client.getClientAuthenticatorType(), storedClient.getClientAuthenticatorType());
+
+ if (client.getNotBefore() != null) {
+ Assert.assertEquals(client.getNotBefore(), storedClient.getNotBefore());
+ }
+ if (client.getDefaultRoles() != null) {
+ Set set = new HashSet();
+ for (String val : client.getDefaultRoles()) {
+ set.add(val);
+ }
+ Set storedSet = new HashSet();
+ for (String val : storedClient.getDefaultRoles()) {
+ storedSet.add(val);
+ }
+
+ Assert.assertEquals(set, storedSet);
+ }
+
+ List redirectUris = client.getRedirectUris();
+ if (redirectUris != null) {
+ Set set = new HashSet();
+ for (String val : client.getRedirectUris()) {
+ set.add(val);
+ }
+ Set storedSet = new HashSet();
+ for (String val : storedClient.getRedirectUris()) {
+ storedSet.add(val);
+ }
+
+ Assert.assertEquals(set, storedSet);
+ }
+
+ List webOrigins = client.getWebOrigins();
+ if (webOrigins != null) {
+ Set set = new HashSet();
+ for (String val : client.getWebOrigins()) {
+ set.add(val);
+ }
+ Set storedSet = new HashSet();
+ for (String val : storedClient.getWebOrigins()) {
+ storedSet.add(val);
+ }
+
+ Assert.assertEquals(set, storedSet);
+ }
+ }
+
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/RealmTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/RealmTest.java
index 42870a6642..604dcffca4 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/RealmTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/RealmTest.java
@@ -1,6 +1,7 @@
package org.keycloak.testsuite.admin;
import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
import org.junit.Test;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
@@ -8,6 +9,7 @@ import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.services.managers.RealmManager;
+import org.keycloak.testsuite.KeycloakServer;
import org.keycloak.util.JsonSerialization;
import javax.ws.rs.NotFoundException;
@@ -43,7 +45,7 @@ public class RealmTest extends AbstractClientTest {
}
@Test
- public void createRealm() {
+ public void createRealmEmpty() {
try {
RealmRepresentation rep = new RealmRepresentation();
rep.setRealm("new-realm");
@@ -62,6 +64,25 @@ public class RealmTest extends AbstractClientTest {
}
}
+ @Test
+ public void createRealm() {
+ try {
+ RealmRepresentation rep = KeycloakServer.loadJson(getClass().getResourceAsStream("/admin-test/testrealm.json"), RealmRepresentation.class);
+ keycloak.realms().create(rep);
+
+ RealmRepresentation created = keycloak.realms().realm("admin-test-1").toRepresentation();
+ assertRealm(rep, created);
+ } finally {
+ KeycloakSession session = keycloakRule.startSession();
+ RealmManager manager = new RealmManager(session);
+ RealmModel newRealm = manager.getRealmByName("admin-test-1");
+ if (newRealm != null) {
+ manager.removeRealm(newRealm);
+ }
+ keycloakRule.stopSession(session, true);
+ }
+ }
+
@Test
public void removeRealm() {
realm.remove();
@@ -194,4 +215,64 @@ public class RealmTest extends AbstractClientTest {
assertEquals("https://LoadBalancer-9.siroe.com:3443/federation/Consumer/metaAlias/sp", converted.getRedirectUris().get(0));
}
+ public static void assertRealm(RealmRepresentation realm, RealmRepresentation storedRealm) {
+ if (realm.getId() != null) {
+ Assert.assertEquals(realm.getId(), storedRealm.getId());
+ }
+ if (realm.getRealm() != null) {
+ Assert.assertEquals(realm.getRealm(), storedRealm.getRealm());
+ }
+ if (realm.isEnabled() != null) Assert.assertEquals(realm.isEnabled(), storedRealm.isEnabled());
+ if (realm.isBruteForceProtected() != null) Assert.assertEquals(realm.isBruteForceProtected(), storedRealm.isBruteForceProtected());
+ if (realm.getMaxFailureWaitSeconds() != null) Assert.assertEquals(realm.getMaxFailureWaitSeconds(), storedRealm.getMaxFailureWaitSeconds());
+ if (realm.getMinimumQuickLoginWaitSeconds() != null) Assert.assertEquals(realm.getMinimumQuickLoginWaitSeconds(), storedRealm.getMinimumQuickLoginWaitSeconds());
+ if (realm.getWaitIncrementSeconds() != null) Assert.assertEquals(realm.getWaitIncrementSeconds(), storedRealm.getWaitIncrementSeconds());
+ if (realm.getQuickLoginCheckMilliSeconds() != null) Assert.assertEquals(realm.getQuickLoginCheckMilliSeconds(), storedRealm.getQuickLoginCheckMilliSeconds());
+ if (realm.getMaxDeltaTimeSeconds() != null) Assert.assertEquals(realm.getMaxDeltaTimeSeconds(), storedRealm.getMaxDeltaTimeSeconds());
+ if (realm.getFailureFactor() != null) Assert.assertEquals(realm.getFailureFactor(), storedRealm.getFailureFactor());
+ if (realm.isRegistrationAllowed() != null) Assert.assertEquals(realm.isRegistrationAllowed(), storedRealm.isRegistrationAllowed());
+ if (realm.isRegistrationEmailAsUsername() != null) Assert.assertEquals(realm.isRegistrationEmailAsUsername(), storedRealm.isRegistrationEmailAsUsername());
+ if (realm.isRememberMe() != null) Assert.assertEquals(realm.isRememberMe(), storedRealm.isRememberMe());
+ if (realm.isVerifyEmail() != null) Assert.assertEquals(realm.isVerifyEmail(), storedRealm.isVerifyEmail());
+ if (realm.isResetPasswordAllowed() != null) Assert.assertEquals(realm.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
+ if (realm.isEditUsernameAllowed() != null) Assert.assertEquals(realm.isEditUsernameAllowed(), storedRealm.isEditUsernameAllowed());
+ if (realm.getSslRequired() != null) Assert.assertEquals(realm.getSslRequired(), storedRealm.getSslRequired());
+ if (realm.getAccessCodeLifespan() != null) Assert.assertEquals(realm.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
+ if (realm.getAccessCodeLifespanUserAction() != null)
+ Assert.assertEquals(realm.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());
+ if (realm.getNotBefore() != null) Assert.assertEquals(realm.getNotBefore(), storedRealm.getNotBefore());
+ if (realm.getAccessTokenLifespan() != null) Assert.assertEquals(realm.getAccessTokenLifespan(), storedRealm.getAccessTokenLifespan());
+ if (realm.getAccessTokenLifespanForImplicitFlow() != null) Assert.assertEquals(realm.getAccessTokenLifespanForImplicitFlow(), storedRealm.getAccessTokenLifespanForImplicitFlow());
+ if (realm.getSsoSessionIdleTimeout() != null) Assert.assertEquals(realm.getSsoSessionIdleTimeout(), storedRealm.getSsoSessionIdleTimeout());
+ if (realm.getSsoSessionMaxLifespan() != null) Assert.assertEquals(realm.getSsoSessionMaxLifespan(), storedRealm.getSsoSessionMaxLifespan());
+ if (realm.getRequiredCredentials() != null) {
+ Assert.assertNotNull(storedRealm.getRequiredCredentials());
+ for (String cred : realm.getRequiredCredentials()) {
+ Assert.assertTrue(storedRealm.getRequiredCredentials().contains(cred));
+ }
+ }
+ if (realm.getLoginTheme() != null) Assert.assertEquals(realm.getLoginTheme(), storedRealm.getLoginTheme());
+ if (realm.getAccountTheme() != null) Assert.assertEquals(realm.getAccountTheme(), storedRealm.getAccountTheme());
+ if (realm.getAdminTheme() != null) Assert.assertEquals(realm.getAdminTheme(), storedRealm.getAdminTheme());
+ if (realm.getEmailTheme() != null) Assert.assertEquals(realm.getEmailTheme(), storedRealm.getEmailTheme());
+
+ if (realm.getPasswordPolicy() != null) Assert.assertEquals(realm.getPasswordPolicy(), storedRealm.getPasswordPolicy());
+
+ if (realm.getDefaultRoles() != null) {
+ Assert.assertNotNull(storedRealm.getDefaultRoles());
+ for (String role : realm.getDefaultRoles()) {
+ Assert.assertTrue(storedRealm.getDefaultRoles().contains(role));
+ }
+ }
+
+ if (realm.getSmtpServer() != null) {
+ Assert.assertEquals(realm.getSmtpServer(), storedRealm.getSmtpServer());
+ }
+
+ if (realm.getBrowserSecurityHeaders() != null) {
+ Assert.assertEquals(realm.getBrowserSecurityHeaders(), storedRealm.getBrowserSecurityHeaders());
+ }
+
+ }
+
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ServerInfoTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ServerInfoTest.java
new file mode 100644
index 0000000000..6c839c5997
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ServerInfoTest.java
@@ -0,0 +1,44 @@
+package org.keycloak.testsuite.admin;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.keycloak.common.Version;
+import org.keycloak.representations.info.ServerInfoRepresentation;
+import org.keycloak.testsuite.OAuthClient;
+import org.keycloak.testsuite.rule.WebResource;
+import org.keycloak.testsuite.rule.WebRule;
+import org.openqa.selenium.WebDriver;
+
+/**
+ * @author Stian Thorgersen
+ */
+public class ServerInfoTest extends AbstractClientTest {
+
+ @Rule
+ public WebRule webRule = new WebRule(this);
+
+ @WebResource
+ protected WebDriver driver;
+
+ @WebResource
+ protected OAuthClient oauth;
+
+ @Test
+ public void testServerInfo() {
+ ServerInfoRepresentation info = keycloak.serverInfo().getInfo();
+
+ Assert.assertNotNull(info);
+ Assert.assertNotNull(info.getProviders());
+ Assert.assertNotNull(info.getThemes());
+ Assert.assertNotNull(info.getEnums());
+
+ Assert.assertNotNull(info.getMemoryInfo());
+ Assert.assertNotNull(info.getSystemInfo());
+
+ Assert.assertEquals(Version.VERSION, info.getSystemInfo().getVersion());
+ Assert.assertNotNull(info.getSystemInfo().getServerTime());
+ Assert.assertNotNull(info.getSystemInfo().getUptime());
+ }
+
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
index 597e7dd5d4..a9b907c612 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/CacheTest.java
@@ -7,10 +7,12 @@ import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Test;
import org.keycloak.models.*;
+import org.keycloak.models.cache.infinispan.ClientAdapter;
import org.keycloak.models.cache.infinispan.RealmAdapter;
import org.keycloak.testsuite.rule.KeycloakRule;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
/**
* @author Bill Burke
@@ -27,10 +29,12 @@ public class CacheTest {
// load up cache
KeycloakSession session = kc.startSession();
RealmModel realm = session.realms().getRealmByName("test");
+ assertTrue(realm instanceof RealmAdapter);
ClientModel testApp = realm.getClientByClientId("test-app");
+ assertTrue(testApp instanceof ClientAdapter);
assertNotNull(testApp);
appId = testApp.getId();
- Assert.assertTrue(testApp.isEnabled());
+ assertTrue(testApp.isEnabled());
kc.stopSession(session, true);
}
{
@@ -40,16 +44,18 @@ public class CacheTest {
// KEYCLOAK-1240 - obtain the realm via session.realms().getRealms()
RealmModel realm = null;
List realms = session.realms().getRealms();
+
for (RealmModel current : realms) {
+ assertTrue(current instanceof RealmAdapter);
if ("test".equals(current.getName())) {
realm = current;
break;
}
}
- Assert.assertTrue(realm instanceof RealmAdapter);
realm.setAccessCodeLifespanLogin(200);
ClientModel testApp = realm.getClientByClientId("test-app");
+
assertNotNull(testApp);
testApp.setEnabled(false);
kc.stopSession(session, true);
@@ -62,10 +68,7 @@ public class CacheTest {
ClientModel testApp = session.realms().getClientById(appId, realm);
Assert.assertFalse(testApp.isEnabled());
kc.stopSession(session, true);
-
}
-
-
}
@Test
diff --git a/testsuite/integration/src/test/resources/log4j.properties b/testsuite/integration/src/test/resources/log4j.properties
index 5bccb0e624..01f6cd503e 100755
--- a/testsuite/integration/src/test/resources/log4j.properties
+++ b/testsuite/integration/src/test/resources/log4j.properties
@@ -21,6 +21,9 @@ log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterP
# Enable to view infinispan initialization
# log4j.logger.org.keycloak.models.sessions.infinispan.initializer=trace
+# Enable to view cache activity
+# log4j.logger.org.keycloak.models.cache=trace
+
# Enable to view database updates
# log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug