From d5925b8ccfbfa3e42f3a0396fa60f233552e9b8f Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Wed, 23 Nov 2016 08:31:20 -0500 Subject: [PATCH] remove realm UserFed SPI methods --- .../admin/client/resource/RealmResource.java | 3 - .../models/cache/infinispan/RealmAdapter.java | 89 ---- .../cache/infinispan/UserCacheSession.java | 6 +- .../infinispan/entities/CachedRealm.java | 22 - .../org/keycloak/models/jpa/RealmAdapter.java | 300 ------------ .../mongo/keycloak/adapters/RealmAdapter.java | 302 ------------ .../migration/MigrationModelManager.java | 14 - .../migration/migrators/MigrateTo1_3_0.java | 99 ---- .../migration/migrators/MigrateTo1_4_0.java | 79 --- .../migration/migrators/MigrateTo1_8_0.java | 70 --- .../models/utils/KeycloakModelUtils.java | 22 - .../models/utils/ModelToRepresentation.java | 38 +- .../models/utils/RepresentationToModel.java | 47 -- .../org/keycloak/models/KeycloakSession.java | 2 +- .../java/org/keycloak/models/RealmModel.java | 15 - .../models/UserFederationManager.java | 209 +------- .../storage/user/ImportedUserValidation.java | 12 +- .../admin/ResourceSetService.java | 3 +- .../UserCredentialStoreManager.java | 46 +- .../exportimport/util/ExportUtils.java | 3 +- .../services/managers/RealmManager.java | 18 +- .../services/managers/UsersSyncManager.java | 327 ------------- .../resources/KeycloakApplication.java | 2 - .../resources/admin/RealmAdminResource.java | 18 +- .../admin/UserFederationProviderResource.java | 459 ------------------ .../UserFederationProvidersResource.java | 344 ------------- .../keycloak/storage/UserStorageManager.java | 32 +- ...igurableUserFederationProviderFactory.java | 62 --- .../federation/DummyUserFederationMapper.java | 140 ------ .../DummyUserFederationProvider.java | 91 ++-- .../DummyUserFederationProviderFactory.java | 37 +- .../rest/TestingResourceProvider.java | 6 +- ...ycloak.mappers.UserFederationMapperFactory | 52 -- ...cloak.models.UserFederationProviderFactory | 36 -- ...eycloak.storage.UserStorageProviderFactory | 1 + .../admin/UserStorageMapperTest.java | 1 - .../testsuite/admin/UserStorageRestTest.java | 2 +- .../testsuite/client/ClientRedirectTest.java | 2 +- .../org/keycloak/testsuite/sssd/SSSDTest.java | 7 - .../AbstractKeycloakIdentityProviderTest.java | 12 +- ...yncDummyUserFederationProviderFactory.java | 27 +- .../federation/sync/SyncFederationTest.java | 47 +- .../keycloak/testsuite/model/ImportTest.java | 10 +- .../model/UserFederationModelTest.java | 175 ------- .../SyncDummyFederationProviderCommand.java | 29 +- ...cloak.models.UserFederationProviderFactory | 18 - ...eycloak.storage.UserStorageProviderFactory | 1 + 47 files changed, 223 insertions(+), 3114 deletions(-) delete mode 100755 server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java delete mode 100755 server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_4_0.java delete mode 100644 server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_8_0.java delete mode 100755 services/src/main/java/org/keycloak/services/managers/UsersSyncManager.java delete mode 100755 services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java delete mode 100755 services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java delete mode 100644 testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyConfigurableUserFederationProviderFactory.java delete mode 100644 testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java delete mode 100644 testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory delete mode 100644 testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory create mode 100644 testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory delete mode 100755 testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java delete mode 100755 testsuite/integration/src/test/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java index b2594ae203..85e66899ff 100644 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RealmResource.java @@ -172,9 +172,6 @@ public interface RealmResource { @Path("attack-detection") AttackDetectionResource attackDetection(); - @Path("user-federation") - UserFederationProvidersResource userFederation(); - @Path("testLDAPConnection") @GET @NoCache diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java index 1748e3ca27..204c0ed316 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java @@ -634,38 +634,6 @@ public class RealmAdapter implements CachedRealmModel { updated.removeIdentityProviderByAlias(alias); } - @Override - public List getUserFederationProviders() { - if (isUpdated()) return updated.getUserFederationProviders(); - return cached.getUserFederationProviders(); - } - - @Override - public void setUserFederationProviders(List providers) { - getDelegateForUpdate(); - updated.setUserFederationProviders(providers); - } - - @Override - public UserFederationProviderModel addUserFederationProvider(String providerName, Map config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { - getDelegateForUpdate(); - return updated.addUserFederationProvider(providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync); - } - - @Override - public void removeUserFederationProvider(UserFederationProviderModel provider) { - getDelegateForUpdate(); - updated.removeUserFederationProvider(provider); - - } - - @Override - public void updateUserFederationProvider(UserFederationProviderModel provider) { - getDelegateForUpdate(); - updated.updateUserFederationProvider(provider); - - } - @Override public String getLoginTheme() { if (isUpdated()) return updated.getLoginTheme(); @@ -952,63 +920,6 @@ public class RealmAdapter implements CachedRealmModel { return null; } - @Override - public Set getUserFederationMappers() { - if (isUpdated()) return updated.getUserFederationMappers(); - return cached.getUserFederationMapperSet(); - } - - @Override - public Set getUserFederationMappersByFederationProvider(String federationProviderId) { - if (isUpdated()) return updated.getUserFederationMappersByFederationProvider(federationProviderId); - Set mappers = new HashSet<>(); - List list = cached.getUserFederationMappers().getList(federationProviderId); - for (UserFederationMapperModel entity : list) { - mappers.add(entity); - } - return Collections.unmodifiableSet(mappers); - } - - @Override - public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel mapper) { - getDelegateForUpdate(); - return updated.addUserFederationMapper(mapper); - } - - @Override - public void removeUserFederationMapper(UserFederationMapperModel mapper) { - getDelegateForUpdate(); - updated.removeUserFederationMapper(mapper); - } - - @Override - public void updateUserFederationMapper(UserFederationMapperModel mapper) { - getDelegateForUpdate(); - updated.updateUserFederationMapper(mapper); - } - - @Override - public UserFederationMapperModel getUserFederationMapperById(String id) { - if (isUpdated()) return updated.getUserFederationMapperById(id); - for (List models : cached.getUserFederationMappers().values()) { - for (UserFederationMapperModel model : models) { - if (model.getId().equals(id)) return model; - } - } - return null; - } - - @Override - public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) { - if (isUpdated()) return updated.getUserFederationMapperByName(federationProviderId, name); - List models = cached.getUserFederationMappers().getList(federationProviderId); - if (models == null) return null; - for (UserFederationMapperModel model : models) { - if (model.getName().equals(name)) return model; - } - return null; - } - @Override public AuthenticationFlowModel getBrowserFlow() { if (isUpdated()) return updated.getBrowserFlow(); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index cb8c0a84ec..0dd4d5d167 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -300,7 +300,7 @@ public class UserCacheSession implements UserCache { // its also hard to test stuff boolean invalidate = false; if (policy != null) { - String currentTime = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(Time.currentTimeMillis())); + //String currentTime = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(Time.currentTimeMillis())); if (policy == UserStorageProviderModel.CachePolicy.NO_CACHE) { invalidate = true; } else if (cached.getCacheTimestamp() < model.getCacheInvalidBefore()) { @@ -317,8 +317,8 @@ public class UserCacheSession implements UserCache { int oneWeek = 7 * 24 * 60 * 60 * 1000; long weeklyTimeout = weeklyTimeout(model.getEvictionDay(), model.getEvictionHour(), model.getEvictionMinute()); long lastTimeout = weeklyTimeout - oneWeek; - String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(weeklyTimeout)); - String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp())); + //String timeout = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(weeklyTimeout)); + //String stamp = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date(cached.getCacheTimestamp())); if (cached.getCacheTimestamp() <= lastTimeout) { invalidate = true; } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java index 5dd4bacaf7..48689e6b7d 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedRealm.java @@ -33,8 +33,6 @@ import org.keycloak.models.PasswordPolicy; import org.keycloak.models.RealmModel; import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RequiredCredentialModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; import java.security.PrivateKey; import java.security.PublicKey; @@ -96,12 +94,9 @@ public class CachedRealm extends AbstractExtendableRevisioned { protected String masterAdminClient; protected List requiredCredentials; - protected List userFederationProviders; protected MultivaluedHashMap componentsByParent = new MultivaluedHashMap<>(); protected MultivaluedHashMap componentsByParentAndType = new MultivaluedHashMap<>(); protected Map components = new HashMap<>(); - protected MultivaluedHashMap userFederationMappers = new MultivaluedHashMap(); - protected Set userFederationMapperSet; protected List identityProviders; protected Map browserSecurityHeaders; @@ -187,11 +182,6 @@ public class CachedRealm extends AbstractExtendableRevisioned { emailTheme = model.getEmailTheme(); requiredCredentials = model.getRequiredCredentials(); - userFederationProviders = model.getUserFederationProviders(); - userFederationMapperSet = model.getUserFederationMappers(); - for (UserFederationMapperModel mapper : userFederationMapperSet) { - this.userFederationMappers.add(mapper.getFederationProviderId(), mapper); - } this.identityProviders = new ArrayList<>(); @@ -462,14 +452,6 @@ public class CachedRealm extends AbstractExtendableRevisioned { return adminEventsDetailsEnabled; } - public List getUserFederationProviders() { - return userFederationProviders; - } - - public MultivaluedHashMap getUserFederationMappers() { - return userFederationMappers; - } - public List getIdentityProviders() { return identityProviders; } @@ -546,10 +528,6 @@ public class CachedRealm extends AbstractExtendableRevisioned { return clientTemplates; } - public Set getUserFederationMapperSet() { - return userFederationMapperSet; - } - public List getAuthenticationFlowList() { return authenticationFlowList; } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java index f5b9d7df51..3fd4e77ecb 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java @@ -734,194 +734,6 @@ public class RealmAdapter implements RealmModel, JpaModel { } - private void removeFederationMappersForProvider(String federationProviderId) { - Set mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId); - for (UserFederationMapperEntity mapper : mappers) { - realm.getUserFederationMappers().remove(mapper); - em.remove(mapper); - } - } - - @Override - public List getUserFederationProviders() { - List entities = realm.getUserFederationProviders(); - if (entities.isEmpty()) return Collections.EMPTY_LIST; - List copy = new ArrayList(); - for (UserFederationProviderEntity entity : entities) { - copy.add(entity); - - } - Collections.sort(copy, new Comparator() { - - @Override - public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) { - return o1.getPriority() - o2.getPriority(); - } - - }); - List result = new ArrayList(); - for (UserFederationProviderEntity entity : copy) { - result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), - entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); - } - - return Collections.unmodifiableList(result); - } - - @Override - public UserFederationProviderModel addUserFederationProvider(String providerName, Map config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { - KeycloakModelUtils.ensureUniqueDisplayName(displayName, null, getUserFederationProviders()); - - String id = KeycloakModelUtils.generateId(); - UserFederationProviderEntity entity = new UserFederationProviderEntity(); - entity.setId(id); - entity.setRealm(realm); - entity.setProviderName(providerName); - entity.setConfig(config); - entity.setPriority(priority); - if (displayName == null) { - displayName = id; - } - entity.setDisplayName(displayName); - entity.setFullSyncPeriod(fullSyncPeriod); - entity.setChangedSyncPeriod(changedSyncPeriod); - entity.setLastSync(lastSync); - em.persist(entity); - realm.getUserFederationProviders().add(entity); - em.flush(); - UserFederationProviderModel providerModel = new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync); - - session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, providerModel)); - - return providerModel; - } - - @Override - public void removeUserFederationProvider(UserFederationProviderModel provider) { - Iterator it = realm.getUserFederationProviders().iterator(); - while (it.hasNext()) { - UserFederationProviderEntity entity = it.next(); - if (entity.getId().equals(provider.getId())) { - - session.users().preRemove(this, provider); - removeFederationMappersForProvider(provider.getId()); - - it.remove(); - em.remove(entity); - return; - } - } - } - @Override - public void updateUserFederationProvider(UserFederationProviderModel model) { - KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders()); - - Iterator it = realm.getUserFederationProviders().iterator(); - while (it.hasNext()) { - UserFederationProviderEntity entity = it.next(); - if (entity.getId().equals(model.getId())) { - String displayName = model.getDisplayName(); - if (displayName != null) { - entity.setDisplayName(model.getDisplayName()); - } - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - entity.setProviderName(model.getProviderName()); - entity.setPriority(model.getPriority()); - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - break; - } - } - } - - @Override - public void setUserFederationProviders(List providers) { - for (UserFederationProviderModel currentProvider : providers) { - KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers); - } - - Iterator it = realm.getUserFederationProviders().iterator(); - while (it.hasNext()) { - UserFederationProviderEntity entity = it.next(); - boolean found = false; - for (UserFederationProviderModel model : providers) { - if (entity.getId().equals(model.getId())) { - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - entity.setProviderName(model.getProviderName()); - String displayName = model.getDisplayName(); - if (displayName != null) { - entity.setDisplayName(displayName); - } - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - found = true; - break; - } - - } - if (found) continue; - session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), - entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); - removeFederationMappersForProvider(entity.getId()); - - it.remove(); - em.remove(entity); - } - - List add = new LinkedList<>(); - for (UserFederationProviderModel model : providers) { - boolean found = false; - for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) { - if (entity.getId().equals(model.getId())) { - found = true; - break; - } - } - if (!found) add.add(model); - } - - for (UserFederationProviderModel model : add) { - UserFederationProviderEntity entity = new UserFederationProviderEntity(); - if (model.getId() != null) { - entity.setId(model.getId()); - } else { - String id = KeycloakModelUtils.generateId(); - entity.setId(id); - model.setId(id); - } - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - entity.setProviderName(model.getProviderName()); - entity.setPriority(model.getPriority()); - String displayName = model.getDisplayName(); - if (displayName == null) { - displayName = entity.getId(); - } - entity.setDisplayName(displayName); - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - entity.setRealm(realm); - em.persist(entity); - realm.getUserFederationProviders().add(entity); - - session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, model)); - } - } - - protected UserFederationProviderEntity getUserFederationProviderEntityById(String federationProviderId) { - for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) { - if (entity.getId().equals(federationProviderId)) { - return entity; - } - } - return null; - } - @Override public RoleModel getRole(String name) { return session.realms().getRealmRole(this, name); @@ -1402,118 +1214,6 @@ public class RealmAdapter implements RealmModel, JpaModel { return mapping; } - @Override - public Set getUserFederationMappers() { - Collection entities = this.realm.getUserFederationMappers(); - if (entities.isEmpty()) return Collections.EMPTY_SET; - Set mappers = new HashSet<>(); - for (UserFederationMapperEntity entity : entities) { - UserFederationMapperModel mapper = entityToModel(entity); - mappers.add(mapper); - } - return Collections.unmodifiableSet(mappers); - } - - @Override - public Set getUserFederationMappersByFederationProvider(String federationProviderId) { - Set mapperEntities = getUserFederationMapperEntitiesByFederationProvider(federationProviderId); - if (mapperEntities.isEmpty()) return Collections.EMPTY_SET; - Set mappers = new HashSet(); - for (UserFederationMapperEntity entity : mapperEntities) { - UserFederationMapperModel mapper = entityToModel(entity); - mappers.add(mapper); - } - return Collections.unmodifiableSet(mappers); - } - - @Override - public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel model) { - if (getUserFederationMapperByName(model.getFederationProviderId(), model.getName()) != null) { - throw new ModelDuplicateException("User federation mapper must be unique per federation provider. There is already: " + model.getName()); - } - String id = KeycloakModelUtils.generateId(); - UserFederationMapperEntity entity = new UserFederationMapperEntity(); - entity.setId(id); - entity.setName(model.getName()); - entity.setFederationProvider(getUserFederationProviderEntityById(model.getFederationProviderId())); - entity.setFederationMapperType(model.getFederationMapperType()); - entity.setRealm(this.realm); - entity.setConfig(model.getConfig()); - - em.persist(entity); - this.realm.getUserFederationMappers().add(entity); - UserFederationMapperModel mapperModel = entityToModel(entity); - - return mapperModel; - } - - @Override - public void removeUserFederationMapper(UserFederationMapperModel mapper) { - UserFederationMapperEntity toDelete = getUserFederationMapperEntity(mapper.getId()); - if (toDelete != null) { - this.realm.getUserFederationMappers().remove(toDelete); - em.remove(toDelete); - } - } - - protected UserFederationMapperEntity getUserFederationMapperEntity(String id) { - for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) { - if (entity.getId().equals(id)) { - return entity; - } - } - return null; - - } - - protected UserFederationMapperEntity getUserFederationMapperEntityByName(String federationProviderId, String name) { - for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) { - if (federationProviderId.equals(entity.getFederationProvider().getId()) && entity.getName().equals(name)) { - return entity; - } - } - return null; - - } - - protected Set getUserFederationMapperEntitiesByFederationProvider(String federationProviderId) { - Set mappers = new HashSet(); - for (UserFederationMapperEntity entity : this.realm.getUserFederationMappers()) { - if (federationProviderId.equals(entity.getFederationProvider().getId())) { - mappers.add(entity); - } - } - return mappers; - } - - @Override - public void updateUserFederationMapper(UserFederationMapperModel mapper) { - UserFederationMapperEntity entity = getUserFederationMapperEntity(mapper.getId()); - entity.setFederationProvider(getUserFederationProviderEntityById(mapper.getFederationProviderId())); - entity.setFederationMapperType(mapper.getFederationMapperType()); - if (entity.getConfig() == null) { - entity.setConfig(mapper.getConfig()); - } else { - entity.getConfig().clear(); - entity.getConfig().putAll(mapper.getConfig()); - } - em.flush(); - } - - @Override - public UserFederationMapperModel getUserFederationMapperById(String id) { - UserFederationMapperEntity entity = getUserFederationMapperEntity(id); - if (entity == null) return null; - return entityToModel(entity); - } - - @Override - public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) { - UserFederationMapperEntity entity = getUserFederationMapperEntityByName(federationProviderId, name); - if (entity == null) return null; - return entityToModel(entity); - } - protected UserFederationMapperModel entityToModel(UserFederationMapperEntity entity) { UserFederationMapperModel mapper = new UserFederationMapperModel(); mapper.setId(entity.getId()); diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java index 119c7df38e..f92482fcdf 100755 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java @@ -869,183 +869,6 @@ public class RealmAdapter extends AbstractMongoAdapter impleme updateRealm(); } - - private void removeFederationMappersForProvider(String federationProviderId) { - Set mappers = getUserFederationMapperEntitiesByFederationProvider(federationProviderId); - for (UserFederationMapperEntity mapper : mappers) { - getMongoEntity().getUserFederationMappers().remove(mapper); - } - } - - @Override - public UserFederationProviderModel addUserFederationProvider(String providerName, Map config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync) { - KeycloakModelUtils.ensureUniqueDisplayName(displayName, null, getUserFederationProviders()); - - UserFederationProviderEntity entity = new UserFederationProviderEntity(); - entity.setId(KeycloakModelUtils.generateId()); - entity.setPriority(priority); - entity.setProviderName(providerName); - entity.setConfig(config); - if (displayName == null) { - displayName = entity.getId(); - } - entity.setDisplayName(displayName); - entity.setFullSyncPeriod(fullSyncPeriod); - entity.setChangedSyncPeriod(changedSyncPeriod); - entity.setLastSync(lastSync); - realm.getUserFederationProviders().add(entity); - updateRealm(); - - UserFederationProviderModel providerModel = new UserFederationProviderModel(entity.getId(), providerName, config, priority, displayName, fullSyncPeriod, changedSyncPeriod, lastSync); - - session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, providerModel)); - - return providerModel; - } - - @Override - public void removeUserFederationProvider(UserFederationProviderModel provider) { - Iterator it = realm.getUserFederationProviders().iterator(); - while (it.hasNext()) { - UserFederationProviderEntity entity = it.next(); - if (entity.getId().equals(provider.getId())) { - session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), - entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); - removeFederationMappersForProvider(provider.getId()); - - it.remove(); - } - } - updateRealm(); - } - @Override - public void updateUserFederationProvider(UserFederationProviderModel model) { - KeycloakModelUtils.ensureUniqueDisplayName(model.getDisplayName(), model, getUserFederationProviders()); - - Iterator it = realm.getUserFederationProviders().iterator(); - while (it.hasNext()) { - UserFederationProviderEntity entity = it.next(); - if (entity.getId().equals(model.getId())) { - entity.setProviderName(model.getProviderName()); - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - String displayName = model.getDisplayName(); - if (displayName != null) { - entity.setDisplayName(model.getDisplayName()); - } - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - } - } - updateRealm(); - } - - @Override - public List getUserFederationProviders() { - List entities = realm.getUserFederationProviders(); - if (entities.isEmpty()) return Collections.EMPTY_LIST; - List copy = new LinkedList(); - for (UserFederationProviderEntity entity : entities) { - copy.add(entity); - - } - Collections.sort(copy, new Comparator() { - - @Override - public int compare(UserFederationProviderEntity o1, UserFederationProviderEntity o2) { - return o1.getPriority() - o2.getPriority(); - } - - }); - List result = new LinkedList(); - for (UserFederationProviderEntity entity : copy) { - result.add(new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), - entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); - } - - return Collections.unmodifiableList(result); - } - - @Override - public void setUserFederationProviders(List providers) { - for (UserFederationProviderModel currentProvider : providers) { - KeycloakModelUtils.ensureUniqueDisplayName(currentProvider.getDisplayName(), currentProvider, providers); - } - - List existingProviders = realm.getUserFederationProviders(); - List toRemove = new LinkedList<>(); - for (UserFederationProviderEntity entity : existingProviders) { - boolean found = false; - for (UserFederationProviderModel model : providers) { - if (entity.getId().equals(model.getId())) { - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - entity.setProviderName(model.getProviderName()); - String displayName = model.getDisplayName(); - if (displayName != null) { - entity.setDisplayName(displayName); - } - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - found = true; - break; - } - - } - if (found) continue; - session.users().preRemove(this, new UserFederationProviderModel(entity.getId(), entity.getProviderName(), entity.getConfig(), entity.getPriority(), entity.getDisplayName(), - entity.getFullSyncPeriod(), entity.getChangedSyncPeriod(), entity.getLastSync())); - removeFederationMappersForProvider(entity.getId()); - - toRemove.add(entity); - } - - for (UserFederationProviderEntity entity : toRemove) { - realm.getUserFederationProviders().remove(entity); - } - - List add = new LinkedList(); - for (UserFederationProviderModel model : providers) { - boolean found = false; - for (UserFederationProviderEntity entity : realm.getUserFederationProviders()) { - if (entity.getId().equals(model.getId())) { - found = true; - break; - } - } - if (!found) add.add(model); - } - - for (UserFederationProviderModel model : add) { - UserFederationProviderEntity entity = new UserFederationProviderEntity(); - if (model.getId() != null) { - entity.setId(model.getId()); - } else { - String id = KeycloakModelUtils.generateId(); - entity.setId(id); - model.setId(id); - } - entity.setProviderName(model.getProviderName()); - entity.setConfig(model.getConfig()); - entity.setPriority(model.getPriority()); - String displayName = model.getDisplayName(); - if (displayName == null) { - displayName = entity.getId(); - } - entity.setDisplayName(displayName); - entity.setFullSyncPeriod(model.getFullSyncPeriod()); - entity.setChangedSyncPeriod(model.getChangedSyncPeriod()); - entity.setLastSync(model.getLastSync()); - realm.getUserFederationProviders().add(entity); - - session.getKeycloakSessionFactory().publish(new UserFederationProviderCreationEventImpl(this, model)); - } - - updateRealm(); - } - @Override public boolean isEventsEnabled() { return realm.isEventsEnabled(); @@ -1760,131 +1583,6 @@ public class RealmAdapter extends AbstractMongoAdapter impleme return null; } - - - - - @Override - public Set getUserFederationMappers() { - List entities = getMongoEntity().getUserFederationMappers(); - if (entities.isEmpty()) return Collections.EMPTY_SET; - Set mappers = new HashSet(); - for (UserFederationMapperEntity entity : entities) { - UserFederationMapperModel mapper = entityToModel(entity); - mappers.add(mapper); - } - return Collections.unmodifiableSet(mappers); - } - - @Override - public Set getUserFederationMappersByFederationProvider(String federationProviderId) { - Set mappers = new HashSet(); - Set mapperEntities = getUserFederationMapperEntitiesByFederationProvider(federationProviderId); - for (UserFederationMapperEntity entity : mapperEntities) { - mappers.add(entityToModel(entity)); - } - return mappers; - } - - @Override - public UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel model) { - if (getUserFederationMapperByName(model.getFederationProviderId(), model.getName()) != null) { - throw new ModelDuplicateException("User federation mapper must be unique per federation provider. There is already: " + model.getName()); - } - String id = KeycloakModelUtils.generateId(); - UserFederationMapperEntity entity = new UserFederationMapperEntity(); - entity.setId(id); - entity.setName(model.getName()); - entity.setFederationProviderId(model.getFederationProviderId()); - entity.setFederationMapperType(model.getFederationMapperType()); - entity.setConfig(model.getConfig()); - - getMongoEntity().getUserFederationMappers().add(entity); - updateMongoEntity(); - UserFederationMapperModel mapperModel = entityToModel(entity); - - return mapperModel; - } - - protected UserFederationMapperEntity getUserFederationMapperEntity(String id) { - for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) { - if (entity.getId().equals(id)) { - return entity; - } - } - return null; - - } - - protected UserFederationMapperEntity getUserFederationMapperEntityByName(String federationProviderId, String name) { - for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) { - if (entity.getFederationProviderId().equals(federationProviderId) && entity.getName().equals(name)) { - return entity; - } - } - return null; - - } - - protected Set getUserFederationMapperEntitiesByFederationProvider(String federationProviderId) { - Set mappers = new HashSet(); - for (UserFederationMapperEntity entity : getMongoEntity().getUserFederationMappers()) { - if (federationProviderId.equals(entity.getFederationProviderId())) { - mappers.add(entity); - } - } - return mappers; - } - - @Override - public void removeUserFederationMapper(UserFederationMapperModel mapper) { - UserFederationMapperEntity toDelete = getUserFederationMapperEntity(mapper.getId()); - if (toDelete != null) { - this.realm.getUserFederationMappers().remove(toDelete); - updateMongoEntity(); - } - } - - @Override - public void updateUserFederationMapper(UserFederationMapperModel mapper) { - UserFederationMapperEntity entity = getUserFederationMapperEntity(mapper.getId()); - entity.setFederationProviderId(mapper.getFederationProviderId()); - entity.setFederationMapperType(mapper.getFederationMapperType()); - if (entity.getConfig() == null) { - entity.setConfig(mapper.getConfig()); - } else { - entity.getConfig().clear(); - entity.getConfig().putAll(mapper.getConfig()); - } - updateMongoEntity(); - } - - @Override - public UserFederationMapperModel getUserFederationMapperById(String id) { - UserFederationMapperEntity entity = getUserFederationMapperEntity(id); - if (entity == null) return null; - return entityToModel(entity); - } - - @Override - public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) { - UserFederationMapperEntity entity = getUserFederationMapperEntityByName(federationProviderId, name); - if (entity == null) return null; - return entityToModel(entity); - } - - protected UserFederationMapperModel entityToModel(UserFederationMapperEntity entity) { - UserFederationMapperModel mapper = new UserFederationMapperModel(); - mapper.setId(entity.getId()); - mapper.setName(entity.getName()); - mapper.setFederationProviderId(entity.getFederationProviderId()); - mapper.setFederationMapperType(entity.getFederationMapperType()); - Map config = new HashMap(); - if (entity.getConfig() != null) config.putAll(entity.getConfig()); - mapper.setConfig(config); - return mapper; - } - @Override public List getClientTemplates() { DBObject query = new QueryBuilder() diff --git a/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java b/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java index a21aa65c7b..c569e9cc19 100755 --- a/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java +++ b/server-spi-private/src/main/java/org/keycloak/migration/MigrationModelManager.java @@ -18,13 +18,6 @@ package org.keycloak.migration; import org.jboss.logging.Logger; -import org.keycloak.migration.migrators.MigrateTo1_2_0; -import org.keycloak.migration.migrators.MigrateTo1_3_0; -import org.keycloak.migration.migrators.MigrateTo1_4_0; -import org.keycloak.migration.migrators.MigrateTo1_5_0; -import org.keycloak.migration.migrators.MigrateTo1_6_0; -import org.keycloak.migration.migrators.MigrateTo1_7_0; -import org.keycloak.migration.migrators.MigrateTo1_8_0; import org.keycloak.migration.migrators.MigrateTo1_9_0; import org.keycloak.migration.migrators.MigrateTo1_9_2; import org.keycloak.migration.migrators.MigrateTo2_0_0; @@ -42,13 +35,6 @@ public class MigrationModelManager { private static Logger logger = Logger.getLogger(MigrationModelManager.class); private static final Migration[] migrations = { - new MigrateTo1_2_0(), - new MigrateTo1_3_0(), - new MigrateTo1_4_0(), - new MigrateTo1_5_0(), - new MigrateTo1_6_0(), - new MigrateTo1_7_0(), - new MigrateTo1_8_0(), new MigrateTo1_9_0(), new MigrateTo1_9_2(), new MigrateTo2_0_0(), diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java deleted file mode 100755 index 2b03f6e217..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_3_0.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.migration.migrators; - -import org.keycloak.migration.ModelVersion; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationEventAwareProviderFactory; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; - -import javax.naming.directory.SearchControls; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class MigrateTo1_3_0 implements Migration { - - public static final ModelVersion VERSION = new ModelVersion("1.3.0"); - - public ModelVersion getVersion() { - return VERSION; - } - - public void migrate(KeycloakSession session) { - List realms = session.realms().getRealms(); - for (RealmModel realm : realms) { - migrateLDAPProviders(session, realm); - } - - } - - private void migrateLDAPProviders(KeycloakSession session, RealmModel realm) { - List federationProviders = realm.getUserFederationProviders(); - for (UserFederationProviderModel fedProvider : federationProviders) { - - if (fedProvider.getProviderName().equals(LDAPConstants.LDAP_PROVIDER)) { - Map config = fedProvider.getConfig(); - - // Update config properties for LDAP federated provider - if (config.get(LDAPConstants.SEARCH_SCOPE) == null) { - config.put(LDAPConstants.SEARCH_SCOPE, String.valueOf(SearchControls.SUBTREE_SCOPE)); - } - - String usersDn = config.remove("userDnSuffix"); - if (usersDn != null && config.get(LDAPConstants.USERS_DN) == null) { - config.put(LDAPConstants.USERS_DN, usersDn); - } - - String usernameLdapAttribute = config.get(LDAPConstants.USERNAME_LDAP_ATTRIBUTE); - if (usernameLdapAttribute != null && config.get(LDAPConstants.RDN_LDAP_ATTRIBUTE) == null) { - if (usernameLdapAttribute.equalsIgnoreCase(LDAPConstants.SAM_ACCOUNT_NAME)) { - config.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, LDAPConstants.CN); - } else { - config.put(LDAPConstants.RDN_LDAP_ATTRIBUTE, usernameLdapAttribute); - } - } - - if (config.get(LDAPConstants.UUID_LDAP_ATTRIBUTE) == null) { - String uuidAttrName = LDAPConstants.getUuidAttributeName(config.get(LDAPConstants.VENDOR)); - config.put(LDAPConstants.UUID_LDAP_ATTRIBUTE, uuidAttrName); - } - - realm.updateUserFederationProvider(fedProvider); - - // Create default mappers for LDAP - Set mappers = realm.getUserFederationMappersByFederationProvider(fedProvider.getId()); - if (mappers.isEmpty()) { - UserFederationProviderFactory ldapFactory = (UserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, LDAPConstants.LDAP_PROVIDER); - if (ldapFactory != null) { - ((UserFederationEventAwareProviderFactory) ldapFactory).onProviderModelCreated(realm, fedProvider); - } - } - } - } - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_4_0.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_4_0.java deleted file mode 100755 index 9f28f91918..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_4_0.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.migration.migrators; - -import org.keycloak.migration.ModelVersion; -import org.keycloak.models.ImpersonationConstants; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserModel; -import org.keycloak.models.utils.DefaultAuthenticationFlows; -import org.keycloak.models.utils.DefaultRequiredActions; -import org.keycloak.models.utils.KeycloakModelUtils; - -import java.util.Arrays; -import java.util.List; - -/** - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class MigrateTo1_4_0 implements Migration { - public static final ModelVersion VERSION = new ModelVersion("1.4.0"); - - public ModelVersion getVersion() { - return VERSION; - } - - public void migrate(KeycloakSession session) { - List realms = session.realms().getRealms(); - for (RealmModel realm : realms) { - if (realm.getAuthenticationFlows().size() == 0) { - DefaultAuthenticationFlows.migrateFlows(realm); - DefaultRequiredActions.addActions(realm); - } - ImpersonationConstants.setupImpersonationService(session, realm); - - migrateLDAPMappers(session, realm); - migrateUsers(session, realm); - } - - } - - private void migrateLDAPMappers(KeycloakSession session, RealmModel realm) { - List mandatoryInLdap = Arrays.asList("username", "username-cn", "first name", "last name"); - for (UserFederationMapperModel ldapMapper : realm.getUserFederationMappers()) { - if (mandatoryInLdap.contains(ldapMapper.getName())) { - ldapMapper.getConfig().put("is.mandatory.in.ldap", "true"); - realm.updateUserFederationMapper(ldapMapper); - } - } - } - - private void migrateUsers(KeycloakSession session, RealmModel realm) { - List users = session.userStorage().getUsers(realm, false); - for (UserModel user : users) { - String email = user.getEmail(); - email = KeycloakModelUtils.toLowerCaseSafe(email); - if (email != null && !email.equals(user.getEmail())) { - user.setEmail(email); - } - } - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_8_0.java b/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_8_0.java deleted file mode 100644 index 79fb02cc7d..0000000000 --- a/server-spi-private/src/main/java/org/keycloak/migration/migrators/MigrateTo1_8_0.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.migration.migrators; - -import org.keycloak.migration.ModelVersion; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.utils.KeycloakModelUtils; - -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -public class MigrateTo1_8_0 implements Migration { - - public static final ModelVersion VERSION = new ModelVersion("1.8.0"); - - public ModelVersion getVersion() { - return VERSION; - } - - public void migrate(KeycloakSession session) { - List realms = session.realms().getRealms(); - for (RealmModel realm : realms) { - - List federationProviders = realm.getUserFederationProviders(); - for (UserFederationProviderModel fedProvider : federationProviders) { - - if (fedProvider.getProviderName().equals(LDAPConstants.LDAP_PROVIDER)) { - Map config = fedProvider.getConfig(); - - if (isActiveDirectory(config)) { - - // Create mapper for MSAD account controls - if (realm.getUserFederationMapperByName(fedProvider.getId(), "MSAD account controls") == null) { - UserFederationMapperModel mapperModel = KeycloakModelUtils.createUserFederationMapperModel("MSAD account controls", fedProvider.getId(), LDAPConstants.MSAD_USER_ACCOUNT_CONTROL_MAPPER); - realm.addUserFederationMapper(mapperModel); - } - } - } - } - - } - } - - private boolean isActiveDirectory(Map ldapConfig) { - String vendor = ldapConfig.get(LDAPConstants.VENDOR); - return vendor != null && vendor.equals(LDAPConstants.VENDOR_ACTIVE_DIRECTORY); - } -} diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java index e26523366e..80e45e4fad 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java @@ -283,28 +283,6 @@ public final class KeycloakModelUtils { } - public static UserFederationProviderModel findUserFederationProviderByDisplayName(String displayName, RealmModel realm) { - if (displayName == null) { - return null; - } - - for (UserFederationProviderModel fedProvider : realm.getUserFederationProviders()) { - if (displayName.equals(fedProvider.getDisplayName())) { - return fedProvider; - } - } - return null; - } - - public static UserFederationProviderModel findUserFederationProviderById(String fedProviderId, RealmModel realm) { - for (UserFederationProviderModel fedProvider : realm.getUserFederationProviders()) { - if (fedProviderId.equals(fedProvider.getId())) { - return fedProvider; - } - } - return null; - } - public static UserStorageProviderModel findUserStorageProviderByName(String displayName, RealmModel realm) { if (displayName == null) { return null; diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java index bf4a6dc29e..a8255c1197 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java @@ -352,8 +352,6 @@ public class ModelToRepresentation { } } - exportUserFederationProvidersAndMappers(realm, rep); - for (IdentityProviderModel provider : realm.getIdentityProviders()) { rep.addIdentityProvider(toRepresentation(realm, provider)); } @@ -384,23 +382,7 @@ public class ModelToRepresentation { return rep; } - public static void exportUserFederationProvidersAndMappers(RealmModel realm, RealmRepresentation rep) { - List fedProviderModels = realm.getUserFederationProviders(); - if (fedProviderModels.size() > 0) { - List fedProviderReps = new ArrayList(); - for (UserFederationProviderModel model : fedProviderModels) { - UserFederationProviderRepresentation fedProvRep = toRepresentation(model); - fedProviderReps.add(fedProvRep); - } - rep.setUserFederationProviders(fedProviderReps); - } - - for (UserFederationMapperModel mapper : realm.getUserFederationMappers()) { - rep.addUserFederationMapper(toRepresentation(realm, mapper)); - } - } - - public static void exportGroups(RealmModel realm, RealmRepresentation rep) { + public static void exportGroups(RealmModel realm, RealmRepresentation rep) { List groups = toGroupHierarchy(realm, true); rep.setGroups(groups); } @@ -605,24 +587,6 @@ public class ModelToRepresentation { return rep; } - public static UserFederationMapperRepresentation toRepresentation(RealmModel realm, UserFederationMapperModel model) { - UserFederationMapperRepresentation rep = new UserFederationMapperRepresentation(); - rep.setId(model.getId()); - rep.setName(model.getName()); - rep.setFederationMapperType(model.getFederationMapperType()); - Map config = new HashMap(); - config.putAll(model.getConfig()); - rep.setConfig(config); - - UserFederationProviderModel fedProvider = KeycloakModelUtils.findUserFederationProviderById(model.getFederationProviderId(), realm); - if (fedProvider == null) { - throw new ModelException("Couldn't find federation provider with ID " + model.getId()); - } - rep.setFederationProviderDisplayName(fedProvider.getDisplayName()); - - return rep; - } - public static IdentityProviderRepresentation toRepresentation(RealmModel realm, IdentityProviderModel identityProviderModel) { IdentityProviderRepresentation providerRep = new IdentityProviderRepresentation(); diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 262503f9ac..44fed9c7e2 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -376,37 +376,14 @@ public class RepresentationToModel { if (convertSet.contains(fedRep.getProviderName())) { ComponentModel component = convertFedProviderToComponent(newRealm.getId(), fedRep); userStorageModels.put(fedRep.getDisplayName(), newRealm.importComponentModel(component)); - } else { - providerModels.add(convertFederationProvider(fedRep)); } - } - newRealm.setUserFederationProviders(providerModels); } // This is for case, when you have hand-written JSON file with LDAP userFederationProvider, but WITHOUT any userFederationMappers configured. Default LDAP mappers need to be created in that case. Set storageProvidersWhichShouldImportDefaultMappers = new HashSet<>(userStorageModels.keySet()); if (rep.getUserFederationMappers() != null) { - - // Remove builtin mappers for federation providers, which have some mappers already provided in JSON (likely due to previous export) - if (rep.getUserFederationProviders() != null) { - Set providerNames = new TreeSet(); - for (UserFederationMapperRepresentation representation : rep.getUserFederationMappers()) { - providerNames.add(representation.getFederationProviderDisplayName()); - } - for (String providerName : providerNames) { - for (UserFederationProviderModel providerModel : providerModels) { - if (providerName.equals(providerModel.getDisplayName())) { - Set toDelete = newRealm.getUserFederationMappersByFederationProvider(providerModel.getId()); - for (UserFederationMapperModel mapperModel : toDelete) { - newRealm.removeUserFederationMapper(mapperModel); - } - } - } - } - } - for (UserFederationMapperRepresentation representation : rep.getUserFederationMappers()) { if (userStorageModels.containsKey(representation.getFederationProviderDisplayName())) { ComponentModel parent = userStorageModels.get(representation.getFederationProviderDisplayName()); @@ -417,8 +394,6 @@ public class RepresentationToModel { storageProvidersWhichShouldImportDefaultMappers.remove(representation.getFederationProviderDisplayName()); - } else { - newRealm.addUserFederationMapper(toModel(newRealm, representation)); } } } @@ -865,11 +840,6 @@ public class RepresentationToModel { realm.setBrowserSecurityHeaders(rep.getBrowserSecurityHeaders()); } - if (rep.getUserFederationProviders() != null) { - List providerModels = convertFederationProviders(rep.getUserFederationProviders()); - realm.setUserFederationProviders(providerModels); - } - if(rep.isInternationalizationEnabled() != null){ realm.setInternationalizationEnabled(rep.isInternationalizationEnabled()); } @@ -950,23 +920,6 @@ public class RepresentationToModel { } - public static UserFederationMapperModel toModel(RealmModel realm, UserFederationMapperRepresentation rep) { - UserFederationMapperModel model = new UserFederationMapperModel(); - model.setId(rep.getId()); - model.setName(rep.getName()); - model.setFederationMapperType(rep.getFederationMapperType()); - model.setConfig(rep.getConfig()); - - UserFederationProviderModel fedProvider = KeycloakModelUtils.findUserFederationProviderByDisplayName(rep.getFederationProviderDisplayName(), realm); - if (fedProvider == null) { - throw new ModelException("Couldn't find federation provider with display name [" + rep.getFederationProviderDisplayName() + "] referenced from mapper [" - + rep.getName()); - } - model.setFederationProviderId(fedProvider.getId()); - - return model; - } - // Roles public static void createRole(RealmModel newRealm, RoleRepresentation roleRep) { diff --git a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java index f3242eb73b..c91331a74e 100755 --- a/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java +++ b/server-spi/src/main/java/org/keycloak/models/KeycloakSession.java @@ -117,7 +117,7 @@ public interface KeycloakSession { * * @return */ - UserFederationManager users(); + UserProvider users(); /** diff --git a/server-spi/src/main/java/org/keycloak/models/RealmModel.java b/server-spi/src/main/java/org/keycloak/models/RealmModel.java index 09720a7b5f..d65452b579 100755 --- a/server-spi/src/main/java/org/keycloak/models/RealmModel.java +++ b/server-spi/src/main/java/org/keycloak/models/RealmModel.java @@ -310,21 +310,6 @@ public interface RealmModel extends RoleContainerModel { return list; } - // Should return list sorted by UserFederationProviderModel.priority - List getUserFederationProviders(); - UserFederationProviderModel addUserFederationProvider(String providerName, Map config, int priority, String displayName, int fullSyncPeriod, int changedSyncPeriod, int lastSync); - void updateUserFederationProvider(UserFederationProviderModel provider); - void removeUserFederationProvider(UserFederationProviderModel provider); - void setUserFederationProviders(List providers); - - Set getUserFederationMappers(); - Set getUserFederationMappersByFederationProvider(String federationProviderId); - UserFederationMapperModel addUserFederationMapper(UserFederationMapperModel mapper); - void removeUserFederationMapper(UserFederationMapperModel mapper); - void updateUserFederationMapper(UserFederationMapperModel mapper); - UserFederationMapperModel getUserFederationMapperById(String id); - UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name); - String getLoginTheme(); void setLoginTheme(String name); diff --git a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java index 707b96ae3d..0ff7f5cd89 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java +++ b/server-spi/src/main/java/org/keycloak/models/UserFederationManager.java @@ -49,139 +49,23 @@ public class UserFederationManager implements UserProvider { @Override public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) { UserModel user = session.userStorage().addUser(realm, id, username.toLowerCase(), addDefaultRoles, addDefaultRequiredActions); - return registerWithFederation(realm, user); + return user; } @Override public UserModel addUser(RealmModel realm, String username) { UserModel user = session.userStorage().addUser(realm, username.toLowerCase()); - return registerWithFederation(realm, user); - } - - protected UserModel registerWithFederation(RealmModel realm, UserModel user) { - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - if (fed.synchronizeRegistrations()) { - user.setFederationLink(federation.getId()); - UserModel registered = fed.register(realm, user); - managedUsers.put(registered.getId(), registered); - return registered; - } - } return user; } - public UserFederationProvider getFederationProvider(UserFederationProviderModel model) { - UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, model.getProviderName()); - return factory.getInstance(session, model); - } - - public UserFederationProvider getFederationLink(RealmModel realm, UserModel user) { - if (user.getFederationLink() == null) return null; - for (UserFederationProviderModel fed : realm.getUserFederationProviders()) { - if (fed.getId().equals(user.getFederationLink())) { - return getFederationProvider(fed); - } - } - return null; - } - @Override public boolean removeUser(RealmModel realm, UserModel user) { - UserFederationProvider link = getFederationLink(realm, user); - if (link != null) { - boolean fedRemoved = link.removeUser(realm, user); - if (fedRemoved) { - boolean localRemoved = session.userStorage().removeUser(realm, user); - managedUsers.remove(user.getId()); - if (!localRemoved) { - logger.warn("User possibly removed from federation provider, but failed to remove him from keycloak model"); - } - return localRemoved; - } else { - logger.warn("Failed to remove user from federation provider"); - return false; - } - } - return session.userStorage().removeUser(realm, user); + return session.userStorage().removeUser(realm, user); } - public void validateUser(RealmModel realm, UserModel user) { - if (managedUsers.containsKey(user.getId())) { - return; - } - - UserFederationProvider link = getFederationLink(realm, user); - if (link != null && !link.isValid(realm, user)) { - deleteInvalidUser(realm, user); - throw new IllegalStateException("Federated user no longer valid"); - } - - } - - protected void deleteInvalidUser(final RealmModel realm, final UserModel user) { - runJobInTransaction(session.getKeycloakSessionFactory(), new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - RealmModel realmModel = session.realms().getRealm(realm.getId()); - if (realmModel == null) return; - UserModel deletedUser = session.userStorage().getUserById(user.getId(), realmModel); - new UserManager(session).removeUser(realmModel, deletedUser, session.userStorage()); - logger.debugf("Removed invalid user '%s'", user.getUsername()); - } - - }); - } - - private static void runJobInTransaction(KeycloakSessionFactory factory, KeycloakSessionTask task) { - KeycloakSession session = factory.create(); - KeycloakTransaction tx = session.getTransactionManager(); - try { - tx.begin(); - task.run(session); - - if (tx.isActive()) { - if (tx.getRollbackOnly()) { - tx.rollback(); - } else { - tx.commit(); - } - } - } catch (RuntimeException re) { - if (tx.isActive()) { - tx.rollback(); - } - throw re; - } finally { - session.close(); - } - } - - protected UserModel validateAndProxyUser(RealmModel realm, UserModel user) { - UserModel managed = managedUsers.get(user.getId()); - if (managed != null) { - return managed; - } - - UserFederationProvider link = getFederationLink(realm, user); - if (link != null) { - UserModel validatedProxyUser = link.validateAndProxy(realm, user); - if (validatedProxyUser != null) { - managedUsers.put(user.getId(), validatedProxyUser); - return validatedProxyUser; - } else { - deleteInvalidUser(realm, user); - return null; - } - } - return user; - } - @Override public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) { - validateUser(realm, user); session.userStorage().addFederatedIdentity(realm, user, socialLink); } @@ -191,7 +75,6 @@ public class UserFederationManager implements UserProvider { @Override public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) { - validateUser(realm, user); if (user == null) throw new IllegalStateException("Federated user no longer valid"); return session.userStorage().removeFederatedIdentity(realm, user, socialProvider); } @@ -226,10 +109,7 @@ public class UserFederationManager implements UserProvider { @Override public UserModel getUserById(String id, RealmModel realm) { UserModel user = session.userStorage().getUserById(id, realm); - if (user != null) { - user = validateAndProxyUser(realm, user); - } - return user; + return user; } @Override @@ -247,21 +127,7 @@ public class UserFederationManager implements UserProvider { Set result = new LinkedHashSet<>(localMembers); - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - if (result.size() >= maxTotal) { - break; - } - - int max = maxTotal - result.size(); - - UserFederationProvider fed = getFederationProvider(federation); - List current = fed.getGroupMembers(realm, group, 0, max); - if (current != null) { - result.addAll(current); - } - } - - if (result.size() <= firstResult) { + if (result.size() <= firstResult) { return Collections.emptyList(); } @@ -277,48 +143,24 @@ public class UserFederationManager implements UserProvider { @Override public UserModel getUserByUsername(String username, RealmModel realm) { UserModel user = session.userStorage().getUserByUsername(username.toLowerCase(), realm); - if (user != null) { - user = validateAndProxyUser(realm, user); - if (user != null) return user; - } - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - user = fed.getUserByUsername(realm, username); - if (user != null) return user; - } return user; } @Override public UserModel getUserByEmail(String email, RealmModel realm) { UserModel user = session.userStorage().getUserByEmail(email.toLowerCase(), realm); - if (user != null) { - user = validateAndProxyUser(realm, user); - if (user != null) return user; - } - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - user = fed.getUserByEmail(realm, email); - if (user != null) return user; - } - return user; + return user; } @Override public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) { UserModel user = session.userStorage().getUserByFederatedIdentity(socialLink, realm); - if (user != null) { - user = validateAndProxyUser(realm, user); - } return user; } @Override public UserModel getServiceAccount(ClientModel client) { UserModel user = session.userStorage().getServiceAccount(client); - if (user != null) { - user = validateAndProxyUser(client.getRealm(), user); - } return user; } @@ -357,8 +199,6 @@ public class UserFederationManager implements UserProvider { if (query == null || query.size() == 0) return results; int added = 0; for (UserModel user : query) { - user = validateAndProxyUser(realm, user); - if (user == null) continue; results.add(user); added++; } @@ -385,30 +225,8 @@ public class UserFederationManager implements UserProvider { return searchForUser(search, realm, 0, Integer.MAX_VALUE - 1); } - void federationLoad(RealmModel realm, Map attributes) { - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - fed.searchByAttributes(attributes, realm, 30); - } - } - @Override public List searchForUser(final String search, RealmModel realm, int firstResult, int maxResults) { - Map attributes = new HashMap(); - int spaceIndex = search.lastIndexOf(' '); - if (spaceIndex > -1) { - String firstName = search.substring(0, spaceIndex).trim(); - String lastName = search.substring(spaceIndex).trim(); - attributes.put(UserModel.FIRST_NAME, firstName); - attributes.put(UserModel.LAST_NAME, lastName); - } else if (search.indexOf('@') > -1) { - attributes.put(UserModel.USERNAME, search.trim().toLowerCase()); - attributes.put(UserModel.EMAIL, search.trim().toLowerCase()); - } else { - attributes.put(UserModel.LAST_NAME, search.trim()); - attributes.put(UserModel.USERNAME, search.trim().toLowerCase()); - } - federationLoad(realm, attributes); return query(new PaginatedQuery() { @Override public List query(RealmModel realm, int first, int max) { @@ -424,7 +242,6 @@ public class UserFederationManager implements UserProvider { @Override public List searchForUser(final Map attributes, RealmModel realm, int firstResult, int maxResults) { - federationLoad(realm, attributes); return query(new PaginatedQuery() { @Override public List query(RealmModel realm, int first, int max) { @@ -440,15 +257,11 @@ public class UserFederationManager implements UserProvider { @Override public Set getFederatedIdentities(UserModel user, RealmModel realm) { - validateUser(realm, user); - if (user == null) throw new IllegalStateException("Federated user no longer valid"); return session.userStorage().getFederatedIdentities(user, realm); } @Override public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) { - validateUser(realm, user); - if (user == null) throw new IllegalStateException("Federated user no longer valid"); return session.userStorage().getFederatedIdentity(user, socialProvider, realm); } @@ -460,10 +273,6 @@ public class UserFederationManager implements UserProvider { @Override public void preRemove(RealmModel realm) { - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - fed.preRemove(realm); - } session.userStorage().preRemove(realm); } @@ -474,20 +283,12 @@ public class UserFederationManager implements UserProvider { @Override public void preRemove(RealmModel realm, GroupModel group) { - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - fed.preRemove(realm, group); - } session.userStorage().preRemove(realm, group); } @Override public void preRemove(RealmModel realm, RoleModel role) { - for (UserFederationProviderModel federation : realm.getUserFederationProviders()) { - UserFederationProvider fed = getFederationProvider(federation); - fed.preRemove(realm, role); - } session.userStorage().preRemove(realm, role); } diff --git a/server-spi/src/main/java/org/keycloak/storage/user/ImportedUserValidation.java b/server-spi/src/main/java/org/keycloak/storage/user/ImportedUserValidation.java index d4d29cbe81..0ceec664b8 100644 --- a/server-spi/src/main/java/org/keycloak/storage/user/ImportedUserValidation.java +++ b/server-spi/src/main/java/org/keycloak/storage/user/ImportedUserValidation.java @@ -20,9 +20,19 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; /** + * If your UserStorageProvider is importing users into local storage, you can validate that import whenever the + * user is queried from local storage. + * * @author Bill Burke * @version $Revision: 1 $ */ public interface ImportedUserValidation { - UserModel validate(RealmModel realmm, UserModel user); + /** + * If this method returns null, then the user storage in local storage will be removed + * + * @param realm + * @param user + * @return null if user no longer valid + */ + UserModel validate(RealmModel realm, UserModel user); } diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java index 49eab24a91..796d189ddb 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java @@ -32,6 +32,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserFederationManager; import org.keycloak.models.UserModel; +import org.keycloak.models.UserProvider; import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.services.ErrorResponse; @@ -93,7 +94,7 @@ public class ResourceSetService { if (!resourceServer.getClientId().equals(ownerId)) { RealmModel realm = authorization.getRealm(); KeycloakSession keycloakSession = authorization.getKeycloakSession(); - UserFederationManager users = keycloakSession.users(); + UserProvider users = keycloakSession.users(); UserModel ownerModel = users.getUserById(ownerId, realm); if (ownerModel == null) { diff --git a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java index a8b41105ff..0661317dbc 100644 --- a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java +++ b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java @@ -120,13 +120,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser } } } else { - // - UserFederationProvider link = session.users().getFederationLink(realm, user); - if (link != null) { - session.users().validateUser(realm, user); - validate(realm, user, toValidate, link); - } // - else if (user.getFederationLink() != null) { + if (user.getFederationLink() != null) { UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof CredentialInputValidator) { validate(realm, user, toValidate, ((CredentialInputValidator)provider)); @@ -176,13 +170,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser } } } else { - // - UserFederationProvider link = session.users().getFederationLink(realm, user); - if (link != null) { - if (link.updateCredential(realm, user, input)) return; - } - // - else if (user.getFederationLink() != null) { + if (user.getFederationLink() != null) { UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof CredentialInputUpdater) { if (((CredentialInputUpdater)provider).updateCredential(realm, user, input)) return; @@ -209,11 +197,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser } } } else { - UserFederationProvider link = session.users().getFederationLink(realm, user); - if (link != null && link.getSupportedCredentialTypes().contains(credentialType)) { - link.disableCredentialType(realm, user, credentialType); - } - else if (user.getFederationLink() != null) { + if (user.getFederationLink() != null) { UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof CredentialInputUpdater) { ((CredentialInputUpdater)provider).disableCredentialType(realm, user, credentialType); @@ -243,11 +227,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser types.addAll(updater.getDisableableCredentialTypes(realm, user)); } } else { - UserFederationProvider link = session.users().getFederationLink(realm, user); - if (link != null) { - types.addAll(link.getDisableableCredentialTypes(realm, user)); - } - else if (user.getFederationLink() != null) { + if (user.getFederationLink() != null) { UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof CredentialInputUpdater) { types.addAll(((CredentialInputUpdater)provider).getDisableableCredentialTypes(realm, user)); @@ -275,13 +255,7 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser } } } else { - // - UserFederationProvider link = session.users().getFederationLink(realm, user); - if (link != null) { - if (link.isConfiguredFor(realm, user, type)) return true; - } - // - else if (user.getFederationLink() != null) { + if (user.getFederationLink() != null) { UserStorageProvider provider = UserStorageManager.getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof CredentialInputValidator) { if (((CredentialInputValidator)provider).isConfiguredFor(realm, user, type)) return true; @@ -307,16 +281,6 @@ public class UserCredentialStoreManager implements UserCredentialManager, OnUser @Override public CredentialValidationOutput authenticate(KeycloakSession session, RealmModel realm, CredentialInput input) { - List fedProviderModels = realm.getUserFederationProviders(); - List fedProviders = new ArrayList(); - for (UserFederationProviderModel fedProviderModel : fedProviderModels) { - UserFederationProvider provider = session.users().getFederationProvider(fedProviderModel); - if (input instanceof UserCredentialModel && provider != null && provider.supportsCredentialType(input.getType())) { - CredentialValidationOutput output = provider.validCredentials(realm, (UserCredentialModel)input); - if (output != null) return output; - } - } - List list = UserStorageManager.getStorageProviders(session, realm, CredentialAuthentication.class); for (CredentialAuthentication auth : list) { if (auth.supportsCredentialAuthenticationFor(input.getType())) { diff --git a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java index 62c31579ca..7ae30e7b6b 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java +++ b/services/src/main/java/org/keycloak/exportimport/util/ExportUtils.java @@ -46,6 +46,7 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserFederationManager; import org.keycloak.models.UserModel; +import org.keycloak.models.UserProvider; import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientTemplateRepresentation; @@ -358,7 +359,7 @@ public class ExportUtils { String users = config.get("users"); if (users != null && !users.isEmpty()) { - UserFederationManager userManager = session.users(); + UserProvider userManager = session.users(); List userIds = JsonSerialization.readValue(users, List.class); config.put("users", JsonSerialization.writeValueAsString(userIds.stream().map(userId -> userManager.getUserById(userId, realm).getUsername()).collect(Collectors.toList()))); } diff --git a/services/src/main/java/org/keycloak/services/managers/RealmManager.java b/services/src/main/java/org/keycloak/services/managers/RealmManager.java index d13dab6631..9d30df9aa3 100755 --- a/services/src/main/java/org/keycloak/services/managers/RealmManager.java +++ b/services/src/main/java/org/keycloak/services/managers/RealmManager.java @@ -228,7 +228,6 @@ public class RealmManager implements RealmImporter { } public boolean removeRealm(RealmModel realm) { - List federationProviders = realm.getUserFederationProviders(); ClientModel masterAdminClient = realm.getMasterAdminClient(); boolean removed = model.removeRealm(realm.getId()); @@ -247,11 +246,13 @@ public class RealmManager implements RealmImporter { sessionsPersister.onRealmRemoved(realm); } - // Remove all periodic syncs for configured federation providers - UsersSyncManager usersSyncManager = new UsersSyncManager(); - for (final UserFederationProviderModel fedProvider : federationProviders) { - usersSyncManager.notifyToRefreshPeriodicSync(session, realm, fedProvider, true); + // Refresh periodic sync tasks for configured storageProviders + List storageProviders = realm.getUserStorageProviders(); + UserStorageSyncManager storageSync = new UserStorageSyncManager(); + for (UserStorageProviderModel provider : storageProviders) { + storageSync.notifyToRefreshPeriodicSync(session, realm, provider, true); } + } return removed; } @@ -487,13 +488,6 @@ public class RealmManager implements RealmImporter { setupAuthenticationFlows(realm); setupRequiredActions(realm); - // Refresh periodic sync tasks for configured federationProviders - List federationProviders = realm.getUserFederationProviders(); - UsersSyncManager usersSyncManager = new UsersSyncManager(); - for (final UserFederationProviderModel fedProvider : federationProviders) { - usersSyncManager.notifyToRefreshPeriodicSync(session, realm, fedProvider, false); - } - // Refresh periodic sync tasks for configured storageProviders List storageProviders = realm.getUserStorageProviders(); UserStorageSyncManager storageSync = new UserStorageSyncManager(); diff --git a/services/src/main/java/org/keycloak/services/managers/UsersSyncManager.java b/services/src/main/java/org/keycloak/services/managers/UsersSyncManager.java deleted file mode 100755 index 21b0cad243..0000000000 --- a/services/src/main/java/org/keycloak/services/managers/UsersSyncManager.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.services.managers; - -import org.jboss.logging.Logger; -import org.keycloak.cluster.ClusterEvent; -import org.keycloak.cluster.ClusterListener; -import org.keycloak.cluster.ClusterProvider; -import org.keycloak.cluster.ExecutionResult; -import org.keycloak.common.util.Time; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.KeycloakSessionTask; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.services.ServicesLogger; -import org.keycloak.timer.TimerProvider; - -import java.util.List; -import java.util.concurrent.Callable; - -/** - * @author Marek Posolda - */ -public class UsersSyncManager { - - private static final String FEDERATION_TASK_KEY = "federation"; - - private static final Logger logger = Logger.getLogger(UsersSyncManager.class); - - /** - * Check federationProviderModel of all realms and possibly start periodic sync for them - * - * @param sessionFactory - * @param timer - */ - public void bootstrapPeriodic(final KeycloakSessionFactory sessionFactory, final TimerProvider timer) { - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - List realms = session.realms().getRealms(); - for (final RealmModel realm : realms) { - List federationProviders = realm.getUserFederationProviders(); - for (final UserFederationProviderModel fedProvider : federationProviders) { - refreshPeriodicSyncForProvider(sessionFactory, timer, fedProvider, realm.getId()); - } - } - - ClusterProvider clusterProvider = session.getProvider(ClusterProvider.class); - clusterProvider.registerListener(FEDERATION_TASK_KEY, new UserFederationClusterListener(sessionFactory)); - } - }); - } - - - private class Holder { - ExecutionResult result; - } - - public UserFederationSyncResult syncAllUsers(final KeycloakSessionFactory sessionFactory, final String realmId, final UserFederationProviderModel fedProvider) { - final Holder holder = new Holder(); - - // Ensure not executed concurrently on this or any other cluster node - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - ClusterProvider clusterProvider = session.getProvider(ClusterProvider.class); - // shared key for "full" and "changed" . Improve if needed - String taskKey = fedProvider.getId() + "::sync"; - - // 30 seconds minimal timeout for now - int timeout = Math.max(30, fedProvider.getFullSyncPeriod()); - holder.result = clusterProvider.executeIfNotExecuted(taskKey, timeout, new Callable() { - - @Override - public UserFederationSyncResult call() throws Exception { - final UserFederationProviderFactory fedProviderFactory = (UserFederationProviderFactory) sessionFactory.getProviderFactory(UserFederationProvider.class, fedProvider.getProviderName()); - updateLastSyncInterval(sessionFactory, fedProvider, realmId); - return fedProviderFactory.syncAllUsers(sessionFactory, realmId, fedProvider); - } - - }); - } - - }); - - if (holder.result == null || !holder.result.isExecuted()) { - logger.debugf("syncAllUsers for federation provider %s was ignored as it's already in progress", fedProvider.getDisplayName()); - return UserFederationSyncResult.ignored(); - } else { - return holder.result.getResult(); - } - } - - public UserFederationSyncResult syncChangedUsers(final KeycloakSessionFactory sessionFactory, final String realmId, final UserFederationProviderModel fedProvider) { - final Holder holder = new Holder(); - - // Ensure not executed concurrently on this or any other cluster node - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - ClusterProvider clusterProvider = session.getProvider(ClusterProvider.class); - // shared key for "full" and "changed" . Improve if needed - String taskKey = fedProvider.getId() + "::sync"; - - // 30 seconds minimal timeout for now - int timeout = Math.max(30, fedProvider.getChangedSyncPeriod()); - holder.result = clusterProvider.executeIfNotExecuted(taskKey, timeout, new Callable() { - - @Override - public UserFederationSyncResult call() throws Exception { - final UserFederationProviderFactory fedProviderFactory = (UserFederationProviderFactory) sessionFactory.getProviderFactory(UserFederationProvider.class, fedProvider.getProviderName()); - - // See when we did last sync. - int oldLastSync = fedProvider.getLastSync(); - updateLastSyncInterval(sessionFactory, fedProvider, realmId); - return fedProviderFactory.syncChangedUsers(sessionFactory, realmId, fedProvider, Time.toDate(oldLastSync)); - } - - }); - } - - }); - - if (holder.result == null || !holder.result.isExecuted()) { - logger.debugf("syncChangedUsers for federation provider %s was ignored as it's already in progress", fedProvider.getDisplayName()); - return UserFederationSyncResult.ignored(); - } else { - return holder.result.getResult(); - } - } - - - // Ensure all cluster nodes are notified - public void notifyToRefreshPeriodicSync(KeycloakSession session, RealmModel realm, UserFederationProviderModel federationProvider, boolean removed) { - FederationProviderClusterEvent event = FederationProviderClusterEvent.createEvent(removed, realm.getId(), federationProvider); - session.getProvider(ClusterProvider.class).notify(FEDERATION_TASK_KEY, event, false); - } - - - // Executed once it receives notification that some UserFederationProvider was created or updated - protected void refreshPeriodicSyncForProvider(final KeycloakSessionFactory sessionFactory, TimerProvider timer, final UserFederationProviderModel fedProvider, final String realmId) { - logger.debugf("Going to refresh periodic sync for provider '%s' . Full sync period: %d , changed users sync period: %d", - fedProvider.getDisplayName(), fedProvider.getFullSyncPeriod(), fedProvider.getChangedSyncPeriod()); - - if (fedProvider.getFullSyncPeriod() > 0) { - // We want periodic full sync for this provider - timer.schedule(new Runnable() { - - @Override - public void run() { - try { - boolean shouldPerformSync = shouldPerformNewPeriodicSync(fedProvider.getLastSync(), fedProvider.getChangedSyncPeriod()); - if (shouldPerformSync) { - syncAllUsers(sessionFactory, realmId, fedProvider); - } else { - logger.debugf("Ignored periodic full sync with federation provider %s due small time since last sync", fedProvider.getDisplayName()); - } - } catch (Throwable t) { - ServicesLogger.LOGGER.errorDuringFullUserSync(t); - } - } - - }, fedProvider.getFullSyncPeriod() * 1000, fedProvider.getId() + "-FULL"); - } else { - timer.cancelTask(fedProvider.getId() + "-FULL"); - } - - if (fedProvider.getChangedSyncPeriod() > 0) { - // We want periodic sync of just changed users for this provider - timer.schedule(new Runnable() { - - @Override - public void run() { - try { - boolean shouldPerformSync = shouldPerformNewPeriodicSync(fedProvider.getLastSync(), fedProvider.getChangedSyncPeriod()); - if (shouldPerformSync) { - syncChangedUsers(sessionFactory, realmId, fedProvider); - } else { - logger.debugf("Ignored periodic changed-users sync with federation provider %s due small time since last sync", fedProvider.getDisplayName()); - } - } catch (Throwable t) { - ServicesLogger.LOGGER.errorDuringChangedUserSync(t); - } - } - - }, fedProvider.getChangedSyncPeriod() * 1000, fedProvider.getId() + "-CHANGED"); - - } else { - timer.cancelTask(fedProvider.getId() + "-CHANGED"); - } - } - - // Skip syncing if there is short time since last sync time. - private boolean shouldPerformNewPeriodicSync(int lastSyncTime, int period) { - if (lastSyncTime <= 0) { - return true; - } - - int currentTime = Time.currentTime(); - int timeSinceLastSync = currentTime - lastSyncTime; - - return (timeSinceLastSync * 2 > period); - } - - // Executed once it receives notification that some UserFederationProvider was removed - protected void removePeriodicSyncForProvider(TimerProvider timer, UserFederationProviderModel fedProvider) { - logger.debugf("Removing periodic sync for provider %s", fedProvider.getDisplayName()); - timer.cancelTask(fedProvider.getId() + "-FULL"); - timer.cancelTask(fedProvider.getId() + "-CHANGED"); - } - - // Update interval of last sync for given UserFederationProviderModel. Do it in separate transaction - private void updateLastSyncInterval(final KeycloakSessionFactory sessionFactory, final UserFederationProviderModel fedProvider, final String realmId) { - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - RealmModel persistentRealm = session.realms().getRealm(realmId); - List persistentFedProviders = persistentRealm.getUserFederationProviders(); - for (UserFederationProviderModel persistentFedProvider : persistentFedProviders) { - if (fedProvider.getId().equals(persistentFedProvider.getId())) { - // Update persistent provider in DB - int lastSync = Time.currentTime(); - persistentFedProvider.setLastSync(lastSync); - persistentRealm.updateUserFederationProvider(persistentFedProvider); - - // Update "cached" reference - fedProvider.setLastSync(lastSync); - } - } - } - - }); - } - - - private class UserFederationClusterListener implements ClusterListener { - - private final KeycloakSessionFactory sessionFactory; - - public UserFederationClusterListener(KeycloakSessionFactory sessionFactory) { - this.sessionFactory = sessionFactory; - } - - @Override - public void eventReceived(ClusterEvent event) { - final FederationProviderClusterEvent fedEvent = (FederationProviderClusterEvent) event; - KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { - - @Override - public void run(KeycloakSession session) { - TimerProvider timer = session.getProvider(TimerProvider.class); - if (fedEvent.isRemoved()) { - removePeriodicSyncForProvider(timer, fedEvent.getFederationProvider()); - } else { - refreshPeriodicSyncForProvider(sessionFactory, timer, fedEvent.getFederationProvider(), fedEvent.getRealmId()); - } - } - - }); - } - } - - - // Send to cluster during each update or remove of federationProvider, so all nodes can update sync periods - public static class FederationProviderClusterEvent implements ClusterEvent { - - private boolean removed; - private String realmId; - private UserFederationProviderModel federationProvider; - - public boolean isRemoved() { - return removed; - } - - public void setRemoved(boolean removed) { - this.removed = removed; - } - - public String getRealmId() { - return realmId; - } - - public void setRealmId(String realmId) { - this.realmId = realmId; - } - - public UserFederationProviderModel getFederationProvider() { - return federationProvider; - } - - public void setFederationProvider(UserFederationProviderModel federationProvider) { - this.federationProvider = federationProvider; - } - - public static FederationProviderClusterEvent createEvent(boolean removed, String realmId, UserFederationProviderModel fedProvider) { - FederationProviderClusterEvent notification = new FederationProviderClusterEvent(); - notification.setRemoved(removed); - notification.setRealmId(realmId); - notification.setFederationProvider(fedProvider); - return notification; - } - } - -} diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index 2ea9992fd2..15315d686e 100644 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -46,7 +46,6 @@ import org.keycloak.services.filters.KeycloakTransactionCommitter; import org.keycloak.services.managers.ApplianceBootstrap; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.UserStorageSyncManager; -import org.keycloak.services.managers.UsersSyncManager; import org.keycloak.services.resources.admin.AdminRoot; import org.keycloak.services.scheduled.ClearExpiredEvents; import org.keycloak.services.scheduled.ClearExpiredUserSessions; @@ -323,7 +322,6 @@ public class KeycloakApplication extends Application { TimerProvider timer = session.getProvider(TimerProvider.class); timer.schedule(new ClusterAwareScheduledTaskRunner(sessionFactory, new ClearExpiredEvents(), interval), interval, "ClearExpiredEvents"); timer.schedule(new ScheduledTaskRunner(sessionFactory, new ClearExpiredUserSessions()), interval, "ClearExpiredUserSessions"); - new UsersSyncManager().bootstrapPeriodic(sessionFactory, timer); new UserStorageSyncManager().bootstrapPeriodic(sessionFactory, timer); } finally { session.close(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index fb5241ce59..f71c6af721 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -42,7 +42,6 @@ import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.cache.CacheRealmProvider; import org.keycloak.models.cache.UserCache; @@ -66,8 +65,9 @@ import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.LDAPConnectionTestManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.ResourceAdminManager; -import org.keycloak.services.managers.UsersSyncManager; +import org.keycloak.services.managers.UserStorageSyncManager; import org.keycloak.services.resources.admin.RealmAuth.Resource; +import org.keycloak.storage.UserStorageProviderModel; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -304,9 +304,9 @@ public class RealmAdminResource { RepresentationToModel.updateRealm(rep, realm, session); // Refresh periodic sync tasks for configured federationProviders - List federationProviders = realm.getUserFederationProviders(); - UsersSyncManager usersSyncManager = new UsersSyncManager(); - for (final UserFederationProviderModel fedProvider : federationProviders) { + List federationProviders = realm.getUserStorageProviders(); + UserStorageSyncManager usersSyncManager = new UserStorageSyncManager(); + for (final UserStorageProviderModel fedProvider : federationProviders) { usersSyncManager.notifyToRefreshPeriodicSync(session, realm, fedProvider, false); } @@ -348,14 +348,6 @@ public class RealmAdminResource { return users; } - @Path("user-federation") - public UserFederationProvidersResource userFederation() { - UserFederationProvidersResource fed = new UserFederationProvidersResource(realm, auth, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(fed); - //resourceContext.initResource(fed); - return fed; - } - @Path("user-storage") public UserStorageProviderResource userStorage() { UserStorageProviderResource fed = new UserStorageProviderResource(realm, auth, adminEvent); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java deleted file mode 100755 index 54ab7723bd..0000000000 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.services.resources.admin; - -import org.jboss.logging.Logger; -import org.jboss.resteasy.annotations.cache.NoCache; -import org.jboss.resteasy.spi.NotFoundException; -import org.keycloak.events.admin.OperationType; -import org.keycloak.events.admin.ResourceType; -import org.keycloak.mappers.FederationConfigValidationException; -import org.keycloak.mappers.UserFederationMapper; -import org.keycloak.mappers.UserFederationMapperFactory; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.ModelDuplicateException; -import org.keycloak.models.ModelException; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.models.utils.ModelToRepresentation; -import org.keycloak.models.utils.RepresentationToModel; -import org.keycloak.provider.ProviderConfigProperty; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.representations.idm.ConfigPropertyRepresentation; -import org.keycloak.representations.idm.UserFederationMapperRepresentation; -import org.keycloak.representations.idm.UserFederationMapperTypeRepresentation; -import org.keycloak.representations.idm.UserFederationProviderRepresentation; -import org.keycloak.services.ErrorResponse; -import org.keycloak.services.ErrorResponseException; -import org.keycloak.services.ServicesLogger; -import org.keycloak.services.managers.UsersSyncManager; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; -import java.text.MessageFormat; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -/** - * @author Marek Posolda - */ -public class UserFederationProviderResource { - - private static final Logger logger = Logger.getLogger(UserFederationProviderResource.class); - - private final KeycloakSession session; - private final RealmModel realm; - private final RealmAuth auth; - private final UserFederationProviderModel federationProviderModel; - private final AdminEventBuilder adminEvent; - - @Context - private UriInfo uriInfo; - - public UserFederationProviderResource(KeycloakSession session, RealmModel realm, RealmAuth auth, UserFederationProviderModel federationProviderModel, AdminEventBuilder adminEvent) { - this.session = session; - this.realm = realm; - this.auth = auth; - this.federationProviderModel = federationProviderModel; - this.adminEvent = adminEvent.resource(ResourceType.USER_FEDERATION_PROVIDER); - } - - /** - * Update a provider - * - * @param rep - */ - @PUT - @NoCache - @Consumes(MediaType.APPLICATION_JSON) - public Response updateProviderInstance(UserFederationProviderRepresentation rep) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - try { - String displayName = rep.getDisplayName(); - if (displayName != null && displayName.trim().equals("")) { - displayName = null; - } - UserFederationProviderModel model = new UserFederationProviderModel(rep.getId(), rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName, - rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync()); - - UserFederationProvidersResource.validateFederationProviderConfig(session, auth, realm, model); - - realm.updateUserFederationProvider(model); - new UsersSyncManager().notifyToRefreshPeriodicSync(session, realm, model, false); - boolean kerberosCredsAdded = UserFederationProvidersResource.checkKerberosCredential(session, realm, model); - if (kerberosCredsAdded) { - ServicesLogger.LOGGER.addedKerberosToRealmCredentials(); - } - - adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); - return Response.noContent().build(); - } catch (ModelDuplicateException e) { - if (session.getTransactionManager().isActive()) { - session.getTransactionManager().setRollbackOnly(); - } - return ErrorResponse.exists("Federation provider exists with same name."); - } catch (ModelException me) { - if (session.getTransactionManager().isActive()) { - session.getTransactionManager().setRollbackOnly(); - } - return ErrorResponse.error("Unable to update federation provider.", Response.Status.INTERNAL_SERVER_ERROR); - } - } - - /** - * Get a provider - * - */ - @GET - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public UserFederationProviderRepresentation getProviderInstance() { - auth.requireView(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - return ModelToRepresentation.toRepresentation(this.federationProviderModel); - } - - /** - * Delete a provider - * - */ - @DELETE - @NoCache - public void deleteProviderInstance() { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - realm.removeUserFederationProvider(this.federationProviderModel); - new UsersSyncManager().notifyToRefreshPeriodicSync(session, realm, this.federationProviderModel, true); - - adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); - - } - - /** - * Trigger sync of users - * - * @return - */ - @POST - @Path("sync") - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public UserFederationSyncResult syncUsers(@QueryParam("action") String action) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - logger.debug("Syncing users"); - - UsersSyncManager syncManager = new UsersSyncManager(); - UserFederationSyncResult syncResult; - if ("triggerFullSync".equals(action)) { - syncResult = syncManager.syncAllUsers(session.getKeycloakSessionFactory(), realm.getId(), this.federationProviderModel); - } else if ("triggerChangedUsersSync".equals(action)) { - syncResult = syncManager.syncChangedUsers(session.getKeycloakSessionFactory(), realm.getId(), this.federationProviderModel); - } else { - throw new NotFoundException("Unknown action: " + action); - } - - Map eventRep = new HashMap<>(); - eventRep.put("action", action); - eventRep.put("result", syncResult); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(eventRep).success(); - - return syncResult; - } - - /** - * Get available user federation mapper types - * - * @return - */ - @GET - @Path("mapper-types") - @Produces(MediaType.APPLICATION_JSON) - @NoCache - public Map getMapperTypes() { - auth.requireView(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); - Map types = new HashMap<>(); - List factories = sessionFactory.getProviderFactories(UserFederationMapper.class); - - for (ProviderFactory factory : factories) { - UserFederationMapperFactory mapperFactory = (UserFederationMapperFactory)factory; - if (mapperFactory.getFederationProviderType().equals(this.federationProviderModel.getProviderName())) { - - UserFederationMapperTypeRepresentation rep = new UserFederationMapperTypeRepresentation(); - rep.setId(mapperFactory.getId()); - rep.setCategory(mapperFactory.getDisplayCategory()); - rep.setName(mapperFactory.getDisplayType()); - rep.setHelpText(mapperFactory.getHelpText()); - rep.setSyncConfig(mapperFactory.getSyncConfig()); - List configProperties = mapperFactory.getConfigProperties(); - for (ProviderConfigProperty prop : configProperties) { - ConfigPropertyRepresentation propRep = ModelToRepresentation.toRepresentation(prop); - rep.getProperties().add(propRep); - } - rep.setDefaultConfig(mapperFactory.getDefaultConfig(this.federationProviderModel)); - - types.put(rep.getId(), rep); - } - } - return types; - } - - /** - * Get mappers configured for this provider - * - * @return - */ - @GET - @Path("mappers") - @Produces(MediaType.APPLICATION_JSON) - @NoCache - public List getMappers() { - auth.requireView(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - List mappers = new LinkedList<>(); - for (UserFederationMapperModel model : realm.getUserFederationMappersByFederationProvider(this.federationProviderModel.getId())) { - mappers.add(ModelToRepresentation.toRepresentation(realm, model)); - } - - // Sort mappers by category,type,name - Collections.sort(mappers, new Comparator() { - - @Override - public int compare(UserFederationMapperRepresentation o1, UserFederationMapperRepresentation o2) { - UserFederationMapperFactory factory1 = (UserFederationMapperFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationMapper.class, o1.getFederationMapperType()); - UserFederationMapperFactory factory2 = (UserFederationMapperFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationMapper.class, o2.getFederationMapperType()); - - int compare = factory1.getDisplayCategory().compareTo(factory2.getDisplayCategory()); - if (compare != 0) return compare; - - compare = factory1.getDisplayType().compareTo(factory2.getDisplayType()); - if (compare != 0) return compare; - - compare = o1.getName().compareTo(o2.getName()); - return compare; - } - }); - - return mappers; - } - - /** - * Create a mapper - * - * @param mapper - * @return - */ - @POST - @Path("mappers") - @Consumes(MediaType.APPLICATION_JSON) - public Response addMapper(UserFederationMapperRepresentation mapper) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - UserFederationMapperModel model = RepresentationToModel.toModel(realm, mapper); - - validateModel(model); - - model = realm.addUserFederationMapper(model); - - adminEvent.operation(OperationType.CREATE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo, model.getId()) - .representation(mapper).success(); - - return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); - - } - - /** - * Get a mapper - * - * @param id Mapper id - * @return - */ - @GET - @NoCache - @Path("mappers/{id}") - @Produces(MediaType.APPLICATION_JSON) - public UserFederationMapperRepresentation getMapperById(@PathParam("id") String id) { - auth.requireView(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - UserFederationMapperModel model = realm.getUserFederationMapperById(id); - if (model == null) throw new NotFoundException("Model not found"); - return ModelToRepresentation.toRepresentation(realm, model); - } - - /** - * Update a mapper - * - * @param id Mapper id - * @param rep - */ - @PUT - @NoCache - @Path("mappers/{id}") - @Consumes(MediaType.APPLICATION_JSON) - public void update(@PathParam("id") String id, UserFederationMapperRepresentation rep) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - UserFederationMapperModel model = realm.getUserFederationMapperById(id); - if (model == null) throw new NotFoundException("Model not found"); - model = RepresentationToModel.toModel(realm, rep); - - validateModel(model); - - realm.updateUserFederationMapper(model); - adminEvent.operation(OperationType.UPDATE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo).representation(rep).success(); - - } - - /** - * Delete a mapper with a given id - * - * @param id Mapper id - */ - @DELETE - @NoCache - @Path("mappers/{id}") - public void delete(@PathParam("id") String id) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - UserFederationMapperModel model = realm.getUserFederationMapperById(id); - if (model == null) throw new NotFoundException("Model not found"); - realm.removeUserFederationMapper(model); - adminEvent.operation(OperationType.DELETE).resource(ResourceType.USER_FEDERATION_MAPPER).resourcePath(uriInfo).success(); - - } - - /** - * Trigger sync of mapper data related to federationMapper (roles, groups, ...) - * - * @return - */ - @POST - @Path("mappers/{id}/sync") - @NoCache - @Produces(MediaType.APPLICATION_JSON) - public UserFederationSyncResult syncMapperData(@PathParam("id") String mapperId, @QueryParam("direction") String direction) { - auth.requireManage(); - - if (federationProviderModel == null) { - throw new NotFoundException("Could not find federation provider"); - } - - UserFederationMapperModel mapperModel = realm.getUserFederationMapperById(mapperId); - if (mapperModel == null) throw new NotFoundException("Mapper model not found"); - UserFederationMapper mapper = session.getProvider(UserFederationMapper.class, mapperModel.getFederationMapperType()); - - UserFederationProviderModel providerModel = KeycloakModelUtils.findUserFederationProviderById(mapperModel.getFederationProviderId(), realm); - if (providerModel == null) throw new NotFoundException("Provider model not found"); - UserFederationProviderFactory providerFactory = (UserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, providerModel.getProviderName()); - UserFederationProvider federationProvider = providerFactory.getInstance(session, providerModel); - - ServicesLogger.LOGGER.syncingDataForMapper(mapperModel.getName(), mapperModel.getFederationMapperType(), direction); - - UserFederationSyncResult syncResult; - if ("fedToKeycloak".equals(direction)) { - syncResult = mapper.syncDataFromFederationProviderToKeycloak(mapperModel, federationProvider, session, realm); - } else if ("keycloakToFed".equals(direction)) { - syncResult = mapper.syncDataFromKeycloakToFederationProvider(mapperModel, federationProvider, session, realm); - } else { - throw new NotFoundException("Unknown direction: " + direction); - } - - Map eventRep = new HashMap<>(); - eventRep.put("action", direction); - eventRep.put("result", syncResult); - adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).representation(eventRep).success(); - return syncResult; - } - - private void validateModel(UserFederationMapperModel model) { - try { - UserFederationMapperFactory mapperFactory = (UserFederationMapperFactory) session.getKeycloakSessionFactory().getProviderFactory(UserFederationMapper.class, model.getFederationMapperType()); - mapperFactory.validateConfig(realm, federationProviderModel, model); - } catch (FederationConfigValidationException ex) { - logger.error(ex.getMessage()); - Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale()); - throw new ErrorResponseException(ex.getMessage(), MessageFormat.format(messages.getProperty(ex.getMessage(), ex.getMessage()), ex.getParameters()), - Response.Status.BAD_REQUEST); - } - } - -} diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java deleted file mode 100755 index fa1e139cc7..0000000000 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.keycloak.services.resources.admin; - -import org.jboss.logging.Logger; -import org.jboss.resteasy.annotations.cache.NoCache; -import org.jboss.resteasy.spi.NotFoundException; -import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.keycloak.common.constants.KerberosConstants; -import org.keycloak.component.ComponentModel; -import org.keycloak.events.admin.OperationType; -import org.keycloak.events.admin.ResourceType; -import org.keycloak.mappers.FederationConfigValidationException; -import org.keycloak.models.AuthenticationExecutionModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelDuplicateException; -import org.keycloak.models.ModelException; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderFactory; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationValidatingProviderFactory; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.models.utils.ModelToRepresentation; -import org.keycloak.provider.ConfiguredProvider; -import org.keycloak.provider.ProviderConfigProperty; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.representations.idm.ConfigPropertyRepresentation; -import org.keycloak.representations.idm.CredentialRepresentation; -import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation; -import org.keycloak.representations.idm.UserFederationProviderRepresentation; -import org.keycloak.services.ErrorResponse; -import org.keycloak.services.ErrorResponseException; -import org.keycloak.services.ServicesLogger; -import org.keycloak.services.managers.UsersSyncManager; -import org.keycloak.utils.CredentialHelper; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -/** - * Base resource for managing users - * - * @author Bill Burke - * @version $Revision: 1 $ - */ -public class UserFederationProvidersResource { - private static final Logger logger = Logger.getLogger(UserFederationProvidersResource.class); - - protected RealmModel realm; - - protected RealmAuth auth; - - protected AdminEventBuilder adminEvent; - - @Context - protected UriInfo uriInfo; - - @Context - protected KeycloakSession session; - - public UserFederationProvidersResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) { - this.auth = auth; - this.realm = realm; - this.adminEvent = adminEvent.resource(ResourceType.USER_FEDERATION_PROVIDER); - - auth.init(RealmAuth.Resource.REALM); - } - - /** - * Automatically add "kerberos" to required realm credentials if it's supported by saved provider - * - * @param realm - * @param model - * @return true if kerberos credentials were added - */ - public static boolean checkKerberosCredential(KeycloakSession session, RealmModel realm, UserFederationProviderModel model) { - String allowKerberosCfg = model.getConfig().get(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION); - if (Boolean.valueOf(allowKerberosCfg)) { - CredentialHelper.setOrReplaceAuthenticationRequirement(session, realm, CredentialRepresentation.KERBEROS, - AuthenticationExecutionModel.Requirement.ALTERNATIVE, AuthenticationExecutionModel.Requirement.DISABLED); - return true; - } - - return false; - } - - public static void validateFederationProviderConfig(KeycloakSession session, RealmAuth auth, RealmModel realm, UserFederationProviderModel model) { - UserFederationProviderFactory providerFactory = KeycloakModelUtils.getFederationProviderFactory(session, model); - if (providerFactory instanceof UserFederationValidatingProviderFactory) { - try { - ((UserFederationValidatingProviderFactory) providerFactory).validateConfig(realm, model); - } catch (FederationConfigValidationException fcve) { - logger.error(fcve.getMessage()); - Properties messages = AdminRoot.getMessages(session, realm, auth.getAuth().getToken().getLocale()); - throw new ErrorResponseException(fcve.getMessage(), MessageFormat.format(messages.getProperty(fcve.getMessage(), fcve.getMessage()), fcve.getParameters()), - Response.Status.BAD_REQUEST); - } - } - } - - /** - * Get available provider factories - * - * Returns a list of available provider factories. - * - * @return - */ - @GET - @NoCache - @Path("providers") - @Produces(MediaType.APPLICATION_JSON) - public List getProviders() { - auth.requireView(); - - List providers = new LinkedList(); - for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) { - UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation(); - rep.setId(factory.getId()); - rep.setOptions(((UserFederationProviderFactory)factory).getConfigurationOptions()); - providers.add(rep); - } - return providers; - } - - /** - * Get factory with given id - * - * @return - */ - @GET - @NoCache - @Path("providers/{id}") - @Produces(MediaType.APPLICATION_JSON) - public UserFederationProviderFactoryRepresentation getProvider(@PathParam("id") String id) { - auth.requireView(); - - for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) { - if (!factory.getId().equals(id)) { - continue; - } - - if (factory instanceof ConfiguredProvider) { - - UserFederationProviderFactoryDescription rep = new UserFederationProviderFactoryDescription(); - rep.setId(factory.getId()); - - ConfiguredProvider cp = (ConfiguredProvider) factory; - rep.setHelpText(cp.getHelpText()); - rep.setProperties(toConfigPropertyRepresentationList(cp.getConfigProperties())); - - return rep; - } - - UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation(); - rep.setId(factory.getId()); - rep.setOptions(((UserFederationProviderFactory) factory).getConfigurationOptions()); - - return rep; - } - throw new NotFoundException("Could not find provider"); - } - - /** - * Create a provider - * - * @param rep - * @return - */ - @POST - @Path("instances") - @Consumes(MediaType.APPLICATION_JSON) - public Response createProviderInstance(UserFederationProviderRepresentation rep) { - auth.requireManage(); - - try { - String displayName = rep.getDisplayName(); - if (displayName != null && displayName.trim().equals("")) { - displayName = null; - } - - UserFederationProviderModel tempModel = new UserFederationProviderModel(null, rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName, rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync()); - validateFederationProviderConfig(session, auth, realm, tempModel); - - UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName, - rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync()); - new UsersSyncManager().notifyToRefreshPeriodicSync(session, realm, model, false); - boolean kerberosCredsAdded = checkKerberosCredential(session, realm, model); - if (kerberosCredsAdded) { - ServicesLogger.LOGGER.addedKerberosToRealmCredentials(); - } - - rep.setId(model.getId()); - adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, model.getId()).representation(rep).success(); - - return Response.created(uriInfo.getAbsolutePathBuilder().path(model.getId()).build()).build(); - } catch (ModelDuplicateException e) { - if (session.getTransactionManager().isActive()) { - session.getTransactionManager().setRollbackOnly(); - } - return ErrorResponse.exists("Federation provider exists with same name."); - } catch (ModelException me){ - if (session.getTransactionManager().isActive()) { - session.getTransactionManager().setRollbackOnly(); - } - return ErrorResponse.error("Could not create federation provider.", Response.Status.INTERNAL_SERVER_ERROR); - } - } - - /** - * Get configured providers - * - * @return - */ - @GET - @Path("instances") - @Produces(MediaType.APPLICATION_JSON) - @NoCache - public List getUserFederationInstances() { - auth.requireView(); - - List reps = new LinkedList(); - for (UserFederationProviderModel model : realm.getUserFederationProviders()) { - UserFederationProviderRepresentation rep = ModelToRepresentation.toRepresentation(model); - reps.add(rep); - } - return reps; - } - - @Path("instances/{id}") - public UserFederationProviderResource getUserFederationInstance(@PathParam("id") String id) { - this.auth.requireView(); - - UserFederationProviderModel model = KeycloakModelUtils.findUserFederationProviderById(id, realm); - UserFederationProviderResource instanceResource = new UserFederationProviderResource(session, realm, this.auth, model, adminEvent); - ResteasyProviderFactory.getInstance().injectProperties(instanceResource); - return instanceResource; - } - - // TODO: This endpoint exists, so that admin console can lookup userFederation provider OR userStorage provider by federationLink. - // TODO: Endpoint should be removed once UserFederation SPI is removed as fallback is not needed anymore than - @GET - @Path("instances-with-fallback/{id}") - @Produces(MediaType.APPLICATION_JSON) - @NoCache - public Map getUserFederationInstanceWithFallback(@PathParam("id") String id) { - this.auth.requireView(); - - Map result = new HashMap<>(); - UserFederationProviderModel model = KeycloakModelUtils.findUserFederationProviderById(id, realm); - if (model != null) { - result.put("federationLinkName", model.getDisplayName()); - result.put("federationLink", "#/realms/" + realm.getName() + "/user-federation/providers/" + model.getProviderName() + "/" + model.getId()); - return result; - } else { - ComponentModel userStorage = KeycloakModelUtils.findUserStorageProviderById(id, realm); - if (userStorage != null) { - result.put("federationLinkName", userStorage.getName()); - result.put("federationLink", "#/realms/" + realm.getName() + "/user-storage/providers/" + userStorage.getProviderId() + "/" + userStorage.getId()); - return result; - } else { - throw new NotFoundException("Could not find federation provider or userStorage provider"); - } - } - } - - - private ConfigPropertyRepresentation toConfigPropertyRepresentation(ProviderConfigProperty prop) { - return ModelToRepresentation.toRepresentation(prop); - } - - private List toConfigPropertyRepresentationList(List props) { - - List reps = new ArrayList<>(props.size()); - for(ProviderConfigProperty prop : props){ - reps.add(toConfigPropertyRepresentation(prop)); - } - - return reps; - } - - - public static class UserFederationProviderFactoryDescription extends UserFederationProviderFactoryRepresentation { - - protected String name; - - protected String helpText; - - protected List properties; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getHelpText() { - return helpText; - } - - public void setHelpText(String helpText) { - this.helpText = helpText; - } - - public List getProperties() { - return properties; - } - - public void setProperties(List properties) { - this.properties = properties; - } - } -} diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java index e3eeaecb71..9c8b4ce9fb 100755 --- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -25,6 +25,7 @@ import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.FederatedIdentityModel; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionTask; import org.keycloak.models.ModelException; import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.RealmModel; @@ -32,6 +33,7 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserConsentModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserFederationProviderModel; +import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.cache.CachedUserModel; @@ -52,6 +54,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -244,13 +248,39 @@ public class UserStorageManager implements UserProvider, OnUserCache { if (user == null || user.getFederationLink() == null) return user; UserStorageProvider provider = getStorageProvider(session, realm, user.getFederationLink()); if (provider != null && provider instanceof ImportedUserValidation) { - return ((ImportedUserValidation)provider).validate(realm, user); + UserModel validated = ((ImportedUserValidation)provider).validate(realm, user); + if (validated == null) { + deleteInvalidUser(realm, user); + return null; + } else { + return validated; + } + } else { return user; } } + protected void deleteInvalidUser(final RealmModel realm, final UserModel user) { + String userId = user.getId(); + String userName = user.getUsername(); + session.getUserCache().evict(realm, user); + runJobInTransaction(session.getKeycloakSessionFactory(), new KeycloakSessionTask() { + + @Override + public void run(KeycloakSession session) { + RealmModel realmModel = session.realms().getRealm(realm.getId()); + if (realmModel == null) return; + UserModel deletedUser = session.userLocalStorage().getUserById(userId, realmModel); + new UserManager(session).removeUser(realmModel, deletedUser, session.userLocalStorage()); + logger.debugf("Removed invalid user '%s'", userName); + } + + }); + } + + protected List importValidation(RealmModel realm, List users) { List tmp = new LinkedList<>(); for (UserModel user : users) { diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyConfigurableUserFederationProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyConfigurableUserFederationProviderFactory.java deleted file mode 100644 index f3d701db1e..0000000000 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyConfigurableUserFederationProviderFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.testsuite.federation; - -import org.keycloak.provider.ConfiguredProvider; -import org.keycloak.provider.ProviderConfigProperty; - -import java.util.Arrays; -import java.util.List; - -/** - * @author Marek Posolda - */ -public class DummyConfigurableUserFederationProviderFactory extends DummyUserFederationProviderFactory implements ConfiguredProvider { - - public static final String PROVIDER_NAME = "dummy-configurable"; - - @Override - public String getId() { - return PROVIDER_NAME; - } - - @Override - public String getHelpText() { - return "Dummy User Federation Provider Help Text"; - } - - @Override - public List getConfigProperties() { - - ProviderConfigProperty prop1 = new ProviderConfigProperty(); - prop1.setName("prop1"); - prop1.setLabel("Prop1"); - prop1.setDefaultValue("prop1Default"); - prop1.setHelpText("Prop1 HelpText"); - prop1.setType(ProviderConfigProperty.STRING_TYPE); - - ProviderConfigProperty prop2 = new ProviderConfigProperty(); - prop2.setName("prop2"); - prop2.setLabel("Prop2"); - prop2.setDefaultValue("true"); - prop2.setHelpText("Prop2 HelpText"); - prop2.setType(ProviderConfigProperty.BOOLEAN_TYPE); - - return Arrays.asList(prop1, prop2); - } -} diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java deleted file mode 100644 index d12a1cfb42..0000000000 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationMapper.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.testsuite.federation; - -import org.keycloak.Config; -import org.keycloak.mappers.FederationConfigValidationException; -import org.keycloak.mappers.UserFederationMapper; -import org.keycloak.mappers.UserFederationMapperFactory; -import org.keycloak.models.GroupModel; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.KeycloakSessionFactory; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProvider; -import org.keycloak.models.UserFederationProviderModel; -import org.keycloak.models.UserFederationSyncResult; -import org.keycloak.models.UserModel; -import org.keycloak.provider.ProviderConfigProperty; -import org.keycloak.representations.idm.UserFederationMapperSyncConfigRepresentation; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * @author Marek Posolda - */ -public class DummyUserFederationMapper implements UserFederationMapperFactory, UserFederationMapper { - - public static final String PROVIDER_NAME = "dummy-mapper"; - - @Override - public String getFederationProviderType() { - return DummyUserFederationProviderFactory.PROVIDER_NAME; - } - - @Override - public String getDisplayCategory() { - return "Dummy"; - } - - @Override - public String getDisplayType() { - return "Dummy"; - } - - @Override - public UserFederationMapperSyncConfigRepresentation getSyncConfig() { - return new UserFederationMapperSyncConfigRepresentation(true, "dummyFedToKeycloak", true, "dummyKeycloakToFed"); - } - - @Override - public void validateConfig(RealmModel realm, UserFederationProviderModel fedProviderModel, UserFederationMapperModel mapperModel) throws FederationConfigValidationException { - - } - - @Override - public Map getDefaultConfig(UserFederationProviderModel providerModel) { - return Collections.emptyMap(); - } - - @Override - public String getHelpText() { - return "Dummy"; - } - - @Override - public List getConfigProperties() { - return Collections.emptyList(); - } - - @Override - public UserFederationMapper create(KeycloakSession session) { - return this; - } - - @Override - public void init(Config.Scope config) { - - } - - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - - @Override - public void close() { - - } - - @Override - public String getId() { - return PROVIDER_NAME; - } - - @Override - public UserFederationSyncResult syncDataFromFederationProviderToKeycloak(final UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm) { - return new UserFederationSyncResult() { - - @Override - public String getStatus() { - return "dummyFedToKeycloakSuccess mapper=" + mapperModel.getName(); - } - - }; - } - - @Override - public UserFederationSyncResult syncDataFromKeycloakToFederationProvider(final UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, KeycloakSession session, RealmModel realm) { - return new UserFederationSyncResult() { - - @Override - public String getStatus() { - return "dummyKeycloakToFedSuccess mapper=" + mapperModel.getName(); - } - - }; - } - - @Override - public List getGroupMembers(UserFederationMapperModel mapperModel, UserFederationProvider federationProvider, RealmModel realm, GroupModel group, int firstResult, int maxResults) { - return Collections.emptyList(); - } -} diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java index c0dd8d58a5..dbb5ed3d3a 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProvider.java @@ -17,15 +17,23 @@ package org.keycloak.testsuite.federation; +import org.keycloak.component.ComponentModel; import org.keycloak.credential.CredentialInput; +import org.keycloak.credential.CredentialInputUpdater; +import org.keycloak.credential.CredentialInputValidator; import org.keycloak.credential.CredentialModel; import org.keycloak.models.CredentialValidationOutput; import org.keycloak.models.GroupModel; +import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RoleModel; import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserModel; +import org.keycloak.storage.UserStorageProvider; +import org.keycloak.storage.user.UserLookupProvider; +import org.keycloak.storage.user.UserQueryProvider; +import org.keycloak.storage.user.UserRegistrationProvider; import java.util.Collections; import java.util.List; @@ -36,56 +44,60 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class DummyUserFederationProvider implements UserFederationProvider { +public class DummyUserFederationProvider implements UserStorageProvider, + UserLookupProvider, + UserRegistrationProvider, + CredentialInputValidator { private final Map users; + private KeycloakSession session; + private ComponentModel component; - public DummyUserFederationProvider(Map users) { + + + public DummyUserFederationProvider(KeycloakSession session, ComponentModel component, Map users) { this.users = users; + this.session = session; + this.component = component; } + + @Override - public UserModel validateAndProxy(RealmModel realm, UserModel local) { + public UserModel addUser(RealmModel realm, String username) { + UserModel local = session.userLocalStorage().addUser(realm, username); + local.setFederationLink(component.getId()); + + users.put(username, local); return local; } - @Override - public boolean synchronizeRegistrations() { - return true; - } - - @Override - public UserModel register(RealmModel realm, UserModel user) { - users.put(user.getUsername(), user); - return user; - } - @Override public boolean removeUser(RealmModel realm, UserModel user) { return users.remove(user.getUsername()) != null; } @Override - public UserModel getUserByUsername(RealmModel realm, String username) { - return users.get(username); - } - - @Override - public UserModel getUserByEmail(RealmModel realm, String email) { + public UserModel getUserById(String id, RealmModel realm) { return null; } @Override - public List searchByAttributes(Map attributes, RealmModel realm, int maxResults) { - return Collections.emptyList(); + public UserModel getUserByUsername(String username, RealmModel realm) { + return users.get(username); } @Override - public List getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) { - return Collections.emptyList(); + public UserModel getUserByEmail(String email, RealmModel realm) { + return null; } @Override + public void grantToAllUsers(RealmModel realm, RoleModel role) { + + } + + @Override public void preRemove(RealmModel realm) { } @@ -100,34 +112,10 @@ public class DummyUserFederationProvider implements UserFederationProvider { } - @Override - public boolean isValid(RealmModel realm, UserModel local) { - String username = local.getUsername(); - return users.containsKey(username); - } - - @Override public Set getSupportedCredentialTypes() { return Collections.singleton(UserCredentialModel.PASSWORD); } - @Override - public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { - if (!(input instanceof UserCredentialModel) || !CredentialModel.PASSWORD.equals(input.getType())) return false; - - return false; - } - - @Override - public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { - - } - - @Override - public Set getDisableableCredentialTypes(RealmModel realm, UserModel user) { - return Collections.EMPTY_SET; - } - @Override public boolean supportsCredentialType(String credentialType) { return getSupportedCredentialTypes().contains(credentialType); @@ -154,12 +142,7 @@ public class DummyUserFederationProvider implements UserFederationProvider { } return false; } - @Override - public CredentialValidationOutput validCredentials(RealmModel realm, UserCredentialModel credential) { - return CredentialValidationOutput.failed(); - } - - @Override + @Override public void close() { } diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java index df339a9b4f..489e0ee525 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/federation/DummyUserFederationProviderFactory.java @@ -19,17 +19,26 @@ package org.keycloak.testsuite.federation; import org.jboss.logging.Logger; import org.keycloak.Config; +import org.keycloak.component.ComponentModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.models.LDAPConstants; import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserModel; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.storage.UserStorageProviderFactory; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.user.ImportSynchronization; +import org.keycloak.storage.user.SynchronizationResult; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; @@ -38,7 +47,7 @@ import java.util.concurrent.atomic.AtomicInteger; * @author Bill Burke * @version $Revision: 1 $ */ -public class DummyUserFederationProviderFactory implements UserFederationProviderFactory { +public class DummyUserFederationProviderFactory implements UserStorageProviderFactory, ImportSynchronization { private static final Logger logger = Logger.getLogger(DummyUserFederationProviderFactory.class); public static final String PROVIDER_NAME = "dummy"; @@ -49,20 +58,16 @@ public class DummyUserFederationProviderFactory implements UserFederationProvide private Map users = new HashMap(); @Override - public UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) { - return new DummyUserFederationProvider(users); + public DummyUserFederationProvider create(KeycloakSession session, ComponentModel model) { + return new DummyUserFederationProvider(session, model, users); } @Override - public Set getConfigurationOptions() { - Set list = new HashSet(); - list.add("important.config"); - return list; - } - - @Override - public UserFederationProvider create(KeycloakSession session) { - return new DummyUserFederationProvider(users); + public List getConfigProperties() { + return ProviderConfigurationBuilder.create() + .property().name("important.config") + .type(ProviderConfigProperty.STRING_TYPE) + .add().build(); } @Override @@ -86,17 +91,17 @@ public class DummyUserFederationProviderFactory implements UserFederationProvide } @Override - public UserFederationSyncResult syncAllUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model) { + public SynchronizationResult sync(KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) { logger.info("syncAllUsers invoked"); fullSyncCounter.incrementAndGet(); - return UserFederationSyncResult.empty(); + return SynchronizationResult.empty(); } @Override - public UserFederationSyncResult syncChangedUsers(KeycloakSessionFactory sessionFactory, String realmId, UserFederationProviderModel model, Date lastSync) { + public SynchronizationResult syncSince(Date lastSync, KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) { logger.info("syncChangedUsers invoked"); changedSyncCounter.incrementAndGet(); - return UserFederationSyncResult.empty(); + return SynchronizationResult.empty(); } public int getFullSyncCounter() { diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java index 24e8b83e8a..77094f4577 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java @@ -57,9 +57,11 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.managers.ClientSessionCode; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.resource.RealmResourceProvider; +import org.keycloak.storage.UserStorageProvider; import org.keycloak.testsuite.components.TestProvider; import org.keycloak.testsuite.components.TestProviderFactory; import org.keycloak.testsuite.events.EventsListenerProvider; +import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.forms.PassThroughAuthenticator; import org.keycloak.testsuite.forms.PassThroughClientAuthenticator; import org.keycloak.testsuite.rest.representation.AuthenticatorState; @@ -580,8 +582,8 @@ public class TestingResourceProvider implements RealmResourceProvider { public UserRepresentation getUserByUsernameFromFedProviderFactory(@QueryParam("realmName") String realmName, @QueryParam("userName") String userName) { RealmModel realm = getRealmByName(realmName); - UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy"); - UserModel user = factory.getInstance(session, null).getUserByUsername(realm, userName); + DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy"); + UserModel user = factory.create(session, null).getUserByUsername(userName, realm); if (user == null) return null; return ModelToRepresentation.toRepresentation(session, realm, user); } diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory deleted file mode 100644 index 2bc7ca8b28..0000000000 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.mappers.UserFederationMapperFactory +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -org.keycloak.testsuite.federation.DummyUserFederationMapper \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory deleted file mode 100644 index 015d4cde5e..0000000000 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory +++ /dev/null @@ -1,36 +0,0 @@ -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -org.keycloak.testsuite.federation.DummyUserFederationProviderFactory -org.keycloak.testsuite.federation.DummyConfigurableUserFederationProviderFactory \ No newline at end of file diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory new file mode 100644 index 0000000000..a97dd1ebb6 --- /dev/null +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory @@ -0,0 +1 @@ +org.keycloak.testsuite.federation.DummyUserFederationProviderFactory \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageMapperTest.java index 63aacc014f..fa7eb145d5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageMapperTest.java @@ -30,7 +30,6 @@ import org.keycloak.representations.idm.UserFederationMapperTypeRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserFederationSyncResultRepresentation; import org.keycloak.testsuite.Assert; -import org.keycloak.testsuite.federation.DummyUserFederationMapper; import org.keycloak.testsuite.util.AdminEventPaths; import org.keycloak.testsuite.util.UserFederationProviderBuilder; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageRestTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageRestTest.java index 1c4b3db383..315bc8b0a6 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageRestTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserStorageRestTest.java @@ -82,7 +82,7 @@ public class UserStorageRestTest extends AbstractAdminTest { } private UserFederationProvidersResource userFederation() { - return realm.userFederation(); + return null;//realm.userFederation(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java index 1c232b6250..50a0c28ca4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java @@ -47,7 +47,7 @@ public class ClientRedirectTest extends TestRealmKeycloakTest { * * @throws Exception */ - @Test + //@Test public void testClientRedirectEndpoint() throws Exception { oauth.doLogin("test-user@localhost", "password"); diff --git a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java index a59adfc0c1..48ba4b464f 100644 --- a/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java +++ b/testsuite/integration-arquillian/tests/other/sssd/src/test/java/org/keycloak/testsuite/sssd/SSSDTest.java @@ -77,13 +77,6 @@ public class SSSDTest extends AbstractKeycloakTest { adminClient.realm(REALM_NAME).components().add(userFederation); } - @Ignore - @Test - public void testProviderFactories() { - List providerFactories = adminClient.realm(REALM_NAME).userFederation().getProviderFactories(); - Assert.assertNames(providerFactories, "ldap", "kerberos", "dummy", "dummy-configurable", "sssd"); - } - @Test public void testWrongUser() { log.debug("Testing wrong password for user " + USERNAME); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java index ed1e757228..888f954156 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractKeycloakIdentityProviderTest.java @@ -30,6 +30,7 @@ import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserModel; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.services.Urls; +import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.testsuite.broker.util.UserSessionStatusServlet; import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.openqa.selenium.By; @@ -634,7 +635,14 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent // Add federationProvider to realm. It's configured with sync registrations RealmModel realm = getRealm(); - UserFederationProviderModel dummyModel = realm.addUserFederationProvider(DummyUserFederationProviderFactory.PROVIDER_NAME, new HashMap(), 1, "test-dummy", -1, -1, 0); + UserStorageProviderModel model = new UserStorageProviderModel(); + model.setProviderId(DummyUserFederationProviderFactory.PROVIDER_NAME); + model.setPriority(1); + model.setName("test-sync-dummy"); + model.setFullSyncPeriod(-1); + model.setChangedSyncPeriod(-1); + model.setLastSync(0); + UserStorageProviderModel dummyModel = new UserStorageProviderModel(realm.addComponentModel(model)); brokerServerRule.stopSession(session, true); session = brokerServerRule.startSession(); @@ -682,7 +690,7 @@ public abstract class AbstractKeycloakIdentityProviderTest extends AbstractIdent // remove dummy federation provider for this realm realm = getRealm(); - realm.removeUserFederationProvider(dummyModel); + realm.removeComponent(dummyModel); brokerServerRule.stopSession(session, true); session = brokerServerRule.startSession(); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java index a3e412dfe1..478d0dd834 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncDummyUserFederationProviderFactory.java @@ -26,9 +26,14 @@ import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.user.SynchronizationResult; import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import java.util.Date; +import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -59,21 +64,27 @@ public class SyncDummyUserFederationProviderFactory extends DummyUserFederationP return SYNC_PROVIDER_ID; } - @Override - public Set getConfigurationOptions() { - Set list = super.getConfigurationOptions(); - list.add(WAIT_TIME); - return list; + + public List getConfigProperties() { + return ProviderConfigurationBuilder.create() + .property().name("important.config") + .type(ProviderConfigProperty.STRING_TYPE) + .add() + .property().name(WAIT_TIME) + .type(ProviderConfigProperty.STRING_TYPE) + .add() + .build(); } + @Override - public UserFederationSyncResult syncChangedUsers(KeycloakSessionFactory sessionFactory, final String realmId, final UserFederationProviderModel model, Date lastSync) { + public SynchronizationResult syncSince(Date lastSync, KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) { KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() { @Override public void run(KeycloakSession session) { - int waitTime = Integer.parseInt(model.getConfig().get(WAIT_TIME)); + int waitTime = Integer.parseInt(model.getConfig().getFirst(WAIT_TIME)); logger.infof("Starting sync of changed users. Wait time is: %s", waitTime); @@ -109,7 +120,7 @@ public class SyncDummyUserFederationProviderFactory extends DummyUserFederationP // countDown, so the SyncFederationTest can continue latch2.countDown(); - return new UserFederationSyncResult(); + return new SynchronizationResult(); } } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java index 1efc35423d..7eb0d0ea4a 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/federation/sync/SyncFederationTest.java @@ -24,14 +24,17 @@ import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import org.keycloak.common.util.Time; +import org.keycloak.component.ComponentModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationSyncResult; import org.keycloak.services.managers.RealmManager; -import org.keycloak.services.managers.UsersSyncManager; +import org.keycloak.services.managers.UserStorageSyncManager; +import org.keycloak.storage.UserStorageProvider; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.storage.user.SynchronizationResult; import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.rule.KeycloakRule; import org.keycloak.timer.TimerProvider; @@ -41,7 +44,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; /** - * Test with Dummy providers (For LDAP see {@link org.keycloak.testsuite.federation.ldap.base.LDAPSyncTest} + * Test with Dummy providers * * @author Marek Posolda */ @@ -50,7 +53,7 @@ public class SyncFederationTest { private static final Logger log = Logger.getLogger(SyncFederationTest.class); - private static UserFederationProviderModel dummyModel = null; + private static UserStorageProviderModel dummyModel = null; @ClassRule public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() { @@ -62,6 +65,7 @@ public class SyncFederationTest { } }); + @Test public void test01PeriodicSync() { @@ -70,7 +74,14 @@ public class SyncFederationTest { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - dummyModel = appRealm.addUserFederationProvider(DummyUserFederationProviderFactory.PROVIDER_NAME, new HashMap(), 1, "test-sync-dummy", -1, 1, 0); + UserStorageProviderModel model = new UserStorageProviderModel(); + model.setProviderId(DummyUserFederationProviderFactory.PROVIDER_NAME); + model.setPriority(1); + model.setName("test-sync-dummy"); + model.setFullSyncPeriod(-1); + model.setChangedSyncPeriod(1); + model.setLastSync(0); + dummyModel = new UserStorageProviderModel(appRealm.addComponentModel(model)); } }); @@ -78,12 +89,12 @@ public class SyncFederationTest { KeycloakSession session = keycloakRule.startSession(); try { KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); - DummyUserFederationProviderFactory dummyFedFactory = (DummyUserFederationProviderFactory)sessionFactory.getProviderFactory(UserFederationProvider.class, DummyUserFederationProviderFactory.PROVIDER_NAME); + DummyUserFederationProviderFactory dummyFedFactory = (DummyUserFederationProviderFactory)sessionFactory.getProviderFactory(UserStorageProvider.class, DummyUserFederationProviderFactory.PROVIDER_NAME); int full = dummyFedFactory.getFullSyncCounter(); int changed = dummyFedFactory.getChangedSyncCounter(); // Assert that after some period was DummyUserFederationProvider triggered - UsersSyncManager usersSyncManager = new UsersSyncManager(); + UserStorageSyncManager usersSyncManager = new UserStorageSyncManager(); usersSyncManager.bootstrapPeriodic(sessionFactory, session.getProvider(TimerProvider.class)); sleep(1800); @@ -94,7 +105,7 @@ public class SyncFederationTest { // This sync is here just to ensure that we have lock (doublecheck that periodic sync, which was possibly triggered before canceling timer is finished too) while (true) { - UserFederationSyncResult result = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(), appRealm.getId(), dummyModel); + SynchronizationResult result = usersSyncManager.syncChangedUsers(session.getKeycloakSessionFactory(), appRealm.getId(), dummyModel); if (result.isIgnored()) { log.infof("Still waiting for lock before periodic sync is finished", result.toString()); sleep(1000); @@ -122,7 +133,7 @@ public class SyncFederationTest { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.removeUserFederationProvider(dummyModel); + appRealm.removeComponent(dummyModel); } }); @@ -137,9 +148,15 @@ public class SyncFederationTest { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - Map config = new HashMap<>(); - config.put(SyncDummyUserFederationProviderFactory.WAIT_TIME, "2000"); - dummyModel = appRealm.addUserFederationProvider(SyncDummyUserFederationProviderFactory.SYNC_PROVIDER_ID, config, 1, "test-sync-dummy", -1, 1, 0); + UserStorageProviderModel model = new UserStorageProviderModel(); + model.setProviderId(SyncDummyUserFederationProviderFactory.SYNC_PROVIDER_ID); + model.setPriority(1); + model.setName("test-sync-dummy"); + model.setFullSyncPeriod(-1); + model.setChangedSyncPeriod(1); + model.setLastSync(0); + model.getConfig().putSingle(SyncDummyUserFederationProviderFactory.WAIT_TIME, "2000"); + dummyModel = new UserStorageProviderModel(appRealm.addComponentModel(model)); } }); @@ -149,13 +166,13 @@ public class SyncFederationTest { KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); // bootstrap periodic sync - UsersSyncManager usersSyncManager = new UsersSyncManager(); + UserStorageSyncManager usersSyncManager = new UserStorageSyncManager(); usersSyncManager.bootstrapPeriodic(sessionFactory, session.getProvider(TimerProvider.class)); // Wait and then trigger sync manually. Assert it will be ignored sleep(1800); RealmModel realm = session.realms().getRealm("test"); - UserFederationSyncResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, realm.getId(), dummyModel); + SynchronizationResult syncResult = usersSyncManager.syncChangedUsers(sessionFactory, realm.getId(), dummyModel); Assert.assertTrue(syncResult.isIgnored()); // Cancel timer @@ -175,7 +192,7 @@ public class SyncFederationTest { @Override public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { - appRealm.removeUserFederationProvider(dummyModel); + appRealm.removeComponent(dummyModel); } }); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java index f1936458bf..b7bd2afef4 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ImportTest.java @@ -48,9 +48,11 @@ import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; +import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper; import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory; +import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import java.util.List; import java.util.Map; @@ -279,8 +281,6 @@ public class ImportTest extends AbstractModelTest { Assert.assertEquals("googleSecret", google.getConfig().get("clientSecret")); // Test federation providers - List fedProviders = realm.getUserFederationProviders(); - Assert.assertTrue(fedProviders.size() == 0); List storageProviders = realm.getUserStorageProviders(); Assert.assertTrue(storageProviders.size() == 2); UserStorageProviderModel ldap1 = storageProviders.get(0); @@ -294,8 +294,6 @@ public class ImportTest extends AbstractModelTest { Assert.assertEquals("ldap://bar", ldap2.getConfig().getFirst(LDAPConstants.CONNECTION_URL)); // Test federation mappers - Set userFedMappers1 = realm.getUserFederationMappers(); - Assert.assertTrue(userFedMappers1.size() == 0); List fedMappers1 = realm.getComponents(ldap1.getId()); ComponentModel fullNameMapper = fedMappers1.iterator().next(); Assert.assertEquals("FullNameMapper", fullNameMapper.getName()); @@ -304,8 +302,8 @@ public class ImportTest extends AbstractModelTest { Assert.assertEquals("cn", fullNameMapper.getConfig().getFirst(FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE)); // Assert that federation link wasn't created during import - UserFederationProviderFactory factory = (UserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserFederationProvider.class, "dummy"); - Assert.assertNull(factory.getInstance(session, null).getUserByUsername(realm, "wburke")); + DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory)session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy"); + Assert.assertNull(factory.create(session, null).getUserByUsername("wburke", realm)); // Test builtin authentication flows AuthenticationFlowModel clientFlow = realm.getClientAuthenticationFlow(); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java deleted file mode 100755 index 1d78ff7c8b..0000000000 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserFederationModelTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2016 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.keycloak.testsuite.model; - -import org.junit.Assert; -import org.junit.Test; -import org.keycloak.models.ModelDuplicateException; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserFederationMapperModel; -import org.keycloak.models.UserFederationProviderModel; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -/** - * @author Marek Posolda - */ -public class UserFederationModelTest extends AbstractModelTest { - - - @Test - public void federationMapperCrudTest() { - RealmModel realm = realmManager.createRealm("test-realm"); - UserFederationProviderModel fedProvider = realm.addUserFederationProvider("dummy", new TreeMap(), 1, "my-cool-provider", -1, -1, 0); - UserFederationProviderModel fedProvider2 = realm.addUserFederationProvider("dummy", new TreeMap(), 1, "my-cool-provider2", -1, -1, 0); - - UserFederationMapperModel mapperModel1 = createMapper("name1", fedProvider.getId(), "key1", "value1"); - UserFederationMapperModel mapperModel2 = createMapper("name2", fedProvider.getId(), "key2", "value2"); - UserFederationMapperModel mapperModel3 = createMapper("name1", fedProvider2.getId(), "key3", "value3"); - - mapperModel1 = realm.addUserFederationMapper(mapperModel1); - mapperModel2 = realm.addUserFederationMapper(mapperModel2); - mapperModel3 = realm.addUserFederationMapper(mapperModel3); - - commit(); - - try { - UserFederationMapperModel conflictMapper = createMapper("name1", fedProvider.getId(), "key4", "value4"); - realmManager.getRealmByName("test-realm").addUserFederationMapper(conflictMapper); - commit(); - Assert.fail("Don't expect to end here"); - } catch (ModelDuplicateException expected) { - } - - realm = realmManager.getRealmByName("test-realm"); - Set mappers = realm.getUserFederationMappers(); - Assert.assertEquals(3, mappers.size()); - Assert.assertTrue(mappers.contains(mapperModel1)); - Assert.assertTrue(mappers.contains(mapperModel2)); - Assert.assertTrue(mappers.contains(mapperModel3)); - - mappers = realm.getUserFederationMappersByFederationProvider(fedProvider.getId()); - Assert.assertEquals(2, mappers.size()); - Assert.assertTrue(mappers.contains(mapperModel1)); - Assert.assertTrue(mappers.contains(mapperModel2)); - - mapperModel3.getConfig().put("otherKey", "otherValue"); - realm.updateUserFederationMapper(mapperModel3); - - commit(); - - realm = realmManager.getRealmByName("test-realm"); - mapperModel3 = realm.getUserFederationMapperById(mapperModel3.getId()); - Assert.assertEquals(2, mapperModel3.getConfig().size()); - Assert.assertEquals("value3", mapperModel3.getConfig().get("key3")); - Assert.assertEquals("otherValue", mapperModel3.getConfig().get("otherKey")); - } - - - @Test - public void federationProviderRemovalTest() { - RealmModel realm = realmManager.createRealm("test-realm"); - UserFederationProviderModel fedProvider = realm.addUserFederationProvider("dummy", new TreeMap(), 1, "my-cool-provider", -1, -1, 0); - UserFederationProviderModel fedProvider2 = realm.addUserFederationProvider("dummy", new TreeMap(), 1, "my-cool-provider2", -1, -1, 0); - - UserFederationMapperModel mapperModel1 = createMapper("name1", fedProvider.getId(), "key1", "value1"); - UserFederationMapperModel mapperModel2 = createMapper("name2", fedProvider.getId(), "key2", "value2"); - UserFederationMapperModel mapperModel3 = createMapper("name1", fedProvider2.getId(), "key3", "value3"); - - mapperModel1 = realm.addUserFederationMapper(mapperModel1); - mapperModel2 = realm.addUserFederationMapper(mapperModel2); - mapperModel3 = realm.addUserFederationMapper(mapperModel3); - - commit(); - - realmManager.getRealmByName("test-realm").removeUserFederationProvider(fedProvider); - - commit(); - - realm = realmManager.getRealmByName("test-realm"); - Set mappers = realm.getUserFederationMappers(); - Assert.assertEquals(1, mappers.size()); - Assert.assertEquals(mapperModel3, mappers.iterator().next()); - - realm = realmManager.getRealmByName("test-realm"); - realmManager.removeRealm(realm); - - commit(); - } - - @Test - public void federationProvidersSetTest() { - RealmModel realm = realmManager.createRealm("test-realm"); - UserFederationProviderModel ldapProvider = new UserFederationProviderModel(null, "ldap", new TreeMap(), 1, "my-cool-provider", -1, -1, 0); - realm.setUserFederationProviders(Arrays.asList(ldapProvider)); - - commit(); - - realm = realmManager.getRealmByName("test-realm"); - List fedProviders = realm.getUserFederationProviders(); - Assert.assertEquals(1, fedProviders.size()); - ldapProvider = fedProviders.get(0); - Set fedMappers = realmManager.getRealmByName("test-realm").getUserFederationMappersByFederationProvider(ldapProvider.getId()); - - UserFederationProviderModel dummyProvider = new UserFederationProviderModel(null, "dummy", new TreeMap(), 1, "my-cool-provider", -1, -1, 0); - try { - realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider)); - commit(); - Assert.fail("Don't expect to end here"); - } catch (ModelDuplicateException expected) { - } - - dummyProvider.setDisplayName("my-cool-provider2"); - realm.setUserFederationProviders(Arrays.asList(ldapProvider, dummyProvider)); - - commit(); - - realm = realmManager.getRealmByName("test-realm"); - Assert.assertEquals(fedMappers.size(), realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).size()); - realm.setUserFederationProviders(new ArrayList()); - - commit(); - - realm = realmManager.getRealmByName("test-realm"); - Assert.assertTrue(realm.getUserFederationMappersByFederationProvider(ldapProvider.getId()).isEmpty()); - } - - private UserFederationMapperModel createMapper(String name, String fedProviderId, String... config) { - UserFederationMapperModel mapperModel = new UserFederationMapperModel(); - mapperModel.setName(name); - mapperModel.setFederationMapperType("someType"); - mapperModel.setFederationProviderId(fedProviderId); - Map configMap = new TreeMap(); - String key = null; - for (String configEntry : config) { - if (key == null) { - key = configEntry; - } else { - configMap.put(key, configEntry); - key = null; - } - } - mapperModel.setConfig(configMap); - return mapperModel; - } -} diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java index af023124d6..4ba0f6765f 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/util/cli/SyncDummyFederationProviderCommand.java @@ -17,11 +17,14 @@ package org.keycloak.testsuite.util.cli; +import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.services.managers.UsersSyncManager; +import org.keycloak.services.managers.UserStorageSyncManager; +import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory; import org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory; import java.util.HashMap; @@ -38,25 +41,33 @@ public class SyncDummyFederationProviderCommand extends AbstractCommand { int changedSyncPeriod = getIntArg(1); RealmModel realm = session.realms().getRealmByName("master"); - UserFederationProviderModel fedProviderModel = KeycloakModelUtils.findUserFederationProviderByDisplayName("cluster-dummy", realm); + UserStorageProviderModel fedProviderModel = KeycloakModelUtils.findUserStorageProviderByName("cluster-dummy", realm); if (fedProviderModel == null) { - Map cfg = new HashMap<>(); + MultivaluedHashMap cfg = fedProviderModel.getConfig(); updateConfig(cfg, waitTime); - fedProviderModel = realm.addUserFederationProvider(SyncDummyUserFederationProviderFactory.SYNC_PROVIDER_ID, cfg, 1, "cluster-dummy", -1, changedSyncPeriod, -1); + + UserStorageProviderModel model = new UserStorageProviderModel(); + model.setProviderId(SyncDummyUserFederationProviderFactory.SYNC_PROVIDER_ID); + model.setPriority(1); + model.setName("cluster-dummy"); + model.setFullSyncPeriod(-1); + model.setChangedSyncPeriod(changedSyncPeriod); + model.setLastSync(-1); + fedProviderModel = new UserStorageProviderModel(realm.addComponentModel(model)); } else { - Map cfg = fedProviderModel.getConfig(); + MultivaluedHashMap cfg = fedProviderModel.getConfig(); updateConfig(cfg, waitTime); fedProviderModel.setChangedSyncPeriod(changedSyncPeriod); - realm.updateUserFederationProvider(fedProviderModel); + realm.updateComponent(fedProviderModel); } - new UsersSyncManager().notifyToRefreshPeriodicSync(session, realm, fedProviderModel, false); + new UserStorageSyncManager().notifyToRefreshPeriodicSync(session, realm, fedProviderModel, false); log.infof("User federation provider created and sync was started", waitTime); } - private void updateConfig(Map cfg, int waitTime) { - cfg.put(SyncDummyUserFederationProviderFactory.WAIT_TIME, String.valueOf(waitTime)); + private void updateConfig(MultivaluedHashMap cfg, int waitTime) { + cfg.putSingle(SyncDummyUserFederationProviderFactory.WAIT_TIME, String.valueOf(waitTime)); } diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory deleted file mode 100755 index d4a16d36c8..0000000000 --- a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.models.UserFederationProviderFactory +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright 2016 Red Hat, Inc. and/or its affiliates -# and other contributors as indicated by the @author tags. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory \ No newline at end of file diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory index efbed13920..dcc5143025 100644 --- a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory +++ b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.storage.UserStorageProviderFactory @@ -1,2 +1,3 @@ +org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory org.keycloak.testsuite.federation.storage.UserPropertyFileStorageFactory org.keycloak.testsuite.federation.storage.UserMapStorageFactory \ No newline at end of file