Merge upstream-master
This commit is contained in:
commit
b8fe608aaf
35 changed files with 632 additions and 463 deletions
|
@ -1,15 +1,25 @@
|
||||||
package org.keycloak.services.resources.admin.info;
|
package org.keycloak.representations.info;
|
||||||
|
|
||||||
public class MemoryInfoRepresentation {
|
public class MemoryInfoRepresentation {
|
||||||
|
|
||||||
protected long total;
|
protected long total;
|
||||||
|
protected String totalFormated;
|
||||||
protected long used;
|
protected long used;
|
||||||
|
protected String usedFormated;
|
||||||
|
protected long free;
|
||||||
|
protected long freePercentage;
|
||||||
|
protected String freeFormated;
|
||||||
|
|
||||||
public static MemoryInfoRepresentation create() {
|
public static MemoryInfoRepresentation create() {
|
||||||
MemoryInfoRepresentation rep = new MemoryInfoRepresentation();
|
MemoryInfoRepresentation rep = new MemoryInfoRepresentation();
|
||||||
Runtime runtime = Runtime.getRuntime();
|
Runtime runtime = Runtime.getRuntime();
|
||||||
rep.total = runtime.maxMemory();
|
rep.total = runtime.maxMemory();
|
||||||
|
rep.totalFormated = formatMemory(rep.total);
|
||||||
rep.used = runtime.totalMemory() - runtime.freeMemory();
|
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;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,15 +28,15 @@ public class MemoryInfoRepresentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTotalFormated() {
|
public String getTotalFormated() {
|
||||||
return formatMemory(getTotal());
|
return totalFormated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFree() {
|
public long getFree() {
|
||||||
return getTotal() - getUsed();
|
return free;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFreeFormated() {
|
public String getFreeFormated() {
|
||||||
return formatMemory(getFree());
|
return freeFormated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getUsed() {
|
public long getUsed() {
|
||||||
|
@ -34,14 +44,14 @@ public class MemoryInfoRepresentation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsedFormated() {
|
public String getUsedFormated() {
|
||||||
return formatMemory(getUsed());
|
return usedFormated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getFreePercentage() {
|
public long getFreePercentage() {
|
||||||
return getFree() * 100 / getTotal();
|
return freePercentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatMemory(long bytes) {
|
private static String formatMemory(long bytes) {
|
||||||
if (bytes > 1024L * 1024L) {
|
if (bytes > 1024L * 1024L) {
|
||||||
return bytes / (1024L * 1024L) + " MB";
|
return bytes / (1024L * 1024L) + " MB";
|
||||||
} else if (bytes > 1024L) {
|
} else if (bytes > 1024L) {
|
|
@ -1,4 +1,4 @@
|
||||||
package org.keycloak.services.resources.admin.info;
|
package org.keycloak.representations.info;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -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.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
|
@ -1,4 +1,4 @@
|
||||||
package org.keycloak.services.resources.admin.info;
|
package org.keycloak.representations.info;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.keycloak.services.resources.admin.info;
|
package org.keycloak.representations.info;
|
||||||
|
|
||||||
import org.keycloak.common.Version;
|
import org.keycloak.common.Version;
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -27,11 +26,11 @@ public class SystemInfoRepresentation {
|
||||||
private String userTimezone;
|
private String userTimezone;
|
||||||
private String userLocale;
|
private String userLocale;
|
||||||
|
|
||||||
public static SystemInfoRepresentation create(KeycloakSession session) {
|
public static SystemInfoRepresentation create(long serverStartupTime) {
|
||||||
SystemInfoRepresentation rep = new SystemInfoRepresentation();
|
SystemInfoRepresentation rep = new SystemInfoRepresentation();
|
||||||
rep.version = Version.VERSION;
|
rep.version = Version.VERSION;
|
||||||
rep.serverTime = new Date().toString();
|
rep.serverTime = new Date().toString();
|
||||||
rep.uptimeMillis = System.currentTimeMillis() - session.getKeycloakSessionFactory().getServerStartupTimestamp();
|
rep.uptimeMillis = System.currentTimeMillis() - serverStartupTime;
|
||||||
rep.uptime = formatUptime(rep.uptimeMillis);
|
rep.uptime = formatUptime(rep.uptimeMillis);
|
||||||
rep.javaVersion = System.getProperty("java.version");
|
rep.javaVersion = System.getProperty("java.version");
|
||||||
rep.javaVendor = System.getProperty("java.vendor");
|
rep.javaVendor = System.getProperty("java.vendor");
|
|
@ -235,7 +235,7 @@ credentials=Credencials
|
||||||
saml-keys=Claus SAML
|
saml-keys=Claus SAML
|
||||||
roles=Rols
|
roles=Rols
|
||||||
mappers=Assignadors
|
mappers=Assignadors
|
||||||
mappers.tootip=Els assignadors de protocols realitzen transformacions en tokens i documents. Poden fer coses com assignar dades d''usuari en peticions de protocol, o simplement transformar qualsevol petici\u00F3 entre el client i el servidor d''autenticaci\u00F3.
|
mappers.tooltip=Els assignadors de protocols realitzen transformacions en tokens i documents. Poden fer coses com assignar dades d''usuari en peticions de protocol, o simplement transformar qualsevol petici\u00F3 entre el client i el servidor d''autenticaci\u00F3.
|
||||||
scope=\u00C0mbit
|
scope=\u00C0mbit
|
||||||
scope.tooltip=Les assignacions d''\u00E0mbit et permeten restringir que assignacions de rols d''usuari s''inclouen en el testimoni d''acc\u00E9s sol\u00B7licitat pel client.
|
scope.tooltip=Les assignacions d''\u00E0mbit et permeten restringir que assignacions de rols d''usuari s''inclouen en el testimoni d''acc\u00E9s sol\u00B7licitat pel client.
|
||||||
sessions.tooltip=Veure sessions actives per a aquest client. Permet veure quins usuaris estan actius i quan es van identificar.
|
sessions.tooltip=Veure sessions actives per a aquest client. Permet veure quins usuaris estan actius i quan es van identificar.
|
||||||
|
|
|
@ -232,7 +232,7 @@ credentials=de Credentials
|
||||||
saml-keys=de SAML Keys
|
saml-keys=de SAML Keys
|
||||||
roles=de Roles
|
roles=de Roles
|
||||||
mappers=de Mappers
|
mappers=de Mappers
|
||||||
mappers.tootip=de Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server.
|
mappers.tooltip=de Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server.
|
||||||
scope=de Scope
|
scope=de Scope
|
||||||
scope.tooltip=de Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client.
|
scope.tooltip=de Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client.
|
||||||
sessions.tooltip=de View active sessions for this client. Allows you to see which users are active and when they logged in.
|
sessions.tooltip=de View active sessions for this client. Allows you to see which users are active and when they logged in.
|
||||||
|
|
|
@ -63,9 +63,9 @@ supported-locales=Supported Locales
|
||||||
supported-locales.placeholder=Type a locale and enter
|
supported-locales.placeholder=Type a locale and enter
|
||||||
default-locale=Default Locale
|
default-locale=Default Locale
|
||||||
realm-cache-enabled=Realm Cache Enabled
|
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=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=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.
|
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
|
sso-session-idle=SSO Session Idle
|
||||||
|
@ -243,7 +243,7 @@ credentials=Credentials
|
||||||
saml-keys=SAML Keys
|
saml-keys=SAML Keys
|
||||||
roles=Roles
|
roles=Roles
|
||||||
mappers=Mappers
|
mappers=Mappers
|
||||||
mappers.tootip=Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server.
|
mappers.tooltip=Protocol mappers perform transformation on tokens and documents. They an do things like map user data into protocol claims, or just transform any requests going between the client and auth server.
|
||||||
scope=Scope
|
scope=Scope
|
||||||
scope.tooltip=Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client.
|
scope.tooltip=Scope mappings allow you to restrict which user role mappings are included within the access token requested by the client.
|
||||||
sessions.tooltip=View active sessions for this client. Allows you to see which users are active and when they logged in.
|
sessions.tooltip=View active sessions for this client. Allows you to see which users are active and when they logged in.
|
||||||
|
|
|
@ -235,7 +235,7 @@ credentials=Credenciales
|
||||||
saml-keys=Claves SAML
|
saml-keys=Claves SAML
|
||||||
roles=Roles
|
roles=Roles
|
||||||
mappers=Asignadores
|
mappers=Asignadores
|
||||||
mappers.tootip=Los asignadores de protocolos realizan transformaciones en tokens y documentos. Pueden hacer cosas como asignar datos de usuario en peticiones de protocolo, o simplemente transformar cualquier petici\u00F3n entre el cliente y el servidor de autenticaci\u00F3n.
|
mappers.tooltip=Los asignadores de protocolos realizan transformaciones en tokens y documentos. Pueden hacer cosas como asignar datos de usuario en peticiones de protocolo, o simplemente transformar cualquier petici\u00F3n entre el cliente y el servidor de autenticaci\u00F3n.
|
||||||
scope=\u00C1mbito
|
scope=\u00C1mbito
|
||||||
scope.tooltip=Las asignaciones de \u00E1mbito te permiten restringir que asignaciones de roles de usuario se incluyen en el token de acceso solicitado por el cliente.
|
scope.tooltip=Las asignaciones de \u00E1mbito te permiten restringir que asignaciones de roles de usuario se incluyen en el token de acceso solicitado por el cliente.
|
||||||
sessions.tooltip=Ver sesiones activas para este cliente. Permite ver qu\u00E9 usuarios est\u00E1n activos y cuando se identificaron.
|
sessions.tooltip=Ver sesiones activas para este cliente. Permite ver qu\u00E9 usuarios est\u00E1n activos y cuando se identificaron.
|
||||||
|
|
|
@ -6,6 +6,7 @@ import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
|
||||||
import org.keycloak.admin.client.resource.BearerAuthFilter;
|
import org.keycloak.admin.client.resource.BearerAuthFilter;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.admin.client.resource.RealmsResource;
|
import org.keycloak.admin.client.resource.RealmsResource;
|
||||||
|
import org.keycloak.admin.client.resource.ServerInfoResource;
|
||||||
import org.keycloak.admin.client.token.TokenManager;
|
import org.keycloak.admin.client.token.TokenManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +52,10 @@ public class Keycloak {
|
||||||
return realms().realm(realmName);
|
return realms().realm(realmName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServerInfoResource serverInfo(){
|
||||||
|
return target.proxy(ServerInfoResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
public TokenManager tokenManager(){
|
public TokenManager tokenManager(){
|
||||||
return tokenManager;
|
return tokenManager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
@Path("/admin/serverinfo")
|
||||||
|
public interface ServerInfoResource {
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
ServerInfoRepresentation getInfo();
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.utils.Base32;
|
import org.keycloak.models.utils.Base32;
|
||||||
import org.keycloak.models.utils.HmacOTP;
|
import org.keycloak.models.utils.HmacOTP;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -13,7 +14,7 @@ import java.util.Map;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class OTPPolicy {
|
public class OTPPolicy implements Serializable {
|
||||||
|
|
||||||
protected static final Logger logger = Logger.getLogger(OTPPolicy.class);
|
protected static final Logger logger = Logger.getLogger(OTPPolicy.class);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.models;
|
package org.keycloak.models;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@ import java.util.Map;
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public class RequiredActionProviderModel {
|
public class RequiredActionProviderModel implements Serializable {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String alias;
|
private String alias;
|
||||||
|
|
|
@ -1044,35 +1044,14 @@ public class RepresentationToModel {
|
||||||
user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
|
user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userRep.getCredentials() != null) {
|
createCredentials(userRep, user);
|
||||||
for (CredentialRepresentation cred : userRep.getCredentials()) {
|
|
||||||
updateCredential(user, cred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (userRep.getFederatedIdentities() != null) {
|
if (userRep.getFederatedIdentities() != null) {
|
||||||
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
||||||
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
||||||
session.users().addFederatedIdentity(newRealm, user, mappingModel);
|
session.users().addFederatedIdentity(newRealm, user, mappingModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (userRep.getRealmRoles() != null) {
|
createRoleMappings(userRep, user, newRealm);
|
||||||
for (String roleString : userRep.getRealmRoles()) {
|
|
||||||
RoleModel role = newRealm.getRole(roleString.trim());
|
|
||||||
if (role == null) {
|
|
||||||
role = newRealm.addRole(roleString.trim());
|
|
||||||
}
|
|
||||||
user.grantRole(role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (userRep.getClientRoles() != null) {
|
|
||||||
for (Map.Entry<String, List<String>> entry : userRep.getClientRoles().entrySet()) {
|
|
||||||
ClientModel client = clientMap.get(entry.getKey());
|
|
||||||
if (client == null) {
|
|
||||||
throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey());
|
|
||||||
}
|
|
||||||
createClientRoleMappings(client, user, entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (userRep.getClientConsents() != null) {
|
if (userRep.getClientConsents() != null) {
|
||||||
for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
|
for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
|
||||||
UserConsentModel consentModel = toModel(newRealm, consentRep);
|
UserConsentModel consentModel = toModel(newRealm, consentRep);
|
||||||
|
@ -1100,6 +1079,14 @@ public class RepresentationToModel {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void createCredentials(UserRepresentation userRep, UserModel user) {
|
||||||
|
if (userRep.getCredentials() != null) {
|
||||||
|
for (CredentialRepresentation cred : userRep.getCredentials()) {
|
||||||
|
updateCredential(user, cred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Detect if it is "plain-text" or "hashed" representation and update model according to it
|
// Detect if it is "plain-text" or "hashed" representation and update model according to it
|
||||||
private static void updateCredential(UserModel user, CredentialRepresentation cred) {
|
private static void updateCredential(UserModel user, CredentialRepresentation cred) {
|
||||||
if (cred.getValue() != null) {
|
if (cred.getValue() != null) {
|
||||||
|
@ -1142,6 +1129,28 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
// Role mappings
|
// Role mappings
|
||||||
|
|
||||||
|
public static void createRoleMappings(UserRepresentation userRep, UserModel user, RealmModel realm) {
|
||||||
|
if (userRep.getRealmRoles() != null) {
|
||||||
|
for (String roleString : userRep.getRealmRoles()) {
|
||||||
|
RoleModel role = realm.getRole(roleString.trim());
|
||||||
|
if (role == null) {
|
||||||
|
role = realm.addRole(roleString.trim());
|
||||||
|
}
|
||||||
|
user.grantRole(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (userRep.getClientRoles() != null) {
|
||||||
|
Map<String, ClientModel> clientMap = realm.getClientNameMap();
|
||||||
|
for (Map.Entry<String, List<String>> entry : userRep.getClientRoles().entrySet()) {
|
||||||
|
ClientModel client = clientMap.get(entry.getKey());
|
||||||
|
if (client == null) {
|
||||||
|
throw new RuntimeException("Unable to find client role mappings for client: " + entry.getKey());
|
||||||
|
}
|
||||||
|
createClientRoleMappings(client, user, entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void createClientRoleMappings(ClientModel clientModel, UserModel user, List<String> roleNames) {
|
public static void createClientRoleMappings(ClientModel clientModel, UserModel user, List<String> roleNames) {
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new RuntimeException("User not found");
|
throw new RuntimeException("User not found");
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class ClientAdapter implements ClientModel {
|
||||||
private void getDelegateForUpdate() {
|
private void getDelegateForUpdate() {
|
||||||
if (updated == null) {
|
if (updated == null) {
|
||||||
cacheSession.registerApplicationInvalidation(getId());
|
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");
|
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
package org.keycloak.models.cache.infinispan;
|
package org.keycloak.models.cache.infinispan;
|
||||||
|
|
||||||
import org.infinispan.Cache;
|
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.Config;
|
||||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
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.CacheRealmProvider;
|
||||||
import org.keycloak.models.cache.CacheRealmProviderFactory;
|
import org.keycloak.models.cache.CacheRealmProviderFactory;
|
||||||
import org.keycloak.models.cache.RealmCache;
|
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;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -17,15 +29,43 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
*/
|
*/
|
||||||
public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFactory {
|
public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFactory {
|
||||||
|
|
||||||
protected final ConcurrentHashMap<String, String> realmLookup = new ConcurrentHashMap<String, String>();
|
private static final Logger log = Logger.getLogger(InfinispanCacheRealmProviderFactory.class);
|
||||||
|
|
||||||
|
protected volatile InfinispanRealmCache realmCache;
|
||||||
|
|
||||||
|
protected final ConcurrentHashMap<String, String> realmLookup = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private boolean isNewInfinispan;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheRealmProvider create(KeycloakSession session) {
|
public CacheRealmProvider create(KeycloakSession session) {
|
||||||
Cache<String, Object> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
|
lazyInit(session);
|
||||||
RealmCache realmCache = new InfinispanRealmCache(cache, realmLookup);
|
|
||||||
return new DefaultCacheRealmProvider(realmCache, session);
|
return new DefaultCacheRealmProvider(realmCache, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void lazyInit(KeycloakSession session) {
|
||||||
|
if (realmCache == null) {
|
||||||
|
synchronized (this) {
|
||||||
|
if (realmCache == null) {
|
||||||
|
checkIspnVersion();
|
||||||
|
|
||||||
|
Cache<String, Object> 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
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
}
|
}
|
||||||
|
@ -44,4 +84,71 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
|
||||||
return "infinispan";
|
return "infinispan";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Listener
|
||||||
|
public class CacheListener {
|
||||||
|
|
||||||
|
@CacheEntryCreated
|
||||||
|
public void created(CacheEntryCreatedEvent<String, Object> 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<String, Object> event) {
|
||||||
|
if (event.isPre()) {
|
||||||
|
Object object = event.getValue();
|
||||||
|
if (object != null) {
|
||||||
|
remove(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEntryInvalidated
|
||||||
|
public void removed(CacheEntryInvalidatedEvent<String, Object> event) {
|
||||||
|
if (event.isPre()) {
|
||||||
|
Object object = event.getValue();
|
||||||
|
if (object != null) {
|
||||||
|
remove(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheEntriesEvicted
|
||||||
|
public void userEvicted(CacheEntriesEvictedEvent<String, Object> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class InfinispanCacheUserProviderFactory implements CacheUserProviderFact
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(InfinispanCacheUserProviderFactory.class);
|
private static final Logger log = Logger.getLogger(InfinispanCacheUserProviderFactory.class);
|
||||||
|
|
||||||
protected InfinispanUserCache userCache;
|
protected volatile InfinispanUserCache userCache;
|
||||||
|
|
||||||
protected final RealmLookup usernameLookup = new RealmLookup();
|
protected final RealmLookup usernameLookup = new RealmLookup();
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,10 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
|
if (this.enabled && !enabled) {
|
||||||
clear();
|
clear();
|
||||||
|
}
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -66,7 +67,7 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
public void addCachedRealm(CachedRealm realm) {
|
public void addCachedRealm(CachedRealm realm) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
logger.tracev("Adding realm {0}", realm.getId());
|
logger.tracev("Adding realm {0}", realm.getId());
|
||||||
cache.put(realm.getId(), realm);
|
cache.putForExternalRead(realm.getId(), realm);
|
||||||
realmLookup.put(realm.getName(), realm.getId());
|
realmLookup.put(realm.getName(), realm.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
public void addCachedClient(CachedClient app) {
|
public void addCachedClient(CachedClient app) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
logger.tracev("Adding application {0}", app.getId());
|
logger.tracev("Adding application {0}", app.getId());
|
||||||
cache.put(app.getId(), app);
|
cache.putForExternalRead(app.getId(), app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -102,6 +103,12 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
cache.remove(id);
|
cache.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evictCachedApplicationById(String id) {
|
||||||
|
logger.tracev("Evicting application {0}", id);
|
||||||
|
cache.evict(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedGroup getGroup(String id) {
|
public CachedGroup getGroup(String id) {
|
||||||
if (!enabled) return null;
|
if (!enabled) return null;
|
||||||
|
@ -112,15 +119,13 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
public void invalidateGroup(CachedGroup role) {
|
public void invalidateGroup(CachedGroup role) {
|
||||||
logger.tracev("Removing group {0}", role.getId());
|
logger.tracev("Removing group {0}", role.getId());
|
||||||
cache.remove(role.getId());
|
cache.remove(role.getId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedGroup(CachedGroup role) {
|
public void addCachedGroup(CachedGroup role) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
logger.tracev("Adding group {0}", role.getId());
|
logger.tracev("Adding group {0}", role.getId());
|
||||||
cache.put(role.getId(), role);
|
cache.putForExternalRead(role.getId(), role);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -134,7 +139,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
public void invalidateGroupById(String id) {
|
public void invalidateGroupById(String id) {
|
||||||
logger.tracev("Removing group {0}", id);
|
logger.tracev("Removing group {0}", id);
|
||||||
cache.remove(id);
|
cache.remove(id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -143,8 +147,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
return get(id, CachedRole.class);
|
return get(id, CachedRole.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateRole(CachedRole role) {
|
public void invalidateRole(CachedRole role) {
|
||||||
logger.tracev("Removing role {0}", role.getId());
|
logger.tracev("Removing role {0}", role.getId());
|
||||||
|
@ -161,7 +163,7 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
public void addCachedRole(CachedRole role) {
|
public void addCachedRole(CachedRole role) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
logger.tracev("Adding role {0}", role.getId());
|
logger.tracev("Adding role {0}", role.getId());
|
||||||
cache.put(role.getId(), role);
|
cache.putForExternalRead(role.getId(), role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -35,9 +35,10 @@ public class InfinispanUserCache implements UserCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
|
if (this.enabled && !enabled) {
|
||||||
clear();
|
clear();
|
||||||
|
}
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -62,7 +63,7 @@ public class InfinispanUserCache implements UserCache {
|
||||||
@Override
|
@Override
|
||||||
public void addCachedUser(String realmId, CachedUser user) {
|
public void addCachedUser(String realmId, CachedUser user) {
|
||||||
logger.tracev("Adding user {0}", user.getId());
|
logger.tracev("Adding user {0}", user.getId());
|
||||||
cache.put(user.getId(), user);
|
cache.putForExternalRead(user.getId(), user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,6 +26,8 @@ public interface RealmCache {
|
||||||
|
|
||||||
void invalidateApplication(CachedClient app);
|
void invalidateApplication(CachedClient app);
|
||||||
|
|
||||||
|
void evictCachedApplicationById(String id);
|
||||||
|
|
||||||
void addCachedClient(CachedClient app);
|
void addCachedClient(CachedClient app);
|
||||||
|
|
||||||
void invalidateCachedApplicationById(String id);
|
void invalidateCachedApplicationById(String id);
|
||||||
|
|
|
@ -9,10 +9,7 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
import org.keycloak.exportimport.ExportImportManager;
|
import org.keycloak.exportimport.ExportImportManager;
|
||||||
import org.keycloak.migration.MigrationModelManager;
|
import org.keycloak.migration.MigrationModelManager;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.models.utils.PostMigrationEvent;
|
import org.keycloak.models.utils.PostMigrationEvent;
|
||||||
import org.keycloak.models.utils.RepresentationToModel;
|
import org.keycloak.models.utils.RepresentationToModel;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
@ -263,35 +260,49 @@ public class KeycloakApplication extends Application {
|
||||||
if (addUserFile.isFile()) {
|
if (addUserFile.isFile()) {
|
||||||
log.info("Importing users from '" + addUserFile + "'");
|
log.info("Importing users from '" + addUserFile + "'");
|
||||||
|
|
||||||
|
List<RealmRepresentation> realms;
|
||||||
|
try {
|
||||||
|
realms = JsonSerialization.readValue(new FileInputStream(addUserFile), new TypeReference<List<RealmRepresentation>>() {
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.errorv("Failed to load 'keycloak-add-user.json': {0}", e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RealmRepresentation realmRep : realms) {
|
||||||
|
for (UserRepresentation userRep : realmRep.getUsers()) {
|
||||||
KeycloakSession session = sessionFactory.create();
|
KeycloakSession session = sessionFactory.create();
|
||||||
try {
|
try {
|
||||||
session.getTransaction().begin();
|
session.getTransaction().begin();
|
||||||
|
|
||||||
List<RealmRepresentation> realms = JsonSerialization.readValue(new FileInputStream(addUserFile), new TypeReference<List<RealmRepresentation>>() {});
|
RealmModel realm = session.realms().getRealmByName(realmRep.getRealm());
|
||||||
for (RealmRepresentation r : realms) {
|
|
||||||
RealmModel realm = session.realms().getRealmByName(r.getRealm());
|
|
||||||
if (realm == null) {
|
if (realm == null) {
|
||||||
throw new Exception("Realm '" + r.getRealm() + "' not found");
|
log.errorv("Failed to add user ''{0}'' to realm ''{1}'': realm not found", userRep.getUsername(), realmRep.getRealm());
|
||||||
}
|
} else {
|
||||||
|
UserModel user = session.users().addUser(realm, userRep.getUsername());
|
||||||
for (UserRepresentation u : r.getUsers()) {
|
user.setEnabled(userRep.isEnabled());
|
||||||
RepresentationToModel.createUser(session, realm, u, realm.getClientNameMap());
|
RepresentationToModel.createCredentials(userRep, user);
|
||||||
}
|
RepresentationToModel.createRoleMappings(userRep, user, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
session.getTransaction().commit();
|
session.getTransaction().commit();
|
||||||
|
log.infov("Added user ''{0}'' to realm ''{1}''", userRep.getUsername(), realmRep.getRealm());
|
||||||
if (!addUserFile.delete()) {
|
} catch (ModelDuplicateException e) {
|
||||||
log.error("Failed to delete '" + addUserFile + "'");
|
log.errorv("Failed to add user ''{0}'' to realm ''{1}'': user with username exists", userRep.getUsername(), realmRep.getRealm());
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
session.getTransaction().rollback();
|
session.getTransaction().rollback();
|
||||||
log.error("Failed to import users from '" + addUserFile + "'", t);
|
log.errorv("Failed to add user ''{0}'' to realm ''{1}'': {2}", userRep.getUsername(), realmRep.getRealm(), t.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
session.close();
|
session.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!addUserFile.delete()) {
|
||||||
|
log.errorv("Failed to delete '{0}'", addUserFile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T loadJson(InputStream is, Class<T> type) {
|
private static <T> T loadJson(InputStream is, Class<T> type) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.keycloak.provider.Spi;
|
||||||
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
|
||||||
|
import org.keycloak.representations.info.*;
|
||||||
import org.keycloak.social.SocialIdentityProvider;
|
import org.keycloak.social.SocialIdentityProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +52,7 @@ public class ServerInfoAdminResource {
|
||||||
@GET
|
@GET
|
||||||
public ServerInfoRepresentation getInfo() {
|
public ServerInfoRepresentation getInfo() {
|
||||||
ServerInfoRepresentation info = new ServerInfoRepresentation();
|
ServerInfoRepresentation info = new ServerInfoRepresentation();
|
||||||
info.setSystemInfo(SystemInfoRepresentation.create(session));
|
info.setSystemInfo(SystemInfoRepresentation.create(session.getKeycloakSessionFactory().getServerStartupTimestamp()));
|
||||||
info.setMemoryInfo(MemoryInfoRepresentation.create());
|
info.setMemoryInfo(MemoryInfoRepresentation.create());
|
||||||
|
|
||||||
setSocialProviders(info);
|
setSocialProviders(info);
|
||||||
|
|
|
@ -1,15 +1,28 @@
|
||||||
package org.keycloak.testsuite.adduser;
|
package org.keycloak.testsuite.adduser;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.type.TypeReference;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.junit.rules.TemporaryFolder;
|
import org.junit.rules.TemporaryFolder;
|
||||||
import org.keycloak.admin.client.Keycloak;
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
|
import org.keycloak.admin.client.resource.RoleMappingResource;
|
||||||
|
import org.keycloak.admin.client.resource.RoleScopeResource;
|
||||||
|
import org.keycloak.admin.client.resource.UserResource;
|
||||||
|
import org.keycloak.common.util.Base64Url;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.models.utils.Pbkdf2PasswordEncoder;
|
||||||
|
import org.keycloak.representations.idm.*;
|
||||||
import org.keycloak.testsuite.KeycloakServer;
|
import org.keycloak.testsuite.KeycloakServer;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
import org.keycloak.wildfly.adduser.AddUser;
|
import org.keycloak.wildfly.adduser.AddUser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -37,7 +50,16 @@ public class AddUserTest {
|
||||||
@Test
|
@Test
|
||||||
public void addUserTest() throws Throwable {
|
public void addUserTest() throws Throwable {
|
||||||
AddUser.main(new String[]{"-u", "addusertest-admin", "-p", "password"});
|
AddUser.main(new String[]{"-u", "addusertest-admin", "-p", "password"});
|
||||||
Assert.assertEquals(1, dir.listFiles().length);
|
assertEquals(1, dir.listFiles().length);
|
||||||
|
|
||||||
|
List<RealmRepresentation> realms = JsonSerialization.readValue(new FileInputStream(new File(dir, "keycloak-add-user.json")), new TypeReference<List<RealmRepresentation>>() {});
|
||||||
|
assertEquals(1, realms.size());
|
||||||
|
assertEquals(1, realms.get(0).getUsers().size());
|
||||||
|
|
||||||
|
UserRepresentation user = realms.get(0).getUsers().get(0);
|
||||||
|
assertEquals(new Integer(100000), user.getCredentials().get(0).getHashIterations());
|
||||||
|
assertNull(user.getCredentials().get(0).getValue());
|
||||||
|
assertEquals(new Pbkdf2PasswordEncoder(Base64Url.decode(user.getCredentials().get(0).getSalt()), 100000).encode("password"), user.getCredentials().get(0).getHashedSaltedValue());
|
||||||
|
|
||||||
KeycloakServer server = new KeycloakServer();
|
KeycloakServer server = new KeycloakServer();
|
||||||
try {
|
try {
|
||||||
|
@ -53,12 +75,54 @@ public class AddUserTest {
|
||||||
|
|
||||||
keycloak.realms().create(testRealm);
|
keycloak.realms().create(testRealm);
|
||||||
|
|
||||||
|
RealmResource realm = keycloak.realm("master");
|
||||||
|
|
||||||
|
List<UserRepresentation> users = realm.users().search("addusertest-admin", null, null, null, null, null);
|
||||||
|
assertEquals(1, users.size());
|
||||||
|
|
||||||
|
UserRepresentation created = users.get(0);
|
||||||
|
assertNotNull(created.getCreatedTimestamp());
|
||||||
|
|
||||||
|
UserResource userResource = realm.users().get(created.getId());
|
||||||
|
|
||||||
|
List<RoleRepresentation> realmRoles = userResource.roles().realmLevel().listAll();
|
||||||
|
|
||||||
|
assertRoles(realmRoles, "admin", "offline_access");
|
||||||
|
|
||||||
|
List<ClientRepresentation> clients = realm.clients().findAll();
|
||||||
|
String accountId = null;
|
||||||
|
for (ClientRepresentation c : clients) {
|
||||||
|
if (c.getClientId().equals("account")) {
|
||||||
|
accountId = c.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<RoleRepresentation> accountRoles = userResource.roles().clientLevel(accountId).listAll();
|
||||||
|
|
||||||
|
assertRoles(accountRoles, "view-profile", "manage-account");
|
||||||
|
|
||||||
keycloak.close();
|
keycloak.close();
|
||||||
|
|
||||||
Assert.assertEquals(0, dir.listFiles().length);
|
assertEquals(0, dir.listFiles().length);
|
||||||
} finally {
|
} finally {
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void assertRoles(List<RoleRepresentation> actual, String... expected) {
|
||||||
|
assertEquals(expected.length, actual.size());
|
||||||
|
|
||||||
|
for (String e : expected) {
|
||||||
|
boolean found = false;
|
||||||
|
for (RoleRepresentation r : actual) {
|
||||||
|
if (r.getName().equals(e)) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
fail("Role " + e + " not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <a href="mailto:bburke@redhat.com">Bill Burke</a>
|
|
||||||
*/
|
|
||||||
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<String> set = new HashSet<String>();
|
|
||||||
for (String val : appRep.getDefaultRoles()) {
|
|
||||||
set.add(val);
|
|
||||||
}
|
|
||||||
Set<String> storedSet = new HashSet<String>();
|
|
||||||
for (String val : storedApp.getDefaultRoles()) {
|
|
||||||
storedSet.add(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals(set, storedSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> redirectUris = appRep.getRedirectUris();
|
|
||||||
if (redirectUris != null) {
|
|
||||||
Set<String> set = new HashSet<String>();
|
|
||||||
for (String val : appRep.getRedirectUris()) {
|
|
||||||
set.add(val);
|
|
||||||
}
|
|
||||||
Set<String> storedSet = new HashSet<String>();
|
|
||||||
for (String val : storedApp.getRedirectUris()) {
|
|
||||||
storedSet.add(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert.assertEquals(set, storedSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> webOrigins = appRep.getWebOrigins();
|
|
||||||
if (webOrigins != null) {
|
|
||||||
Set<String> set = new HashSet<String>();
|
|
||||||
for (String val : appRep.getWebOrigins()) {
|
|
||||||
set.add(val);
|
|
||||||
}
|
|
||||||
Set<String> storedSet = new HashSet<String>();
|
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +1,26 @@
|
||||||
package org.keycloak.testsuite.admin;
|
package org.keycloak.testsuite.admin;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.ClientResource;
|
import org.keycloak.admin.client.resource.ClientResource;
|
||||||
import org.keycloak.admin.client.resource.ProtocolMappersResource;
|
import org.keycloak.admin.client.resource.ProtocolMappersResource;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.*;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
|
||||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
import org.keycloak.testsuite.rule.WebRule;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.client.Entity;
|
||||||
|
import javax.ws.rs.client.WebTarget;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
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);
|
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();
|
ClientRepresentation rep = new ClientRepresentation();
|
||||||
rep.setClientId("my-app");
|
rep.setClientId("my-app");
|
||||||
rep.setDescription("my-app description");
|
rep.setDescription("my-app description");
|
||||||
rep.setEnabled(true);
|
rep.setEnabled(true);
|
||||||
Response response = realm.clients().create(rep);
|
Response response = realm.clients().create(rep);
|
||||||
response.close();
|
response.close();
|
||||||
return ApiUtil.getCreatedId(response);
|
String id = ApiUtil.getCreatedId(response);
|
||||||
|
rep.setId(id);
|
||||||
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createClientVerify() {
|
public void createClientVerify() {
|
||||||
String id = createClient();
|
String id = createClient().getId();
|
||||||
|
|
||||||
assertNotNull(realm.clients().get(id));
|
assertNotNull(realm.clients().get(id));
|
||||||
assertNames(realm.clients().findAll(), "account", "realm-management", "security-admin-console", "broker", "my-app", Constants.ADMIN_CLI_CLIENT_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
|
@Test
|
||||||
public void removeClient() {
|
public void removeClient() {
|
||||||
String id = createClient();
|
String id = createClient().getId();
|
||||||
|
|
||||||
realm.clients().get(id).remove();
|
realm.clients().get(id).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getClientRepresentation() {
|
public void getClientRepresentation() {
|
||||||
String id = createClient();
|
String id = createClient().getId();
|
||||||
|
|
||||||
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
|
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
|
||||||
assertEquals(id, rep.getId());
|
assertEquals(id, rep.getId());
|
||||||
|
@ -86,8 +90,7 @@ public class ClientTest extends AbstractClientTest {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void getClientDescription() {
|
public void getClientDescription() {
|
||||||
|
String id = createClient().getId();
|
||||||
String id = createClient();
|
|
||||||
|
|
||||||
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
|
ClientRepresentation rep = realm.clients().get(id).toRepresentation();
|
||||||
assertEquals(id, rep.getId());
|
assertEquals(id, rep.getId());
|
||||||
|
@ -145,6 +148,28 @@ public class ClientTest extends AbstractClientTest {
|
||||||
protocolMappersTest(mappersResource);
|
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) {
|
public static void protocolMappersTest(ProtocolMappersResource mappersResource) {
|
||||||
// assert default mappers found
|
// 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<String> set = new HashSet<String>();
|
||||||
|
for (String val : client.getDefaultRoles()) {
|
||||||
|
set.add(val);
|
||||||
|
}
|
||||||
|
Set<String> storedSet = new HashSet<String>();
|
||||||
|
for (String val : storedClient.getDefaultRoles()) {
|
||||||
|
storedSet.add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(set, storedSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> redirectUris = client.getRedirectUris();
|
||||||
|
if (redirectUris != null) {
|
||||||
|
Set<String> set = new HashSet<String>();
|
||||||
|
for (String val : client.getRedirectUris()) {
|
||||||
|
set.add(val);
|
||||||
|
}
|
||||||
|
Set<String> storedSet = new HashSet<String>();
|
||||||
|
for (String val : storedClient.getRedirectUris()) {
|
||||||
|
storedSet.add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(set, storedSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> webOrigins = client.getWebOrigins();
|
||||||
|
if (webOrigins != null) {
|
||||||
|
Set<String> set = new HashSet<String>();
|
||||||
|
for (String val : client.getWebOrigins()) {
|
||||||
|
set.add(val);
|
||||||
|
}
|
||||||
|
Set<String> storedSet = new HashSet<String>();
|
||||||
|
for (String val : storedClient.getWebOrigins()) {
|
||||||
|
storedSet.add(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertEquals(set, storedSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.keycloak.testsuite.admin;
|
package org.keycloak.testsuite.admin;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
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.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.testsuite.KeycloakServer;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
@ -43,7 +45,7 @@ public class RealmTest extends AbstractClientTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createRealm() {
|
public void createRealmEmpty() {
|
||||||
try {
|
try {
|
||||||
RealmRepresentation rep = new RealmRepresentation();
|
RealmRepresentation rep = new RealmRepresentation();
|
||||||
rep.setRealm("new-realm");
|
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
|
@Test
|
||||||
public void removeRealm() {
|
public void removeRealm() {
|
||||||
realm.remove();
|
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));
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
*/
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ import org.keycloak.testsuite.pages.LoginUpdateProfilePage;
|
||||||
import org.keycloak.testsuite.pages.OAuthGrantPage;
|
import org.keycloak.testsuite.pages.OAuthGrantPage;
|
||||||
import org.keycloak.testsuite.pages.VerifyEmailPage;
|
import org.keycloak.testsuite.pages.VerifyEmailPage;
|
||||||
import org.keycloak.testsuite.rule.GreenMailRule;
|
import org.keycloak.testsuite.rule.GreenMailRule;
|
||||||
|
import org.keycloak.testsuite.rule.LoggingRule;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
import org.keycloak.testsuite.rule.WebResource;
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
import org.keycloak.testsuite.rule.WebRule;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
@ -93,6 +94,9 @@ public abstract class AbstractIdentityProviderTest {
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static BrokerKeyCloakRule brokerServerRule = new BrokerKeyCloakRule();
|
public static BrokerKeyCloakRule brokerServerRule = new BrokerKeyCloakRule();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public LoggingRule loggingRule = new LoggingRule(this);
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public WebRule webRule = new WebRule(this);
|
public WebRule webRule = new WebRule(this);
|
||||||
|
|
||||||
|
|
|
@ -83,13 +83,15 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled() throws IOException, MessagingException {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled() throws IOException, MessagingException {
|
||||||
getRealm().setVerifyEmail(true);
|
RealmModel realm = getRealm();
|
||||||
|
realm.setVerifyEmail(true);
|
||||||
|
setUpdateProfileFirstLogin(realm, IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
try {
|
try {
|
||||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
|
||||||
identityProviderModel.setTrustEmail(false);
|
identityProviderModel.setTrustEmail(false);
|
||||||
|
|
||||||
UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
|
UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
|
||||||
|
@ -152,13 +154,15 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailNotProvided_emailVerifyEnabled() {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailNotProvided_emailVerifyEnabled() {
|
||||||
getRealm().setVerifyEmail(true);
|
RealmModel realm = getRealm();
|
||||||
|
realm.setVerifyEmail(true);
|
||||||
|
setUpdateProfileFirstLogin(realm, IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
|
||||||
|
|
||||||
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
|
UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
|
||||||
|
|
||||||
|
@ -174,8 +178,10 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled_emailTrustEnabled() {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile_emailProvided_emailVerifyEnabled_emailTrustEnabled() {
|
||||||
getRealm().setVerifyEmail(true);
|
RealmModel realmWithBroker = getRealm();
|
||||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
realmWithBroker.setVerifyEmail(true);
|
||||||
|
setUpdateProfileFirstLogin(realmWithBroker, IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
|
@ -201,13 +207,15 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthentication_emailTrustEnabled_emailVerifyEnabled_emailUpdatedOnFirstLogin() throws IOException, MessagingException {
|
public void testSuccessfulAuthentication_emailTrustEnabled_emailVerifyEnabled_emailUpdatedOnFirstLogin() throws IOException, MessagingException {
|
||||||
getRealm().setVerifyEmail(true);
|
RealmModel realm = getRealm();
|
||||||
|
realm.setVerifyEmail(true);
|
||||||
|
setUpdateProfileFirstLogin(realm, IdentityProviderRepresentation.UPFLM_ON);
|
||||||
|
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
try {
|
try {
|
||||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_ON);
|
|
||||||
identityProviderModel.setTrustEmail(true);
|
identityProviderModel.setTrustEmail(true);
|
||||||
|
|
||||||
UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
|
UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
|
||||||
|
@ -220,14 +228,15 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername() {
|
public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername() {
|
||||||
|
RealmModel realm = getRealm();
|
||||||
|
realm.setRegistrationEmailAsUsername(true);
|
||||||
|
setUpdateProfileFirstLogin(realm, IdentityProviderRepresentation.UPFLM_OFF);
|
||||||
|
|
||||||
getRealm().setRegistrationEmailAsUsername(true);
|
|
||||||
brokerServerRule.stopSession(this.session, true);
|
brokerServerRule.stopSession(this.session, true);
|
||||||
this.session = brokerServerRule.startSession();
|
this.session = brokerServerRule.startSession();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
IdentityProviderModel identityProviderModel = getIdentityProviderModel();
|
||||||
setUpdateProfileFirstLogin(IdentityProviderRepresentation.UPFLM_OFF);
|
|
||||||
|
|
||||||
authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
|
authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
|
||||||
|
|
||||||
|
@ -238,7 +247,7 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent
|
||||||
session = brokerServerRule.startSession();
|
session = brokerServerRule.startSession();
|
||||||
|
|
||||||
// check correct user is created with email as username and bound to correct federated identity
|
// check correct user is created with email as username and bound to correct federated identity
|
||||||
RealmModel realm = getRealm();
|
realm = getRealm();
|
||||||
|
|
||||||
UserModel federatedUser = session.users().getUserByUsername("test-user@localhost", realm);
|
UserModel federatedUser = session.users().getUserByUsername("test-user@localhost", realm);
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,12 @@ import org.junit.Assert;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.models.*;
|
import org.keycloak.models.*;
|
||||||
|
import org.keycloak.models.cache.infinispan.ClientAdapter;
|
||||||
import org.keycloak.models.cache.infinispan.RealmAdapter;
|
import org.keycloak.models.cache.infinispan.RealmAdapter;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -27,10 +29,12 @@ public class CacheTest {
|
||||||
// load up cache
|
// load up cache
|
||||||
KeycloakSession session = kc.startSession();
|
KeycloakSession session = kc.startSession();
|
||||||
RealmModel realm = session.realms().getRealmByName("test");
|
RealmModel realm = session.realms().getRealmByName("test");
|
||||||
|
assertTrue(realm instanceof RealmAdapter);
|
||||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||||
|
assertTrue(testApp instanceof ClientAdapter);
|
||||||
assertNotNull(testApp);
|
assertNotNull(testApp);
|
||||||
appId = testApp.getId();
|
appId = testApp.getId();
|
||||||
Assert.assertTrue(testApp.isEnabled());
|
assertTrue(testApp.isEnabled());
|
||||||
kc.stopSession(session, true);
|
kc.stopSession(session, true);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -40,16 +44,18 @@ public class CacheTest {
|
||||||
// KEYCLOAK-1240 - obtain the realm via session.realms().getRealms()
|
// KEYCLOAK-1240 - obtain the realm via session.realms().getRealms()
|
||||||
RealmModel realm = null;
|
RealmModel realm = null;
|
||||||
List<RealmModel> realms = session.realms().getRealms();
|
List<RealmModel> realms = session.realms().getRealms();
|
||||||
|
|
||||||
for (RealmModel current : realms) {
|
for (RealmModel current : realms) {
|
||||||
|
assertTrue(current instanceof RealmAdapter);
|
||||||
if ("test".equals(current.getName())) {
|
if ("test".equals(current.getName())) {
|
||||||
realm = current;
|
realm = current;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.assertTrue(realm instanceof RealmAdapter);
|
|
||||||
realm.setAccessCodeLifespanLogin(200);
|
realm.setAccessCodeLifespanLogin(200);
|
||||||
ClientModel testApp = realm.getClientByClientId("test-app");
|
ClientModel testApp = realm.getClientByClientId("test-app");
|
||||||
|
|
||||||
assertNotNull(testApp);
|
assertNotNull(testApp);
|
||||||
testApp.setEnabled(false);
|
testApp.setEnabled(false);
|
||||||
kc.stopSession(session, true);
|
kc.stopSession(session, true);
|
||||||
|
@ -62,10 +68,7 @@ public class CacheTest {
|
||||||
ClientModel testApp = session.realms().getClientById(appId, realm);
|
ClientModel testApp = session.realms().getClientById(appId, realm);
|
||||||
Assert.assertFalse(testApp.isEnabled());
|
Assert.assertFalse(testApp.isEnabled());
|
||||||
kc.stopSession(session, true);
|
kc.stopSession(session, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientSessionModel;
|
import org.keycloak.models.ClientSessionModel;
|
||||||
|
@ -26,6 +27,7 @@ import org.keycloak.services.managers.UserManager;
|
||||||
import org.keycloak.services.managers.UserSessionManager;
|
import org.keycloak.services.managers.UserSessionManager;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
|
import org.keycloak.testsuite.rule.LoggingRule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -35,6 +37,9 @@ public class UserSessionProviderOfflineTest {
|
||||||
@ClassRule
|
@ClassRule
|
||||||
public static KeycloakRule kc = new KeycloakRule();
|
public static KeycloakRule kc = new KeycloakRule();
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public LoggingRule loggingRule = new LoggingRule(this);
|
||||||
|
|
||||||
private KeycloakSession session;
|
private KeycloakSession session;
|
||||||
private RealmModel realm;
|
private RealmModel realm;
|
||||||
private UserSessionManager sessionManager;
|
private UserSessionManager sessionManager;
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
package org.keycloak.testsuite.rule;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
import org.junit.rules.TestRule;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.runners.model.Statement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
public class LoggingRule implements TestRule {
|
||||||
|
|
||||||
|
private final Logger log;
|
||||||
|
|
||||||
|
public LoggingRule(Object test) {
|
||||||
|
log = Logger.getLogger(test.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Statement apply(final Statement base, final Description description) {
|
||||||
|
return new Statement() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evaluate() throws Throwable {
|
||||||
|
log.debugf("Before %s", description.getMethodName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
base.evaluate();
|
||||||
|
} finally {
|
||||||
|
log.debugf("After %s", description.getMethodName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,6 +14,10 @@ log4j.logger.org.keycloak=info
|
||||||
# log4j.logger.org.keycloak.provider.ProviderManager=debug
|
# log4j.logger.org.keycloak.provider.ProviderManager=debug
|
||||||
# log4j.logger.org.keycloak.provider.FileSystemProviderLoaderFactory=debug
|
# log4j.logger.org.keycloak.provider.FileSystemProviderLoaderFactory=debug
|
||||||
|
|
||||||
|
# Broker logging
|
||||||
|
keycloak.testsuite.logging.level=info
|
||||||
|
log4j.logger.org.keycloak.testsuite=${keycloak.testsuite.logging.level}
|
||||||
|
|
||||||
# Liquibase updates logged with "info" by default. Logging level can be changed by system property "keycloak.liquibase.logging.level"
|
# Liquibase updates logged with "info" by default. Logging level can be changed by system property "keycloak.liquibase.logging.level"
|
||||||
keycloak.liquibase.logging.level=info
|
keycloak.liquibase.logging.level=info
|
||||||
log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider=${keycloak.liquibase.logging.level}
|
log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider=${keycloak.liquibase.logging.level}
|
||||||
|
@ -21,13 +25,16 @@ log4j.logger.org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterP
|
||||||
# Enable to view infinispan initialization
|
# Enable to view infinispan initialization
|
||||||
# log4j.logger.org.keycloak.models.sessions.infinispan.initializer=trace
|
# 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
|
# Enable to view database updates
|
||||||
# log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
|
# log4j.logger.org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider=debug
|
||||||
# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
|
# log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug
|
||||||
# log4j.logger.org.keycloak.migration.MigrationModelManager=debug
|
# log4j.logger.org.keycloak.migration.MigrationModelManager=debug
|
||||||
|
|
||||||
# Enable to view kerberos/spnego logging
|
# Enable to view kerberos/spnego logging
|
||||||
# log4j.logger.org.keycloak.broker.kerberos=trace
|
# log4j.logger.org.keycloak.federation.kerberos=trace
|
||||||
|
|
||||||
# Enable to view detailed AS REQ and TGS REQ requests to embedded Kerberos server
|
# Enable to view detailed AS REQ and TGS REQ requests to embedded Kerberos server
|
||||||
# log4j.logger.org.apache.directory.server.kerberos=debug
|
# log4j.logger.org.apache.directory.server.kerberos=debug
|
||||||
|
@ -37,3 +44,4 @@ log4j.logger.org.hibernate=off
|
||||||
log4j.logger.org.jboss.resteasy=warn
|
log4j.logger.org.jboss.resteasy=warn
|
||||||
log4j.logger.org.apache.directory.api=warn
|
log4j.logger.org.apache.directory.api=warn
|
||||||
log4j.logger.org.apache.directory.server.core=warn
|
log4j.logger.org.apache.directory.server.core=warn
|
||||||
|
log4j.logger.org.apache.directory.server.ldap.LdapProtocolHandler=error
|
|
@ -154,9 +154,9 @@ public class AddUser {
|
||||||
roles = rolesString.split(",");
|
roles = rolesString.split(",");
|
||||||
} else {
|
} else {
|
||||||
if (realmName.equals("master")) {
|
if (realmName.equals("master")) {
|
||||||
roles = new String[] { "admin", "account/manage-account" };
|
roles = new String[] { "admin" };
|
||||||
} else {
|
} else {
|
||||||
roles = new String[] { "realm-management/realm-admin", "account/manage-account" };
|
roles = new String[] { "realm-management/realm-admin" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue