diff --git a/export-import/export-import-impl/pom.xml b/export-import/export-import-impl/pom.xml deleted file mode 100755 index d32455e0e2..0000000000 --- a/export-import/export-import-impl/pom.xml +++ /dev/null @@ -1,236 +0,0 @@ - - - - keycloak-export-import-parent - org.keycloak - 1.0-beta-4-SNAPSHOT - ../pom.xml - - 4.0.0 - - keycloak-export-import-impl - Keycloak Export Import Impl - - - - - org.keycloak - keycloak-core - ${project.version} - provided - - - org.keycloak - keycloak-model-api - ${project.version} - provided - - - org.keycloak - keycloak-export-import-api - ${project.version} - provided - - - org.jboss.resteasy - jaxrs-api - provided - - - org.jboss.resteasy - resteasy-jaxrs - provided - - - log4j - log4j - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-simple - - - - - org.jboss.logging - jboss-logging - provided - - - org.codehaus.jackson - jackson-core-asl - provided - - - org.codehaus.jackson - jackson-mapper-asl - provided - - - net.iharder - base64 - provided - - - org.bouncycastle - bcprov-jdk16 - provided - - - - de.idyl - winzipaes - provided - - - - org.keycloak - keycloak-model-tests - ${project.version} - tests - test - - - org.keycloak - keycloak-invalidation-cache-model - ${project.version} - test - - - - - - - - - - - - - - - - - - - - - - org.keycloak - keycloak-model-tests - ${project.version} - test - - - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - test - - - org.hibernate - hibernate-entitymanager - test - - - com.h2database - h2 - test - - - junit - junit - test - - - org.mongodb - mongo-java-driver - test - - - - - localhost - 27018 - keycloak - true - 127.0.0.1 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${maven.compiler.source} - ${maven.compiler.target} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportPropertiesManager.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportPropertiesManager.java deleted file mode 100755 index 4d49b5a828..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportPropertiesManager.java +++ /dev/null @@ -1,152 +0,0 @@ -package org.keycloak.exportimport; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jboss.logging.Logger; -import org.keycloak.models.utils.reflection.Property; -import org.keycloak.models.utils.reflection.PropertyCriteria; -import org.keycloak.models.utils.reflection.PropertyQueries; - -/** - * Not thread safe (objectProperties). Assumption is that export/import is executed once per JVM - * - * @author Marek Posolda - */ -public class ExportImportPropertiesManager { - - private static final Logger logger = Logger.getLogger(ExportImportPropertiesManager.class); - - private Map, Map>> objectProperties = new HashMap, Map>>(); - - // Add properties of class to objectProperties - protected void initClassProperties(Class clazz) { - Map> classProps = PropertyQueries.createQuery(clazz).addCriteria(new NonEmptyGetterCriteria()).getWritableResultList(); - this.objectProperties.put(clazz, classProps); - } - - public void setBasicPropertiesFromModel(Object model, Object entity) { - Class modelClass = getModelClass(model); - - // Lazy init of properties - checkPropertiesAvailable(modelClass, entity.getClass()); - - Map> modelProps = this.objectProperties.get(modelClass); - Map> entityProps = this.objectProperties.get(entity.getClass()); - - Map> entityPropsCopy = new HashMap>(entityProps); - - logger.debugf("Properties of entity %s: %s", entity, entityProps.keySet()); - for (Property modelProperty : modelProps.values()) { - Property entityProperty = entityPropsCopy.get(modelProperty.getName()); - - entityPropsCopy.remove(modelProperty.getName()); - - if (entityProperty != null) { - Object propertyValue = modelProperty.getValue(model); - - // Workaround needed because model classes have many getters/setters with "Set", but for entity classes, there are usually "List" - if (propertyValue instanceof Set) { - Set propValueAsSet = (Set)propertyValue; - entityProperty.setValue(entity, new ArrayList(propValueAsSet)); - } else { - entityProperty.setValue(entity, propertyValue); - } - if (logger.isTraceEnabled()) { - logger.tracef("Property %s successfully set in JSON to entity %s", modelProperty.getName(), entity); - } - } else { - logger.debugf("Property %s not known in JSON for entity %s", modelProperty.getName(), entity); - } - } - - logger.debugf("Entity properties for manual setup: %s", entityPropsCopy.keySet()); - } - - private void checkPropertiesAvailable(Class modelClass, Class entityClass) { - if (!objectProperties.containsKey(modelClass)) { - initClassProperties(modelClass); - } - if (!objectProperties.containsKey(entityClass)) { - initClassProperties(entityClass); - } - } - - public void setBasicPropertiesToModel(Object model, Object entity) { - Class modelClass = getModelClass(model); - - // Lazy init of properties - checkPropertiesAvailable(modelClass, entity.getClass()); - - Map> modelProps = this.objectProperties.get(modelClass); - Map> entityProps = this.objectProperties.get(entity.getClass()); - - Map> entityPropsCopy = new HashMap>(entityProps); - - logger.debugf("Properties of exported entity %s: %s", entity, entityProps.keySet()); - - for (Property modelProperty : modelProps.values()) { - Property entityProperty = entityPropsCopy.get(modelProperty.getName()); - - entityPropsCopy.remove(modelProperty.getName()); - - if (entityProperty != null) { - Object propertyValue = entityProperty.getValue(entity); - - // Workaround needed because model classes have many getters/setters with "Set", but for entity classes, there are usually "List" - if (propertyValue instanceof List && Set.class.isAssignableFrom(modelProperty.getJavaClass())) { - List propValueAsList = (List)propertyValue; - modelProperty.setValue(model, new HashSet(propValueAsList)); - } else { - modelProperty.setValue(model, propertyValue); - } - - if (logger.isTraceEnabled()) { - logger.tracef("Property %s successfully set in model from entity %s", modelProperty.getName(), entity); - } - } else { - logger.debugf("Property %s not known for entity %s", modelProperty.getName(), entity); - } - } - - logger.debugf("Entity properties for manual setup: %s", entityPropsCopy.keySet()); - } - - protected Class getModelClass(Object model) { - Class modelClass = model.getClass(); - Class[] interfaces = modelClass.getInterfaces(); - - // Bit unsafe, but looks that it works for all "model adapters" so far - if (interfaces.length == 0) { - return modelClass; - } else { - return interfaces[0]; - } - } - - public static class NonEmptyGetterCriteria implements PropertyCriteria { - - private static final List IGNORED_METHODS = Arrays.asList("getPasswordPolicy", "getAuthenticationProviders", "getAuthenticationLink"); - - @Override - public boolean methodMatches(Method m) { - // Ignore non-empty getters - if (m.getParameterTypes().length > 0) { - return false; - } - - // Ignore some "known" getters (for example incompatible types between model and entity) - if (IGNORED_METHODS.contains(m.getName())) { - return false; - } - - return true; - } - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java deleted file mode 100644 index c43d3c5233..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ExportImportProviderImpl.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.keycloak.exportimport; - -import org.jboss.logging.Logger; -import org.keycloak.exportimport.io.ExportImportIOProvider; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.exportimport.io.ImportReader; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.KeycloakTransaction; -import org.keycloak.util.ProviderLoader; - -/** - * @author Marek Posolda - */ -public class ExportImportProviderImpl { - - private static final Logger logger = Logger.getLogger(ExportImportProviderImpl.class); - - public static final String ACTION_EXPORT = "export"; - public static final String ACTION_IMPORT = "import"; - - public void checkExportImport(KeycloakSessionFactory sessionFactory) { - String exportImportAction = ExportImportConfig.getAction(); - - boolean export = false; - boolean importt = false; - if (ACTION_EXPORT.equals(exportImportAction)) { - logger.infof("Full model export requested"); - export = true; - } else if (ACTION_IMPORT.equals(exportImportAction)) { - logger.infof("Full model import requested"); - importt = true; - } - - if (export || importt) { - KeycloakSession session = sessionFactory.create(); - KeycloakTransaction transaction = session.getTransaction(); - try { - transaction.begin(); - - if (export) { - ExportWriter exportWriter = getProvider().getExportWriter(); - new ModelExporter().exportModel(session.model(), exportWriter); - logger.infof("Export finished successfully"); - } else { - ImportReader importReader = getProvider().getImportReader(); - new ModelImporter().importModel(session.model(), importReader); - logger.infof("Import finished successfully"); - } - - if (transaction.isActive()) { - if (transaction.getRollbackOnly()) { - transaction.rollback(); - } else { - transaction.commit(); - } - } - } catch (Exception e) { - if (transaction.isActive()) { - session.getTransaction().rollback(); - } - throw new RuntimeException(e); - } finally { - session.close(); - } - } - } - - private ExportImportIOProvider getProvider() { - String providerId = ExportImportConfig.getProvider(); - logger.infof("Requested migration provider: " + providerId); - - Iterable providers = ProviderLoader.load(ExportImportIOProvider.class); - for (ExportImportIOProvider provider : providers) { - if (providerId.equals(provider.getId())) { - return provider; - } - } - - throw new IllegalStateException("Provider " + providerId + " not found"); - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java deleted file mode 100755 index 2b47bcec6c..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelExporter.java +++ /dev/null @@ -1,335 +0,0 @@ -package org.keycloak.exportimport; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.jboss.logging.Logger; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.AuthenticationLinkModel; -import org.keycloak.models.AuthenticationProviderModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelProvider; -import org.keycloak.models.OAuthClientModel; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RequiredCredentialModel; -import org.keycloak.models.RoleContainerModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.SocialLinkModel; -import org.keycloak.models.UserCredentialValueModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UsernameLoginFailureModel; -import org.keycloak.models.entities.ApplicationEntity; -import org.keycloak.models.entities.AuthenticationLinkEntity; -import org.keycloak.models.entities.AuthenticationProviderEntity; -import org.keycloak.models.entities.CredentialEntity; -import org.keycloak.models.entities.OAuthClientEntity; -import org.keycloak.models.entities.RealmEntity; -import org.keycloak.models.entities.RequiredCredentialEntity; -import org.keycloak.models.entities.RoleEntity; -import org.keycloak.models.entities.SocialLinkEntity; -import org.keycloak.models.entities.UserEntity; -import org.keycloak.models.entities.UsernameLoginFailureEntity; - -/** - * @author Marek Posolda - */ -public class ModelExporter { - - private static final Logger logger = Logger.getLogger(ModelExporter.class); - - private ExportWriter exportWriter; - private ExportImportPropertiesManager propertiesManager; - - public void exportModel(ModelProvider model, ExportWriter exportWriter) { - // Initialize needed objects - this.exportWriter = exportWriter; - this.propertiesManager = new ExportImportPropertiesManager(); - - // Create separate files for "realms", "applications", "oauthClients", "roles" and finally "users". Users may be done in more files (pagination) - exportRealms(model, "realms.json"); - exportApplications(model, "applications.json"); - exportOAuthClients(model, "oauthClients.json"); - exportRoles(model, "roles.json"); - exportUsers(model, "users.json"); -// exportUserFailures(model, "userFailures.json"); - - this.exportWriter.closeExportWriter(); - } - - protected void exportRealms(ModelProvider model, String fileName) { - List realms = model.getRealms(); - - // Convert models to entities, which will be written into JSON file - List result = new LinkedList(); - for (RealmModel realmModel : realms) { - RealmEntity entity = new RealmEntity(); - entity.setId(realmModel.getId()); - result.add(entity); - - // Export all basic properties from realm - this.propertiesManager.setBasicPropertiesFromModel(realmModel, entity); - - // Export 'advanced' properties - ApplicationModel realmAdminApp = realmModel.getMasterAdminApp(); - if (realmAdminApp != null) { - entity.setAdminAppId(realmAdminApp.getId()); - } - entity.setDefaultRoles(realmModel.getDefaultRoles()); - - List reqCredEntities = new ArrayList(); - List requiredCredModels = realmModel.getRequiredCredentials(); - for (RequiredCredentialModel requiredCredModel : requiredCredModels) { - RequiredCredentialEntity reqCredEntity = new RequiredCredentialEntity(); - this.propertiesManager.setBasicPropertiesFromModel(requiredCredModel, reqCredEntity); - reqCredEntities.add(reqCredEntity); - } - entity.setRequiredCredentials(reqCredEntities); - - // password policy - entity.setPasswordPolicy(realmModel.getPasswordPolicy().toString()); - - // authentication providers - List authProviderEntities = new ArrayList(); - for (AuthenticationProviderModel authProvider : realmModel.getAuthenticationProviders()) { - AuthenticationProviderEntity authProviderEntity = new AuthenticationProviderEntity(); - this.propertiesManager.setBasicPropertiesFromModel(authProvider, authProviderEntity); - authProviderEntities.add(authProviderEntity); - - } - entity.setAuthenticationProviders(authProviderEntities); - } - - this.exportWriter.writeEntities(fileName, result); - logger.infof("Realms exported: " + result); - } - - protected void exportApplications(ModelProvider model, String fileName) { - List allApplications = getAllApplications(model); - - List result = new LinkedList(); - for (ApplicationModel appModel : allApplications) { - ApplicationEntity appEntity = new ApplicationEntity(); - appEntity.setId(appModel.getId()); - result.add(appEntity); - - this.propertiesManager.setBasicPropertiesFromModel(appModel, appEntity); - - // Export 'advanced' properties of application - appEntity.setRealmId(appModel.getRealm().getId()); - appEntity.setDefaultRoles(appModel.getDefaultRoles()); - - List scopeIds = getScopeIds(appModel); - appEntity.setScopeIds(scopeIds); - } - - this.exportWriter.writeEntities(fileName, result); - logger.infof("Applications exported: " + result); - } - - protected void exportOAuthClients(ModelProvider model, String fileName) { - List realms = model.getRealms(); - List allClients = new ArrayList(); - for (RealmModel realmModel : realms) { - allClients.addAll(realmModel.getOAuthClients()); - } - - List result = new LinkedList(); - for (OAuthClientModel clientModel : allClients) { - OAuthClientEntity clientEntity = new OAuthClientEntity(); - clientEntity.setId(clientModel.getId()); - result.add(clientEntity); - - this.propertiesManager.setBasicPropertiesFromModel(clientModel, clientEntity); - - // Export 'advanced' properties of client - clientEntity.setName(clientModel.getClientId()); - clientEntity.setRealmId(clientModel.getRealm().getId()); - - List scopeIds = getScopeIds(clientModel); - clientEntity.setScopeIds(scopeIds); - } - - this.exportWriter.writeEntities(fileName, result); - logger.infof("OAuth clients exported: " + result); - } - - protected void exportRoles(ModelProvider model, String fileName) { - List allRoles = getAllRoles(model); - - List result = new LinkedList(); - for (RoleModel roleModel : allRoles) { - RoleEntity roleEntity = new RoleEntity(); - roleEntity.setId(roleModel.getId()); - result.add(roleEntity); - - roleEntity.setName(roleModel.getName()); - roleEntity.setDescription(roleModel.getDescription()); - - RoleContainerModel roleContainer = roleModel.getContainer(); - if (roleContainer instanceof RealmModel) { - RealmModel realm = (RealmModel)roleContainer; - roleEntity.setRealmId(realm.getId()); - } else { - ApplicationModel appModel = (ApplicationModel)roleContainer; - roleEntity.setApplicationId(appModel.getId()); - } - - List compositeRolesIds = null; - for (RoleModel composite : roleModel.getComposites()) { - - // Lazy init - if (compositeRolesIds == null) { - compositeRolesIds = new ArrayList(); - } - - compositeRolesIds.add(composite.getId()); - } - roleEntity.setCompositeRoleIds(compositeRolesIds); - } - - this.exportWriter.writeEntities(fileName, result); - - logger.infof("%d roles exported: ", result.size()); - if (logger.isDebugEnabled()) { - logger.debug("Exported roles: " + result); - } - } - - protected void exportUsers(ModelProvider model, String fileName) { - List realms = model.getRealms(); - List result = new LinkedList(); - - for (RealmModel realm : realms) { - List userModels = realm.getUsers(); - for (UserModel userModel : userModels) { - UserEntity userEntity = new UserEntity(); - userEntity.setId(userModel.getId()); - result.add(userEntity); - - this.propertiesManager.setBasicPropertiesFromModel(userModel, userEntity); - - userEntity.setUsername(userModel.getUsername()); - userEntity.setRealmId(realm.getId()); - - // authentication links - AuthenticationLinkModel authLink = userModel.getAuthenticationLink(); - if (authLink != null) { - AuthenticationLinkEntity authLinkEntity = new AuthenticationLinkEntity(); - this.propertiesManager.setBasicPropertiesFromModel(authLink, authLinkEntity); - - userEntity.setAuthenticationLink(authLinkEntity); - } - - // social links - Set socialLinks = realm.getSocialLinks(userModel); - if (socialLinks != null && !socialLinks.isEmpty()) { - List socialLinkEntities = new ArrayList(); - for (SocialLinkModel socialLink : socialLinks) { - SocialLinkEntity socialLinkEntity = new SocialLinkEntity(); - this.propertiesManager.setBasicPropertiesFromModel(socialLink, socialLinkEntity); - - socialLinkEntities.add(socialLinkEntity); - } - - userEntity.setSocialLinks(socialLinkEntities); - } - - // required actions - Set requiredActions = userModel.getRequiredActions(); - if (requiredActions != null && !requiredActions.isEmpty()) { - userEntity.setRequiredActions(new ArrayList(requiredActions)); - } - - // attributes - userEntity.setAttributes(userModel.getAttributes()); - - // roleIds - Set roles = userModel.getRoleMappings(); - List roleIds = new ArrayList(); - for (RoleModel role : roles) { - roleIds.add(role.getId()); - } - userEntity.setRoleIds(roleIds); - - // credentials - List credentials = userModel.getCredentialsDirectly(); - List credEntities = new ArrayList(); - for (UserCredentialValueModel credModel : credentials) { - CredentialEntity credEntity = new CredentialEntity(); - this.propertiesManager.setBasicPropertiesFromModel(credModel, credEntity); - credEntities.add(credEntity); - } - - userEntity.setCredentials(credEntities); - } - } - - this.exportWriter.writeEntities(fileName, result); - - logger.infof("%d users exported: ", result.size()); - if (logger.isDebugEnabled()) { - logger.debug("Exported users: " + result); - } - } - - - // Does it makes sense to export user failures ? -// protected void exportUserFailures(ModelProvider model, String fileName) { -// List realms = model.getRealms(); -// List allFailures = new ArrayList(); -// for (RealmModel realmModel : realms) { -// allFailures.addAll(realmModel.getAllUserLoginFailures()); -// } -// -// List result = new LinkedList(); -// for (UsernameLoginFailureModel failureModel : allFailures) { -// UsernameLoginFailureEntity failureEntity = new UsernameLoginFailureEntity(); -// this.propertiesManager.setBasicPropertiesFromModel(failureModel, failureEntity); -// result.add(failureEntity); -// -// failureEntity.setUsername(failureModel.getUsername()); -// failureEntity.setNumFailures(failureModel.getNumFailures()); -// } -// -// this.exportWriter.writeEntities(fileName, result); -// } - - private List getScopeIds(ClientModel clientModel) { - Set allScopes = clientModel.getScopeMappings(); - List scopeIds = new ArrayList(); - for (RoleModel role : allScopes) { - scopeIds.add(role.getId()); - } - return scopeIds; - } - - private List getAllApplications(ModelProvider model) { - List realms = model.getRealms(); - List allApplications = new ArrayList(); - for (RealmModel realmModel : realms) { - allApplications.addAll(realmModel.getApplications()); - } - return allApplications; - } - - private List getAllRoles(ModelProvider model) { - List allRoles = new ArrayList(); - - List realms = model.getRealms(); - for (RealmModel realmModel : realms) { - allRoles.addAll(realmModel.getRoles()); - } - - List allApplications = getAllApplications(model); - for (ApplicationModel appModel : allApplications) { - allRoles.addAll(appModel.getRoles()); - } - - return allRoles; - } - -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java deleted file mode 100755 index 35371b44f0..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/ModelImporter.java +++ /dev/null @@ -1,327 +0,0 @@ -package org.keycloak.exportimport; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jboss.logging.Logger; -import org.keycloak.exportimport.io.ImportReader; -import org.keycloak.models.ApplicationModel; -import org.keycloak.models.AuthenticationLinkModel; -import org.keycloak.models.AuthenticationProviderModel; -import org.keycloak.models.ClientModel; -import org.keycloak.Config; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelProvider; -import org.keycloak.models.OAuthClientModel; -import org.keycloak.models.PasswordPolicy; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleContainerModel; -import org.keycloak.models.RoleModel; -import org.keycloak.models.SocialLinkModel; -import org.keycloak.models.UserCredentialValueModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.UsernameLoginFailureModel; -import org.keycloak.models.entities.ApplicationEntity; -import org.keycloak.models.entities.AuthenticationLinkEntity; -import org.keycloak.models.entities.AuthenticationProviderEntity; -import org.keycloak.models.entities.ClientEntity; -import org.keycloak.models.entities.CredentialEntity; -import org.keycloak.models.entities.OAuthClientEntity; -import org.keycloak.models.entities.RealmEntity; -import org.keycloak.models.entities.RequiredCredentialEntity; -import org.keycloak.models.entities.RoleEntity; -import org.keycloak.models.entities.SocialLinkEntity; -import org.keycloak.models.entities.UserEntity; -import org.keycloak.models.entities.UsernameLoginFailureEntity; - -/** - * @author Marek Posolda - */ -public class ModelImporter { - - private static final Logger logger = Logger.getLogger(ModelImporter.class); - - private ImportReader importReader; - private ExportImportPropertiesManager propertiesManager; - - public void importModel(ModelProvider model, ImportReader importReader) { - // Initialize needed objects - this.importReader = importReader; - this.propertiesManager = new ExportImportPropertiesManager(); - - importRealms(model, "realms.json"); - importApplications(model, "applications.json"); - importRoles(model, "roles.json"); - - // Now we have all realms,applications and roles filled. So fill other objects (default roles, scopes etc) - importRealmsStep2(model, "realms.json"); - importApplicationsStep2(model, "applications.json"); - - importOAuthClients(model, "oauthClients.json"); - importUsers(model, "users.json"); -// importUserFailures(model, "userFailures.json"); - - this.importReader.closeImportReader(); - } - - protected void importRealms(ModelProvider model, String fileName) { - List realms = this.importReader.readEntities(fileName, RealmEntity.class); - - for (RealmEntity realmEntity : realms) { - RealmModel realm = model.createRealm(realmEntity.getId(), realmEntity.getName()); - - this.propertiesManager.setBasicPropertiesToModel(realm, realmEntity); - - Set reqCredModels = new HashSet(); - for (RequiredCredentialEntity requiredCredEntity : realmEntity.getRequiredCredentials()) { - reqCredModels.add(requiredCredEntity.getType()); - } - realm.updateRequiredCredentials(reqCredModels); - - // AdminApp and defaultRoles are set in step2 - - // password policy - realm.setPasswordPolicy(new PasswordPolicy(realmEntity.getPasswordPolicy())); - - // authentication providers - List authProviderModels = new ArrayList(); - for (AuthenticationProviderEntity authProviderEntity : realmEntity.getAuthenticationProviders()) { - AuthenticationProviderModel authProvider = new AuthenticationProviderModel(); - this.propertiesManager.setBasicPropertiesToModel(authProvider, authProviderEntity); - authProviderModels.add(authProvider); - - } - realm.setAuthenticationProviders(authProviderModels); - } - - logger.infof("Realms imported: " + realms); - } - - protected void importApplications(ModelProvider model, String fileName) { - List apps = this.importReader.readEntities(fileName, ApplicationEntity.class); - for (ApplicationEntity appEntity : apps) { - RealmModel realm = model.getRealm(appEntity.getRealmId()); - ApplicationModel app = realm.addApplication(appEntity.getId(), appEntity.getName()); - - this.propertiesManager.setBasicPropertiesToModel(app , appEntity); - - // scopeIds and default roles will be done in step2 - } - - logger.infof("Applications imported: " + apps); - } - - protected void importRoles(ModelProvider model, String fileName) { - // helper map for composite roles - Map rolesMap = new HashMap(); - - List roles = this.importReader.readEntities(fileName, RoleEntity.class); - for (RoleEntity roleEntity : roles) { - RoleModel role = null; - if (roleEntity.getRealmId() != null) { - RealmModel realm = model.getRealm(roleEntity.getRealmId()); - role = realm.addRole(roleEntity.getId(), roleEntity.getName()); - } else if (roleEntity.getApplicationId() != null) { - ApplicationModel app = findApplicationById(model, roleEntity.getApplicationId()); - role = app.addRole(roleEntity.getId(), roleEntity.getName()); - } else { - throw new IllegalStateException("Role " + roleEntity.getId() + " doesn't have realmId nor applicationId"); - } - - role.setDescription(roleEntity.getDescription()); - - rolesMap.put(roleEntity.getId(), roleEntity); - } - - // All roles were added. Fill composite roles now - for (RealmModel realm : model.getRealms()) { - - // realm roles - fillCompositeRoles(rolesMap, realm, realm); - - // app roles - for (ApplicationModel app : realm.getApplications()) { - fillCompositeRoles(rolesMap, app, realm); - } - } - - logger.infof("%d roles imported: ", roles.size()); - if (logger.isDebugEnabled()) { - logger.debug("Imported roles: " + roles); - } - } - - private void fillCompositeRoles(Map rolesMap, RoleContainerModel roleContainer, RealmModel realm) { - for (RoleModel role : roleContainer.getRoles()) { - RoleEntity roleEntity = rolesMap.get(role.getId()); - - if (roleEntity.getCompositeRoleIds() == null) { - continue; - } - - for (String compositeRoleId : roleEntity.getCompositeRoleIds()) { - RoleModel compositeRole = realm.getRoleById(compositeRoleId); - role.addCompositeRole(compositeRole); - } - } - } - - protected void importRealmsStep2(ModelProvider model, String fileName) { - List realms = this.importReader.readEntities(fileName, RealmEntity.class); - RealmModel adminRealm = model.getRealm(Config.getAdminRealm()); - - for (RealmEntity realmEntity : realms) { - RealmModel realm = model.getRealm(realmEntity.getId()); - - // admin app - String adminAppId = realmEntity.getAdminAppId(); - if (adminAppId != null) { - realm.setMasterAdminApp(adminRealm.getApplicationById(adminAppId)); - } - - // Default roles - realm.updateDefaultRoles(realmEntity.getDefaultRoles().toArray(new String[] {})); - } - } - - protected void importApplicationsStep2(ModelProvider model, String fileName) { - List apps = this.importReader.readEntities(fileName, ApplicationEntity.class); - for (ApplicationEntity appEntity : apps) { - RealmModel realm = model.getRealm(appEntity.getRealmId()); - ApplicationModel application = realm.getApplicationById(appEntity.getId()); - - // Default roles - application.updateDefaultRoles(appEntity.getDefaultRoles().toArray(new String[] {})); - - // Scopes - addScopes(realm, application, appEntity); - } - } - - private void addScopes(RealmModel realm, ClientModel client, ClientEntity clientEntity) { - for (String scopeId : clientEntity.getScopeIds()) { - RoleModel scope = realm.getRoleById(scopeId); - client.addScopeMapping(scope); - } - } - - protected void importOAuthClients(ModelProvider model, String fileName) { - List clients = this.importReader.readEntities(fileName, OAuthClientEntity.class); - for (OAuthClientEntity clientEntity : clients) { - RealmModel realm = model.getRealm(clientEntity.getRealmId()); - OAuthClientModel client = realm.addOAuthClient(clientEntity.getId(), clientEntity.getName()); - - this.propertiesManager.setBasicPropertiesToModel(client, clientEntity); - - client.setClientId(clientEntity.getName()); - - // Scopes. All roles are already added at this point - addScopes(realm, client, clientEntity); - } - - logger.info("OAuth clients imported: " + clients); - } - - protected ApplicationModel findApplicationById(ModelProvider model, String applicationId) { - for (RealmModel realm : model.getRealms()) { - ApplicationModel appModel = realm.getApplicationById(applicationId); - if (appModel != null) { - return appModel; - } - } - - return null; - } - - public void importUsers(ModelProvider model, String fileName) { - List users = this.importReader.readEntities(fileName, UserEntity.class); - for (UserEntity userEntity : users) { - RealmModel realm = model.getRealm(userEntity.getRealmId()); - UserModel user = realm.addUser(userEntity.getId(), userEntity.getUsername(), false); - - // We need to remove defaultRoles here as realm.addUser is automatically adding them. We may add them later during roles mapping processing - for (RoleModel role : user.getRoleMappings()) { - user.deleteRoleMapping(role); - } - - this.propertiesManager.setBasicPropertiesToModel(user, userEntity); - - // authentication links - AuthenticationLinkEntity authLinkEntity = userEntity.getAuthenticationLink(); - if (authLinkEntity != null) { - AuthenticationLinkModel authLinkModel = new AuthenticationLinkModel(); - this.propertiesManager.setBasicPropertiesToModel(authLinkModel, authLinkEntity); - - user.setAuthenticationLink(authLinkModel); - } - - // social links - List socialLinks = userEntity.getSocialLinks(); - if (socialLinks != null && !socialLinks.isEmpty()) { - for (SocialLinkEntity socialLinkEntity : socialLinks) { - SocialLinkModel socialLink = new SocialLinkModel(); - this.propertiesManager.setBasicPropertiesToModel(socialLink, socialLinkEntity); - - realm.addSocialLink(user, socialLink); - } - } - - // required actions - List requiredActions = userEntity.getRequiredActions(); - if (requiredActions != null && !requiredActions.isEmpty()) { - for (UserModel.RequiredAction reqAction : requiredActions) { - user.addRequiredAction(reqAction); - } - } - - // attributes - if (userEntity.getAttributes() != null) { - for (Map.Entry attr : userEntity.getAttributes().entrySet()) { - user.setAttribute(attr.getKey(), attr.getValue()); - } - } - - // roles - if (userEntity.getRoleIds() != null) { - for (String roleId : userEntity.getRoleIds()) { - RoleModel role = realm.getRoleById(roleId); - user.grantRole(role); - } - } - - // credentials - List credentials = userEntity.getCredentials(); - if (credentials != null) { - for (CredentialEntity credEntity : credentials) { - UserCredentialValueModel credModel = new UserCredentialValueModel(); - this.propertiesManager.setBasicPropertiesToModel(credModel, credEntity); - - user.updateCredentialDirectly(credModel); - } - } - } - - logger.infof("%d users imported: ", users.size()); - if (logger.isDebugEnabled()) { - logger.debug("Imported users: " + users); - } - } - -// public void importUserFailures(ModelProvider model, String fileName) { -// List userFailures = this.importReader.readEntities(fileName, UsernameLoginFailureEntity.class); -// for (UsernameLoginFailureEntity entity : userFailures) { -// RealmModel realm = model.getRealm(entity.getRealmId()); -// UsernameLoginFailureModel loginFailureModel = realm.addUserLoginFailure(entity.getUsername()); -// -// this.propertiesManager.setBasicPropertiesToModel(loginFailureModel , entity); -// -// for (int i=0 ; iMarek Posolda - */ -public interface ExportImportIOProvider { - - String getId(); - - ExportWriter getExportWriter(); - - ImportReader getImportReader(); - -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ExportWriter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ExportWriter.java deleted file mode 100644 index c90a57f794..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ExportWriter.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.keycloak.exportimport.io; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public interface ExportWriter { - - void writeEntities(String fileName, List entities); - - void closeExportWriter(); -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ImportReader.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ImportReader.java deleted file mode 100644 index 83faabd3cc..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/ImportReader.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.keycloak.exportimport.io; - -import java.util.List; - -/** - * @author Marek Posolda - */ -public interface ImportReader { - - List readEntities(String fileName, Class entityClass); - - void closeImportReader(); -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportImportIOProvider.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportImportIOProvider.java deleted file mode 100644 index b785c4174a..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportImportIOProvider.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.keycloak.exportimport.io.directory; - -import org.keycloak.exportimport.ExportImportConfig; -import org.keycloak.exportimport.io.ExportImportIOProvider; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.exportimport.io.ImportReader; - -import java.io.File; - -/** - * Export/import into JSON files inside "tmp" directory. This implementation is used mainly for testing - * (shouldn't be used in production due to passwords in JSON files) - * - * @author Marek Posolda - */ -public class TmpDirExportImportIOProvider implements ExportImportIOProvider { - - public static final String PROVIDER_ID = "dir"; - - @Override - public ExportWriter getExportWriter() { - String dir = ExportImportConfig.getDir(); - return dir!=null ? new TmpDirExportWriter(new File(dir)) : new TmpDirExportWriter(); - } - - @Override - public ImportReader getImportReader() { - String dir = ExportImportConfig.getDir(); - return dir!=null ? new TmpDirImportReader(new File(dir)) : new TmpDirImportReader(); - } - - @Override - public String getId() { - return PROVIDER_ID; - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportWriter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportWriter.java deleted file mode 100644 index d1ee454128..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirExportWriter.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.keycloak.exportimport.io.directory; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; - -import org.codehaus.jackson.map.ObjectMapper; -import org.jboss.logging.Logger; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.util.JsonSerialization; - -/** - * @author Marek Posolda - */ -public class TmpDirExportWriter implements ExportWriter { - - private static final Logger logger = Logger.getLogger(TmpDirExportWriter.class); - - private final ObjectMapper objectMapper; - private final File rootDirectory; - - public TmpDirExportWriter() { - // Determine system tmp directory - String tempDir = System.getProperty("java.io.tmpdir"); - - // Delete and recreate directory inside tmp - this.rootDirectory = new File(tempDir + "/keycloak-export"); - if (this.rootDirectory .exists()) { - recursiveDeleteDir(this.rootDirectory ); - } - this.rootDirectory.mkdirs(); - - logger.infof("Exporting into directory %s", this.rootDirectory.getAbsolutePath()); - this.objectMapper = getObjectMapper(); - } - - public TmpDirExportWriter(File rootDirectory) { - this.rootDirectory = rootDirectory; - this.rootDirectory.mkdirs(); - this.objectMapper = getObjectMapper(); - - logger.infof("Exporting into directory %s", this.rootDirectory.getAbsolutePath()); - } - - private ObjectMapper getObjectMapper() { - return JsonSerialization.prettyMapper; - } - - protected boolean recursiveDeleteDir(File dirPath) { - if (dirPath.exists()) { - File[] files = dirPath.listFiles(); - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { - recursiveDeleteDir(files[i]); - } else { - files[i].delete(); - } - } - } - if (dirPath.exists()) - return dirPath.delete(); - else - return true; - } - - @Override - public void writeEntities(String fileName, List entities) { - try { - File file = new File(this.rootDirectory, fileName); - FileOutputStream stream = new FileOutputStream(file); - this.objectMapper.writeValue(stream, entities); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public void closeExportWriter() { - //To change body of implemented methods use File | Settings | File Templates. - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirImportReader.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirImportReader.java deleted file mode 100644 index 942e23a93b..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/directory/TmpDirImportReader.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.keycloak.exportimport.io.directory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.List; - -import org.codehaus.jackson.map.ObjectMapper; -import org.jboss.logging.Logger; -import org.keycloak.exportimport.io.ImportReader; -import org.keycloak.util.JsonSerialization; - -/** - * @author Marek Posolda - */ -public class TmpDirImportReader implements ImportReader { - - private static final Logger logger = Logger.getLogger(TmpDirImportReader.class); - - private final ObjectMapper objectMapper; - private final File rootDirectory; - - public TmpDirImportReader() { - // Determine system tmp directory - String tempDir = System.getProperty("java.io.tmpdir"); - - // Delete and recreate directory inside tmp - this.rootDirectory = new File(tempDir + "/keycloak-export"); - if (!this.rootDirectory .exists()) { - throw new IllegalStateException("Directory " + this.rootDirectory + " doesn't exists"); - } - - logger.infof("Importing from directory %s", this.rootDirectory.getAbsolutePath()); - this.objectMapper = getObjectMapper(); - } - - public TmpDirImportReader(File rootDirectory) { - this.rootDirectory = rootDirectory; - this.objectMapper = getObjectMapper(); - - logger.infof("Importing from directory %s", this.rootDirectory.getAbsolutePath()); - } - - private ObjectMapper getObjectMapper() { - return JsonSerialization.prettyMapper; - } - - @Override - public List readEntities(String fileName, Class entityClass) { - try { - File file = new File(this.rootDirectory, fileName); - FileInputStream stream = new FileInputStream(file); - T[] template = (T[]) Array.newInstance(entityClass, 0); - T[] result = (T[])this.objectMapper.readValue(stream, template.getClass()); - return Arrays.asList(result); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public void closeImportReader() { - //TODO: Should directory be deleted after import? - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPExportWriter.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPExportWriter.java deleted file mode 100644 index 0b49940b84..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPExportWriter.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.keycloak.exportimport.io.zip; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.List; - -import de.idyl.winzipaes.AesZipFileEncrypter; -import de.idyl.winzipaes.impl.AESEncrypter; -import de.idyl.winzipaes.impl.AESEncrypterBC; -import org.codehaus.jackson.map.ObjectMapper; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.util.JsonSerialization; - -/** - * @author Marek Posolda - */ -public class EncryptedZIPExportWriter implements ExportWriter { - - private final File zipFile; - private final ObjectMapper objectMapper; - private final String password; - - private final AesZipFileEncrypter encrypter; - - - public EncryptedZIPExportWriter(String zipFileName, String password) { - try { - this.zipFile = new File(zipFileName); - if (zipFile.exists()) { - throw new IllegalStateException("File " + zipFileName + " already exists"); - } - - this.objectMapper = JsonSerialization.mapper; - - AESEncrypter encrypter = new AESEncrypterBC(); - this.encrypter = new AesZipFileEncrypter(this.zipFile, encrypter); - this.password = password; - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public void writeEntities(String fileName, List entities) { - try { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - this.objectMapper.writeValue(stream, entities); - - byte[] byteArray = stream.toByteArray(); - this.encrypter.add(fileName, new ByteArrayInputStream(byteArray), this.password); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public void closeExportWriter() { - try { - this.encrypter.close(); - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPIOProvider.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPIOProvider.java deleted file mode 100644 index 31883acb14..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPIOProvider.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.keycloak.exportimport.io.zip; - -import org.jboss.logging.Logger; -import org.keycloak.exportimport.ExportImportConfig; -import org.keycloak.exportimport.io.ExportImportIOProvider; -import org.keycloak.exportimport.io.ExportWriter; -import org.keycloak.exportimport.io.ImportReader; - -/** - * @author Marek Posolda - */ -public class EncryptedZIPIOProvider implements ExportImportIOProvider { - - private static final Logger logger = Logger.getLogger(EncryptedZIPIOProvider.class); - - public static final String PROVIDER_ID = "zip"; - - @Override - public String getId() { - return PROVIDER_ID; - } - - @Override - public ExportWriter getExportWriter() { - String zipFile = ExportImportConfig.getZipFile(); - String zipPassword = ExportImportConfig.getZipPassword(); - logger.infof("Using zip for export: " + zipFile); - - if (zipFile==null || zipPassword==null) { - throw new IllegalArgumentException("zipFile or zipPassword are null"); - } - - return new EncryptedZIPExportWriter(zipFile, zipPassword); - } - - @Override - public ImportReader getImportReader() { - String zipFile = ExportImportConfig.getZipFile(); - String zipPassword = ExportImportConfig.getZipPassword(); - logger.infof("Using zip for import: " + zipFile); - - if (zipFile==null || zipPassword==null) { - throw new IllegalArgumentException("zipFile or zipPassword are null"); - } - - return new EncryptedZIPImportReader(zipFile, zipPassword); - } -} diff --git a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPImportReader.java b/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPImportReader.java deleted file mode 100644 index d115b7d6e9..0000000000 --- a/export-import/export-import-impl/src/main/java/org/keycloak/exportimport/io/zip/EncryptedZIPImportReader.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.keycloak.exportimport.io.zip; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.List; - -import de.idyl.winzipaes.AesZipFileDecrypter; -import de.idyl.winzipaes.impl.AESDecrypter; -import de.idyl.winzipaes.impl.AESDecrypterBC; -import org.codehaus.jackson.map.ObjectMapper; -import org.keycloak.exportimport.io.ImportReader; -import org.keycloak.util.JsonSerialization; - -/** - * @author Marek Posolda - */ -public class EncryptedZIPImportReader implements ImportReader { - - private final File zipFile; - private final ObjectMapper objectMapper; - private final String password; - - private final AesZipFileDecrypter decrypter; - - - public EncryptedZIPImportReader(String zipFileName, String password) { - try { - this.zipFile = new File(zipFileName); - if (!zipFile.exists()) { - throw new IllegalStateException("File " + zipFileName + " doesn't exists"); - } - - this.objectMapper = JsonSerialization.mapper; - - AESDecrypter decrypter = new AESDecrypterBC(); - this.decrypter = new AesZipFileDecrypter(this.zipFile, decrypter); - this.password = password; - } catch (IOException ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public List readEntities(String fileName, Class entityClass) { - try { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - this.decrypter.extractEntry(this.decrypter.getEntry(fileName), bos, this.password); - - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - T[] template = (T[]) Array.newInstance(entityClass, 0); - T[] result = (T[])this.objectMapper.readValue(bis, template.getClass()); - return Arrays.asList(result); - } catch (Exception ioe) { - throw new RuntimeException(ioe); - } - } - - @Override - public void closeImportReader() { - try { - this.decrypter.close(); - } catch (Exception ioe) { - throw new RuntimeException(ioe); - } - } -} diff --git a/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportImportProvider b/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportImportProvider deleted file mode 100644 index 353987ffb8..0000000000 --- a/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.ExportImportProvider +++ /dev/null @@ -1 +0,0 @@ -org.keycloak.exportimport.ExportImportProviderImpl diff --git a/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.io.ExportImportIOProvider b/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.io.ExportImportIOProvider deleted file mode 100644 index 75c97ec96b..0000000000 --- a/export-import/export-import-impl/src/main/resources/META-INF/services/org.keycloak.exportimport.io.ExportImportIOProvider +++ /dev/null @@ -1,2 +0,0 @@ -org.keycloak.exportimport.io.directory.TmpDirExportImportIOProvider -org.keycloak.exportimport.io.zip.EncryptedZIPIOProvider diff --git a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/JPAToMongoExportImportTest.java b/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/JPAToMongoExportImportTest.java deleted file mode 100644 index 32be243a71..0000000000 --- a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/JPAToMongoExportImportTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.exportimport; - -import org.junit.Ignore; -import org.keycloak.exportimport.io.directory.TmpDirExportImportIOProvider; -import org.keycloak.models.KeycloakSessionFactory; - -/** - * Test for full export of data from JPA and import them to Mongo. Using "directory" provider - * - * @author Marek Posolda - */ -@Ignore -public class JPAToMongoExportImportTest { -} diff --git a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/MongoToJPAExportImportTest.java b/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/MongoToJPAExportImportTest.java deleted file mode 100644 index 686722a29c..0000000000 --- a/export-import/export-import-impl/src/test/java/org/keycloak/exportimport/MongoToJPAExportImportTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.keycloak.exportimport; - -import org.junit.Assert; -import org.junit.Ignore; -import org.keycloak.exportimport.io.zip.EncryptedZIPIOProvider; -import org.keycloak.models.KeycloakSessionFactory; - -import java.io.File; - -/** - * Test for full export of data from Mongo and import them to JPA. Using export into encrypted ZIP and import from it - * - * @author Marek Posolda - */ -@Ignore -public class MongoToJPAExportImportTest { -} diff --git a/export-import/pom.xml b/export-import/pom.xml index 15d39f6a36..72468fad73 100755 --- a/export-import/pom.xml +++ b/export-import/pom.xml @@ -16,7 +16,6 @@ export-import-api - export-import-impl export-import-dir export-import-single-file export-import-zip diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java index d1167440bc..edc79e2a29 100755 --- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java +++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/DefaultCacheModelProvider.java @@ -266,9 +266,23 @@ public class DefaultCacheModelProvider implements CacheModelProvider { @Override public boolean removeRealm(String id) { cache.invalidateCachedRealmById(id); + + RealmModel realm = getDelegate().getRealm(id); + Set realmRoles = null; + if (realm != null) { + realmRoles = realm.getRoles(); + } + boolean didIt = getDelegate().removeRealm(id); realmInvalidations.add(id); + // TODO: Temporary workaround to invalidate cached realm roles + if (didIt && realmRoles != null) { + for (RoleModel role : realmRoles) { + roleInvalidations.add(role.getId()); + } + } + return didIt; } diff --git a/project-integrations/aerogear-ups/auth-server/pom.xml b/project-integrations/aerogear-ups/auth-server/pom.xml index 2ea0015550..a68969721b 100755 --- a/project-integrations/aerogear-ups/auth-server/pom.xml +++ b/project-integrations/aerogear-ups/auth-server/pom.xml @@ -167,7 +167,12 @@ org.keycloak - keycloak-export-import-impl + keycloak-export-import-dir + ${project.version} + + + org.keycloak + keycloak-export-import-single-file ${project.version} diff --git a/server/pom.xml b/server/pom.xml index a086cee071..7ab2cbb6a1 100755 --- a/server/pom.xml +++ b/server/pom.xml @@ -284,7 +284,17 @@ org.keycloak - keycloak-export-import-impl + keycloak-export-import-dir + ${project.version} + + + org.keycloak + keycloak-export-import-zip + ${project.version} + + + org.keycloak + keycloak-export-import-single-file ${project.version} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java index 20b5f09fef..a3e9df90ef 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/exportimport/ExportImportTest.java @@ -5,8 +5,6 @@ import java.util.Properties; import org.junit.Assert; import org.junit.ClassRule; -import org.junit.FixMethodOrder; -import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExternalResource; import org.junit.rules.RuleChain; @@ -25,7 +23,6 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.rule.KeycloakRule; -import org.keycloak.testutils.KeycloakServer; /** * @author Marek Posolda @@ -39,7 +36,7 @@ public class ExportImportTest { @Override protected void before() throws Throwable { - if (System.getProperty("hibernate.connection.url") == null) { + if (System.getProperty("hibernate.connection.url") == null) { String baseExportImportDir = getExportImportTestDirectory(); File oldDBFile = new File(baseExportImportDir, "keycloakDB.h2.db"); @@ -64,6 +61,29 @@ public class ExportImportTest { } }; + // We want data to be persisted among server restarts + private static ExternalResource mongoRule = new ExternalResource() { + + private static final String MONGO_CLEAR_ON_STARTUP_PROP_NAME = "keycloak.model.mongo.clearOnStartup"; + private String previousMongoClearOnStartup; + + @Override + protected void before() throws Throwable { + previousMongoClearOnStartup = System.getProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME); + System.setProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME, "false"); + } + + @Override + protected void after() { + if (previousMongoClearOnStartup != null) { + System.setProperty(MONGO_CLEAR_ON_STARTUP_PROP_NAME, "false"); + } else { + System.getProperties().remove(MONGO_CLEAR_ON_STARTUP_PROP_NAME); + } + } + + }; + private static KeycloakRule keycloakRule = new KeycloakRule( new KeycloakRule.KeycloakSetup() { @Override @@ -79,9 +99,10 @@ public class ExportImportTest { @ClassRule public static TestRule chain = RuleChain .outerRule(hibernateSetupRule) + .around(mongoRule) .around(keycloakRule); - //@Test + @Test public void testDirFullExportImport() throws Throwable { ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); String targetDirPath = getExportImportTestDirectory() + File.separator + "dirExport"; @@ -95,7 +116,7 @@ public class ExportImportTest { Assert.assertEquals(4, new File(targetDirPath).listFiles().length); } - //@Test + @Test public void testDirRealmExportImport() throws Throwable { ExportImportConfig.setProvider(DirExportProviderFactory.PROVIDER_ID); String targetDirPath = getExportImportTestDirectory() + File.separator + "dirRealmExport"; @@ -118,7 +139,7 @@ public class ExportImportTest { testFullExportImport(); } - //@Test + @Test public void testSingleFileRealmExportImport() throws Throwable { ExportImportConfig.setProvider(SingleFileExportProviderFactory.PROVIDER_ID); String targetFilePath = getExportImportTestDirectory() + File.separator + "singleFile-realm.json"; @@ -127,7 +148,7 @@ public class ExportImportTest { testRealmExportImport(); } - //@Test + @Test public void testZipFullExportImport() throws Throwable { ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID); String zipFilePath = getExportImportTestDirectory() + File.separator + "export-full.zip"; @@ -139,7 +160,7 @@ public class ExportImportTest { testFullExportImport(); } - //@Test + @Test public void testZipRealmExportImport() throws Throwable { ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID); String zipFilePath = getExportImportTestDirectory() + File.separator + "export-realm.zip"; diff --git a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java index 8deadb718d..14a106cb48 100755 --- a/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java +++ b/testsuite/performance/src/test/java/org/keycloak/testsuite/performance/CreateRealmsWorker.java @@ -6,6 +6,7 @@ import org.apache.log.Logger; import org.keycloak.models.ApplicationModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; +import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.services.managers.RealmManager; @@ -77,9 +78,9 @@ public class CreateRealmsWorker implements Worker { // Add required credentials if (createRequiredCredentials) { - realmManager.addRequiredCredential(realm, CredentialRepresentation.PASSWORD); - realmManager.addRequiredCredential(realm, CredentialRepresentation.TOTP); - realmManager.addRequiredCredential(realm, CredentialRepresentation.CLIENT_CERT); + RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.PASSWORD); + RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.TOTP); + RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.CLIENT_CERT); } log.info("Finished creation of realm " + realmName); diff --git a/testsuite/tools/pom.xml b/testsuite/tools/pom.xml index c630624317..d3b9867de2 100755 --- a/testsuite/tools/pom.xml +++ b/testsuite/tools/pom.xml @@ -283,7 +283,17 @@ org.keycloak - keycloak-export-import-impl + keycloak-export-import-dir + ${project.version} + + + org.keycloak + keycloak-export-import-zip + ${project.version} + + + org.keycloak + keycloak-export-import-single-file ${project.version} diff --git a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java index 4077f6b58e..793c8c3323 100644 --- a/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java +++ b/testsuite/tools/src/main/java/org/keycloak/test/tools/PerfTools.java @@ -1,6 +1,7 @@ package org.keycloak.test.tools; import org.keycloak.exportimport.ExportImportConfig; +import org.keycloak.exportimport.ExportImportManager; import org.keycloak.exportimport.ExportProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; @@ -231,14 +232,7 @@ public class PerfTools { ExportImportConfig.setProvider("dir"); ExportImportConfig.setDir(dir); - Iterator providers = ProviderLoader.load(ExportProvider.class).iterator(); - - if (providers.hasNext()) { - ExportProvider exportImport = providers.next(); - exportImport.checkExportImport(sessionFactory); - } else { - throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); - } + new ExportImportManager().checkExportImport(sessionFactory); } public static class JobRepresentation {