Move User Storage SPI, introduce ExportImportManager
This commit is contained in:
parent
703e868a51
commit
82094d113e
63 changed files with 1680 additions and 1482 deletions
|
@ -27,6 +27,7 @@ import org.keycloak.provider.ProviderFactory;
|
|||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
|
||||
import javax.naming.directory.SearchControls;
|
||||
import java.util.List;
|
||||
|
@ -52,7 +53,7 @@ public class MigrateTo1_3_0 implements Migration {
|
|||
}
|
||||
|
||||
private void migrateLDAPProviders(KeycloakSession session, RealmModel realm) {
|
||||
realm.getUserStorageProvidersStream().forEachOrdered(fedProvider -> {
|
||||
UserStorageUtil.getUserStorageProvidersStream(realm).forEachOrdered(fedProvider -> {
|
||||
if (fedProvider.getProviderId().equals(LDAPConstants.LDAP_PROVIDER)) {
|
||||
fedProvider = new UserStorageProviderModel(fedProvider); // copy don't want to muck with cache
|
||||
MultivaluedHashMap<String, String> config = fedProvider.getConfig();
|
|
@ -29,6 +29,7 @@ import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
|||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -67,7 +68,7 @@ public class MigrateTo1_4_0 implements Migration {
|
|||
|
||||
private void migrateLDAPMappers(KeycloakSession session, RealmModel realm) {
|
||||
List<String> mandatoryInLdap = Arrays.asList("username", "username-cn", "first name", "last name");
|
||||
realm.getUserStorageProvidersStream()
|
||||
UserStorageUtil.getUserStorageProvidersStream(realm)
|
||||
.filter(providerModel -> Objects.equals(providerModel.getProviderId(), LDAPConstants.LDAP_PROVIDER))
|
||||
.forEachOrdered(providerModel -> realm.getComponentsStream(providerModel.getId())
|
||||
.filter(mapper -> mandatoryInLdap.contains(mapper.getName()))
|
|
@ -25,6 +25,7 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
@ -50,7 +51,7 @@ public class MigrateTo1_8_0 implements Migration {
|
|||
}
|
||||
|
||||
protected void migrateRealm(RealmModel realm) {
|
||||
realm.getUserStorageProvidersStream()
|
||||
UserStorageUtil.getUserStorageProvidersStream(realm)
|
||||
.filter(fedProvider -> Objects.equals(fedProvider.getProviderId(), LDAPConstants.LDAP_PROVIDER))
|
||||
.filter(this::isActiveDirectory)
|
||||
.filter(fedProvider -> Objects.isNull(getMapperByName(realm, fedProvider, "MSAD account controls")))
|
|
@ -12,13 +12,14 @@ import org.keycloak.models.cache.UserCache;
|
|||
import org.keycloak.storage.ClientScopeStorageManager;
|
||||
import org.keycloak.storage.ClientStorageManager;
|
||||
import org.keycloak.storage.DatastoreProvider;
|
||||
import org.keycloak.storage.ExportImportManager;
|
||||
import org.keycloak.storage.GroupStorageManager;
|
||||
import org.keycloak.storage.LegacyStoreManagers;
|
||||
import org.keycloak.storage.MigrationManager;
|
||||
import org.keycloak.storage.RoleStorageManager;
|
||||
import org.keycloak.storage.UserStorageManager;
|
||||
|
||||
public class LegacyDatastoreProvider implements DatastoreProvider, LegacyStoreManagers {
|
||||
|
||||
private final LegacyDatastoreProviderFactory factory;
|
||||
private final KeycloakSession session;
|
||||
|
||||
|
@ -184,4 +185,15 @@ public class LegacyDatastoreProvider implements DatastoreProvider, LegacyStoreMa
|
|||
}
|
||||
return userProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExportImportManager getExportImportManager() {
|
||||
return new LegacyExportImportManager(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MigrationManager getMigrationManager() {
|
||||
return new LegacyMigrationManager(session);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,181 @@
|
|||
package org.keycloak.storage.datastore;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.Version;
|
||||
import org.keycloak.migration.MigrationModel;
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.migration.migrators.MigrateTo12_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo14_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo18_0_0;
|
||||
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;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_1_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_3_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_5_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_1_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_1;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_2;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_6_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo6_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo8_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo8_0_2;
|
||||
import org.keycloak.migration.migrators.MigrateTo9_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo9_0_4;
|
||||
import org.keycloak.migration.migrators.Migration;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.DeploymentStateProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.MigrationManager;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* This wraps the functionality for migrations of the legacy storage. This will be handled differently for the new map storage,
|
||||
* therefore, it has been extracted.
|
||||
*
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class LegacyMigrationManager implements MigrationManager {
|
||||
private static final Logger logger = Logger.getLogger(LegacyMigrationManager.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(),
|
||||
new MigrateTo2_1_0(),
|
||||
new MigrateTo2_2_0(),
|
||||
new MigrateTo2_3_0(),
|
||||
new MigrateTo2_5_0(),
|
||||
new MigrateTo3_0_0(),
|
||||
new MigrateTo3_1_0(),
|
||||
new MigrateTo3_2_0(),
|
||||
new MigrateTo3_4_0(),
|
||||
new MigrateTo3_4_1(),
|
||||
new MigrateTo3_4_2(),
|
||||
new MigrateTo4_0_0(),
|
||||
new MigrateTo4_2_0(),
|
||||
new MigrateTo4_6_0(),
|
||||
new MigrateTo6_0_0(),
|
||||
new MigrateTo8_0_0(),
|
||||
new MigrateTo8_0_2(),
|
||||
new MigrateTo9_0_0(),
|
||||
new MigrateTo9_0_4(),
|
||||
new MigrateTo12_0_0(),
|
||||
new MigrateTo14_0_0(),
|
||||
new MigrateTo18_0_0()
|
||||
};
|
||||
|
||||
private final KeycloakSession session;
|
||||
|
||||
public LegacyMigrationManager(KeycloakSession session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void migrate() {
|
||||
session.setAttribute(Constants.STORAGE_BATCH_ENABLED, Boolean.getBoolean("keycloak.migration.batch-enabled"));
|
||||
session.setAttribute(Constants.STORAGE_BATCH_SIZE, Integer.getInteger("keycloak.migration.batch-size"));
|
||||
MigrationModel model = session.getProvider(DeploymentStateProvider.class).getMigrationModel();
|
||||
|
||||
ModelVersion currentVersion = new ModelVersion(Version.VERSION_KEYCLOAK);
|
||||
ModelVersion latestUpdate = migrations[migrations.length-1].getVersion();
|
||||
ModelVersion databaseVersion = model.getStoredVersion() != null ? new ModelVersion(model.getStoredVersion()) : null;
|
||||
|
||||
if (databaseVersion == null || databaseVersion.lessThan(latestUpdate)) {
|
||||
for (Migration m : migrations) {
|
||||
if (databaseVersion == null || databaseVersion.lessThan(m.getVersion())) {
|
||||
if (databaseVersion != null) {
|
||||
logger.debugf("Migrating older model to %s", m.getVersion());
|
||||
}
|
||||
m.migrate(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (databaseVersion == null || databaseVersion.lessThan(currentVersion)) {
|
||||
model.setStoredVersion(currentVersion.toString());
|
||||
}
|
||||
|
||||
Version.RESOURCES_VERSION = model.getResourcesTag();
|
||||
}
|
||||
|
||||
public static final ModelVersion RHSSO_VERSION_7_0_KEYCLOAK_VERSION = new ModelVersion("1.9.8");
|
||||
public static final ModelVersion RHSSO_VERSION_7_1_KEYCLOAK_VERSION = new ModelVersion("2.5.5");
|
||||
public static final ModelVersion RHSSO_VERSION_7_2_KEYCLOAK_VERSION = new ModelVersion("3.4.3");
|
||||
public static final ModelVersion RHSSO_VERSION_7_3_KEYCLOAK_VERSION = new ModelVersion("4.8.3");
|
||||
public static final ModelVersion RHSSO_VERSION_7_4_KEYCLOAK_VERSION = new ModelVersion("9.0.3");
|
||||
|
||||
private static final Map<Pattern, ModelVersion> PATTERN_MATCHER = new LinkedHashMap<>();
|
||||
static {
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.0\\.\\d+\\.GA$"), RHSSO_VERSION_7_0_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.1\\.\\d+\\.GA$"), RHSSO_VERSION_7_1_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.2\\.\\d+\\.GA$"), RHSSO_VERSION_7_2_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.3\\.\\d+\\.GA$"), RHSSO_VERSION_7_3_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.4\\.\\d+\\.GA$"), RHSSO_VERSION_7_4_KEYCLOAK_VERSION);
|
||||
}
|
||||
|
||||
public void migrate(RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
ModelVersion stored = null;
|
||||
if (rep.getKeycloakVersion() != null) {
|
||||
stored = convertRHSSOVersionToKeycloakVersion(rep.getKeycloakVersion());
|
||||
if (stored == null) {
|
||||
stored = new ModelVersion(rep.getKeycloakVersion());
|
||||
}
|
||||
}
|
||||
if (stored == null) {
|
||||
stored = migrations[0].getVersion();
|
||||
}
|
||||
|
||||
for (Migration m : migrations) {
|
||||
if (stored == null || stored.lessThan(m.getVersion())) {
|
||||
if (stored != null) {
|
||||
logger.debugf("Migrating older json representation to %s", m.getVersion());
|
||||
}
|
||||
try {
|
||||
m.migrateImport(session, realm, rep, skipUserDependent);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to migrate json representation for version: " + m.getVersion(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ModelVersion convertRHSSOVersionToKeycloakVersion(String version) {
|
||||
// look for the keycloakVersion pattern to identify it as RH SSO
|
||||
for (Pattern pattern : PATTERN_MATCHER.keySet()) {
|
||||
if (pattern.matcher(version).find()) {
|
||||
return PATTERN_MATCHER.get(pattern);
|
||||
}
|
||||
}
|
||||
// chceck if the version is in format for CD releases, e.g.: "keycloakVersion": "6"
|
||||
if (Pattern.compile("^[0-9]*$").matcher(version).find()) {
|
||||
return new ModelVersion(Integer.parseInt(version), 0, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,6 +31,7 @@ import org.keycloak.models.utils.KeycloakModelUtils;
|
|||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderFactory;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
import org.keycloak.storage.user.ImportSynchronization;
|
||||
import org.keycloak.storage.user.SynchronizationResult;
|
||||
import org.keycloak.timer.TimerProvider;
|
||||
|
@ -61,7 +62,7 @@ public class UserStorageSyncManager {
|
|||
public void run(KeycloakSession session) {
|
||||
Stream<RealmModel> realms = session.realms().getRealmsWithProviderTypeStream(UserStorageProvider.class);
|
||||
realms.forEach(realm -> {
|
||||
Stream<UserStorageProviderModel> providers = realm.getUserStorageProvidersStream();
|
||||
Stream<UserStorageProviderModel> providers = UserStorageUtil.getUserStorageProvidersStream(realm);
|
||||
providers.forEachOrdered(provider -> {
|
||||
UserStorageProviderFactory factory = (UserStorageProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, provider.getProviderId());
|
||||
if (factory instanceof ImportSynchronization && provider.isImportEnabled()) {
|
||||
|
@ -165,7 +166,7 @@ public class UserStorageSyncManager {
|
|||
|
||||
|
||||
public static void notifyToRefreshPeriodicSyncAll(KeycloakSession session, RealmModel realm, boolean removed) {
|
||||
realm.getUserStorageProvidersStream().forEachOrdered(fedProvider ->
|
||||
UserStorageUtil.getUserStorageProvidersStream(realm).forEachOrdered(fedProvider ->
|
||||
notifyToRefreshPeriodicSync(session, realm, fedProvider, removed));
|
||||
}
|
||||
|
||||
|
@ -267,7 +268,7 @@ public class UserStorageSyncManager {
|
|||
@Override
|
||||
public void run(KeycloakSession session) {
|
||||
RealmModel persistentRealm = session.realms().getRealm(realmId);
|
||||
persistentRealm.getUserStorageProvidersStream()
|
||||
UserStorageUtil.getUserStorageProvidersStream(persistentRealm)
|
||||
.filter(persistentFedProvider -> Objects.equals(provider.getId(), persistentFedProvider.getId()))
|
||||
.forEachOrdered(persistentFedProvider -> {
|
||||
// Update persistent provider in DB
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.models.datastore;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.RHSSO_VERSION_7_0_KEYCLOAK_VERSION;
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.RHSSO_VERSION_7_1_KEYCLOAK_VERSION;
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.RHSSO_VERSION_7_2_KEYCLOAK_VERSION;
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.RHSSO_VERSION_7_3_KEYCLOAK_VERSION;
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.RHSSO_VERSION_7_4_KEYCLOAK_VERSION;
|
||||
import static org.keycloak.storage.datastore.LegacyMigrationManager.convertRHSSOVersionToKeycloakVersion;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class LegacyMigrationManagerTest {
|
||||
|
||||
@Test
|
||||
public void testRHSSOVersionToKeycloakVersionConversion() {
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.0.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.1.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.2.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.0.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.1.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.2.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.0.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.1.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.2.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.0.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.1.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.2.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.10.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.4.0.GA"), is(equalTo(RHSSO_VERSION_7_4_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.4.15.GA"), is(equalTo(RHSSO_VERSION_7_4_KEYCLOAK_VERSION)));
|
||||
|
||||
// check the conversion doesn't change version for keycloak
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.0"), is(nullValue()));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("8.0.0"), is(nullValue()));
|
||||
|
||||
// check for CD releases
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("6"), is(equalTo(new ModelVersion("6.0.0"))));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7"), is(equalTo(new ModelVersion("7.0.0"))));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("10"), is(equalTo(new ModelVersion("10.0.0"))));
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ import org.keycloak.events.admin.OperationType;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.services.managers.UserStorageSyncManager;
|
||||
import org.keycloak.storage.managers.UserStorageSyncManager;
|
||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.keycloak.storage;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class UserStorageUtil {
|
||||
/**
|
||||
* Returns sorted {@link UserStorageProviderModel UserStorageProviderModel} as a stream.
|
||||
* It should be used with forEachOrdered if the ordering is required.
|
||||
* @return Sorted stream of {@link UserStorageProviderModel}. Never returns {@code null}.
|
||||
*/
|
||||
public static Stream<UserStorageProviderModel> getUserStorageProvidersStream(RealmModel realm) {
|
||||
return realm.getComponentsStream(realm.getId(), UserStorageProvider.class.getName())
|
||||
.map(UserStorageProviderModel::new)
|
||||
.sorted(UserStorageProviderModel.comparator);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ import org.keycloak.Config;
|
|||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.LDAPConstants;
|
||||
import org.keycloak.models.map.storage.ldap.role.config.LdapMapRoleMapperConfig;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
|
||||
import javax.naming.directory.SearchControls;
|
||||
import java.util.Collection;
|
||||
|
@ -271,15 +270,6 @@ public class LdapMapConfig {
|
|||
return Boolean.parseBoolean(config.getFirst(LDAPConstants.START_TLS));
|
||||
}
|
||||
|
||||
public UserStorageProvider.EditMode getEditMode() {
|
||||
String editModeString = config.getFirst(LDAPConstants.EDIT_MODE);
|
||||
if (editModeString == null) {
|
||||
return UserStorageProvider.EditMode.READ_ONLY;
|
||||
} else {
|
||||
return UserStorageProvider.EditMode.valueOf(editModeString);
|
||||
}
|
||||
}
|
||||
|
||||
public void addBinaryAttribute(String attrName) {
|
||||
binaryAttributeNames.add(attrName);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
|||
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.client.ClientStorageProvider;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -456,9 +455,6 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
|||
public void preRemove(RealmModel realm, ComponentModel component) {
|
||||
String componentId = component.getId();
|
||||
LOG.tracef("preRemove[ComponentModel](%s, %s)%s", realm, componentId, getShortStackTrace());
|
||||
if (component.getProviderType().equals(UserStorageProvider.class.getName())) {
|
||||
removeImportedUsers(realm, componentId);
|
||||
}
|
||||
if (component.getProviderType().equals(ClientStorageProvider.class.getName())) {
|
||||
DefaultModelCriteria<UserModel> mcb = criteria();
|
||||
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
|
||||
|
|
|
@ -17,169 +17,25 @@
|
|||
|
||||
package org.keycloak.migration;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.common.Version;
|
||||
import org.keycloak.migration.migrators.MigrateTo12_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo14_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo18_0_0;
|
||||
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;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_1_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_3_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo2_5_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_1_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_1;
|
||||
import org.keycloak.migration.migrators.MigrateTo3_4_2;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_2_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo4_6_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo6_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo8_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo8_0_2;
|
||||
import org.keycloak.migration.migrators.MigrateTo9_0_0;
|
||||
import org.keycloak.migration.migrators.MigrateTo9_0_4;
|
||||
import org.keycloak.migration.migrators.Migration;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.DeploymentStateProvider;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.DatastoreProvider;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
@Deprecated // as this will be moved to a legacy module
|
||||
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(),
|
||||
new MigrateTo2_1_0(),
|
||||
new MigrateTo2_2_0(),
|
||||
new MigrateTo2_3_0(),
|
||||
new MigrateTo2_5_0(),
|
||||
new MigrateTo3_0_0(),
|
||||
new MigrateTo3_1_0(),
|
||||
new MigrateTo3_2_0(),
|
||||
new MigrateTo3_4_0(),
|
||||
new MigrateTo3_4_1(),
|
||||
new MigrateTo3_4_2(),
|
||||
new MigrateTo4_0_0(),
|
||||
new MigrateTo4_2_0(),
|
||||
new MigrateTo4_6_0(),
|
||||
new MigrateTo6_0_0(),
|
||||
new MigrateTo8_0_0(),
|
||||
new MigrateTo8_0_2(),
|
||||
new MigrateTo9_0_0(),
|
||||
new MigrateTo9_0_4(),
|
||||
new MigrateTo12_0_0(),
|
||||
new MigrateTo14_0_0(),
|
||||
new MigrateTo18_0_0()
|
||||
};
|
||||
|
||||
public static void migrate(KeycloakSession session) {
|
||||
session.setAttribute(Constants.STORAGE_BATCH_ENABLED, Boolean.getBoolean("keycloak.migration.batch-enabled"));
|
||||
session.setAttribute(Constants.STORAGE_BATCH_SIZE, Integer.getInteger("keycloak.migration.batch-size"));
|
||||
MigrationModel model = session.getProvider(DeploymentStateProvider.class).getMigrationModel();
|
||||
|
||||
ModelVersion currentVersion = new ModelVersion(Version.VERSION_KEYCLOAK);
|
||||
ModelVersion latestUpdate = migrations[migrations.length-1].getVersion();
|
||||
ModelVersion databaseVersion = model.getStoredVersion() != null ? new ModelVersion(model.getStoredVersion()) : null;
|
||||
|
||||
if (databaseVersion == null || databaseVersion.lessThan(latestUpdate)) {
|
||||
for (Migration m : migrations) {
|
||||
if (databaseVersion == null || databaseVersion.lessThan(m.getVersion())) {
|
||||
if (databaseVersion != null) {
|
||||
logger.debugf("Migrating older model to %s", m.getVersion());
|
||||
}
|
||||
m.migrate(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (databaseVersion == null || databaseVersion.lessThan(currentVersion)) {
|
||||
model.setStoredVersion(currentVersion.toString());
|
||||
}
|
||||
|
||||
Version.RESOURCES_VERSION = model.getResourcesTag();
|
||||
}
|
||||
|
||||
public static final ModelVersion RHSSO_VERSION_7_0_KEYCLOAK_VERSION = new ModelVersion("1.9.8");
|
||||
public static final ModelVersion RHSSO_VERSION_7_1_KEYCLOAK_VERSION = new ModelVersion("2.5.5");
|
||||
public static final ModelVersion RHSSO_VERSION_7_2_KEYCLOAK_VERSION = new ModelVersion("3.4.3");
|
||||
public static final ModelVersion RHSSO_VERSION_7_3_KEYCLOAK_VERSION = new ModelVersion("4.8.3");
|
||||
public static final ModelVersion RHSSO_VERSION_7_4_KEYCLOAK_VERSION = new ModelVersion("9.0.3");
|
||||
|
||||
private static final Map<Pattern, ModelVersion> PATTERN_MATCHER = new LinkedHashMap<>();
|
||||
static {
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.0\\.\\d+\\.GA$"), RHSSO_VERSION_7_0_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.1\\.\\d+\\.GA$"), RHSSO_VERSION_7_1_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.2\\.\\d+\\.GA$"), RHSSO_VERSION_7_2_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.3\\.\\d+\\.GA$"), RHSSO_VERSION_7_3_KEYCLOAK_VERSION);
|
||||
PATTERN_MATCHER.put(Pattern.compile("^7\\.4\\.\\d+\\.GA$"), RHSSO_VERSION_7_4_KEYCLOAK_VERSION);
|
||||
session.getProvider(DatastoreProvider.class).getMigrationManager().migrate();
|
||||
}
|
||||
|
||||
public static void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||
ModelVersion stored = null;
|
||||
if (rep.getKeycloakVersion() != null) {
|
||||
stored = convertRHSSOVersionToKeycloakVersion(rep.getKeycloakVersion());
|
||||
if (stored == null) {
|
||||
stored = new ModelVersion(rep.getKeycloakVersion());
|
||||
}
|
||||
}
|
||||
if (stored == null) {
|
||||
stored = migrations[0].getVersion();
|
||||
}
|
||||
|
||||
for (Migration m : migrations) {
|
||||
if (stored == null || stored.lessThan(m.getVersion())) {
|
||||
if (stored != null) {
|
||||
logger.debugf("Migrating older json representation to %s", m.getVersion());
|
||||
}
|
||||
try {
|
||||
m.migrateImport(session, realm, rep, skipUserDependent);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to migrate json representation for version: " + m.getVersion(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
session.getProvider(DatastoreProvider.class).getMigrationManager().migrate(realm, rep, skipUserDependent);
|
||||
}
|
||||
|
||||
public static ModelVersion convertRHSSOVersionToKeycloakVersion(String version) {
|
||||
// look for the keycloakVersion pattern to identify it as RH SSO
|
||||
for (Pattern pattern : PATTERN_MATCHER.keySet()) {
|
||||
if (pattern.matcher(version).find()) {
|
||||
return PATTERN_MATCHER.get(pattern);
|
||||
}
|
||||
}
|
||||
// chceck if the version is in format for CD releases, e.g.: "keycloakVersion": "6"
|
||||
if (Pattern.compile("^[0-9]*$").matcher(version).find()) {
|
||||
return new ModelVersion(Integer.parseInt(version), 0, 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.keycloak.models.RoleModel;
|
|||
import org.keycloak.models.ScopeContainerModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.representations.idm.CertificateRepresentation;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.transaction.JtaTransactionManagerLookup;
|
||||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
@ -392,24 +391,6 @@ public final class KeycloakModelUtils {
|
|||
// USER FEDERATION RELATED STUFF
|
||||
|
||||
|
||||
public static UserStorageProviderModel findUserStorageProviderByName(String displayName, RealmModel realm) {
|
||||
if (displayName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return realm.getUserStorageProvidersStream()
|
||||
.filter(fedProvider -> Objects.equals(fedProvider.getName(), displayName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static UserStorageProviderModel findUserStorageProviderById(String fedProviderId, RealmModel realm) {
|
||||
return realm.getUserStorageProvidersStream()
|
||||
.filter(fedProvider -> Objects.equals(fedProvider.getId(), fedProviderId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static ComponentModel createComponentModel(String name, String parentId, String providerId, String providerType, String... config) {
|
||||
ComponentModel mapperModel = new ComponentModel();
|
||||
mapperModel.setParentId(parentId);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -22,4 +22,7 @@ public interface DatastoreProvider extends Provider {
|
|||
|
||||
public UserProvider users();
|
||||
|
||||
ExportImportManager getExportImportManager();
|
||||
|
||||
MigrationManager getMigrationManager();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.keycloak.storage;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* Manage importing and updating of realms for the legacy store.
|
||||
*
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public interface ExportImportManager {
|
||||
void importRealm(RealmRepresentation rep, RealmModel newRealm, boolean skipUserDependent);
|
||||
|
||||
void updateRealm(RealmRepresentation rep, RealmModel realm);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.keycloak.storage;
|
||||
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
||||
/**
|
||||
* Handle the migration of the datastore and an imported realm representation.
|
||||
* Will eventually be handled by the store directly.
|
||||
*
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
@Deprecated
|
||||
public interface MigrationManager {
|
||||
|
||||
void migrate();
|
||||
|
||||
void migrate(RealmModel realm, RealmRepresentation rep, boolean skipUserDependent);
|
||||
}
|
|
@ -21,11 +21,6 @@ import org.junit.Assert;
|
|||
import org.junit.Test;
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.keycloak.migration.MigrationModelManager.*;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -100,35 +95,4 @@ public class MigrationVersionTest {
|
|||
Assert.assertNull(versionProduct.getQualifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRHSSOVersionToKeycloakVersionConversion() {
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.0.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.1.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.2.GA"), is(equalTo(RHSSO_VERSION_7_0_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.0.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.1.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.1.2.GA"), is(equalTo(RHSSO_VERSION_7_1_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.0.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.1.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.2.2.GA"), is(equalTo(RHSSO_VERSION_7_2_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.0.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.1.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.2.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.3.10.GA"), is(equalTo(RHSSO_VERSION_7_3_KEYCLOAK_VERSION)));
|
||||
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.4.0.GA"), is(equalTo(RHSSO_VERSION_7_4_KEYCLOAK_VERSION)));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.4.15.GA"), is(equalTo(RHSSO_VERSION_7_4_KEYCLOAK_VERSION)));
|
||||
|
||||
// check the conversion doesn't change version for keycloak
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7.0.0"), is(nullValue()));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("8.0.0"), is(nullValue()));
|
||||
|
||||
// check for CD releases
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("6"), is(equalTo(new ModelVersion("6.0.0"))));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("7"), is(equalTo(new ModelVersion("7.0.0"))));
|
||||
Assert.assertThat(convertRHSSOVersionToKeycloakVersion("10"), is(equalTo(new ModelVersion("10.0.0"))));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ import org.keycloak.component.ComponentModel;
|
|||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
import org.keycloak.storage.SearchableModelField;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.client.ClientStorageProvider;
|
||||
import org.keycloak.storage.client.ClientStorageProviderModel;
|
||||
import org.keycloak.storage.role.RoleStorageProvider;
|
||||
|
@ -662,25 +660,6 @@ public interface RealmModel extends RoleContainerModel {
|
|||
|
||||
ComponentModel getComponent(String id);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getUserStorageProvidersStream() getUserStorageProvidersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserStorageProviderModel> getUserStorageProviders() {
|
||||
return getUserStorageProvidersStream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sorted {@link UserStorageProviderModel UserStorageProviderModel} as a stream.
|
||||
* It should be used with forEachOrdered if the ordering is required.
|
||||
* @return Sorted stream of {@link UserStorageProviderModel}. Never returns {@code null}.
|
||||
*/
|
||||
default Stream<UserStorageProviderModel> getUserStorageProvidersStream() {
|
||||
return getComponentsStream(getId(), UserStorageProvider.class.getName())
|
||||
.map(UserStorageProviderModel::new)
|
||||
.sorted(UserStorageProviderModel.comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getClientStorageProvidersStream() getClientStorageProvidersStream} instead.
|
||||
*/
|
||||
|
|
|
@ -162,9 +162,9 @@ public class CacheableStorageProviderModel extends PrioritizedComponentModel {
|
|||
}
|
||||
|
||||
public long getLifespan() {
|
||||
UserStorageProviderModel.CachePolicy policy = getCachePolicy();
|
||||
CachePolicy policy = getCachePolicy();
|
||||
long lifespan = -1;
|
||||
if (policy == null || policy == UserStorageProviderModel.CachePolicy.DEFAULT) {
|
||||
if (policy == null || policy == CachePolicy.DEFAULT) {
|
||||
lifespan = -1;
|
||||
} else if (policy == CacheableStorageProviderModel.CachePolicy.EVICT_DAILY) {
|
||||
if (getEvictionHour() > -1 && getEvictionMinute() > -1) {
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.keycloak.models.RoleModel;
|
|||
|
||||
/**
|
||||
* This is an optional capability interface that is intended to be implemented by any
|
||||
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports bulk operations.
|
||||
* <code>UserStorageProvider</code> that supports bulk operations.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.keycloak.models.UserModel;
|
|||
|
||||
/**
|
||||
* This is an optional capability interface that is intended to be implemented by any
|
||||
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports basic user querying. You must
|
||||
* <code>UserStorageProvider</code> that supports basic user querying. You must
|
||||
* implement this interface if you want to be able to log in to keycloak using users from your storage.
|
||||
* <p/>
|
||||
* Note that all methods in this interface should limit search only to data available within the storage that is
|
||||
|
|
|
@ -31,7 +31,7 @@ import java.util.stream.Stream;
|
|||
/**
|
||||
*
|
||||
* This is an optional capability interface that is intended to be implemented by any
|
||||
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports complex user querying. You must
|
||||
* <code>UserStorageProvider</code> that supports complex user querying. You must
|
||||
* implement this interface if you want to view and manage users from the administration console.
|
||||
* <p/>
|
||||
* Note that all methods in this interface should limit search only to data available within the storage that is
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.keycloak.models.UserModel;
|
|||
|
||||
/**
|
||||
* This is an optional capability interface that is intended to be implemented by any
|
||||
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports addition of new users. You must
|
||||
* <code>UserStorageProvider</code> that supports addition of new users. You must
|
||||
* implement this interface if you want to use this storage for registering new users.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
|
|
@ -25,11 +25,11 @@ import org.keycloak.models.UserModel;
|
|||
import org.keycloak.models.cache.CachedUserModel;
|
||||
import org.keycloak.models.cache.OnUserCache;
|
||||
import org.keycloak.models.cache.UserCache;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.storage.AbstractStorageManager;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderFactory;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
|
@ -41,11 +41,11 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserCredentialStoreManager extends AbstractStorageManager<UserStorageProvider, UserStorageProviderModel>
|
||||
public class UserCredentialStoreManager extends AbstractStorageManager<Provider, CacheableStorageProviderModel>
|
||||
implements UserCredentialManager.Streams, OnUserCache {
|
||||
|
||||
public UserCredentialStoreManager(KeycloakSession session) {
|
||||
super(session, UserStorageProviderFactory.class, UserStorageProvider.class, UserStorageProviderModel::new, "user");
|
||||
super(session, ProviderFactory.class, Provider.class, componentModel -> null, "user");
|
||||
}
|
||||
|
||||
protected UserCredentialStore getStoreForUser(UserModel user) {
|
||||
|
@ -143,6 +143,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
List<CredentialInput> toValidate = new LinkedList<>(inputs);
|
||||
String providerId = StorageId.isLocalStorage(user) ? user.getFederationLink() : StorageId.resolveProviderId(user);
|
||||
if (providerId != null) {
|
||||
/*
|
||||
UserStorageProviderModel model = getStorageProviderModel(realm, providerId);
|
||||
if (model == null || !model.isEnabled()) return false;
|
||||
|
||||
|
@ -150,6 +151,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
if (validator != null) {
|
||||
validate(realm, user, toValidate, validator);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (toValidate.isEmpty()) return true;
|
||||
|
@ -176,6 +178,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
if (!StorageId.isLocalStorage(user)) throwExceptionIfInvalidUser(user);
|
||||
|
||||
if (providerId != null) {
|
||||
/*
|
||||
UserStorageProviderModel model = getStorageProviderModel(realm, providerId);
|
||||
if (model == null || !model.isEnabled()) return false;
|
||||
|
||||
|
@ -183,6 +186,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
if (updater != null && updater.supportsCredentialType(input.getType())) {
|
||||
if (updater.updateCredential(realm, user, input)) return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return getCredentialProviders(session, CredentialInputUpdater.class)
|
||||
|
@ -195,6 +199,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
String providerId = StorageId.isLocalStorage(user) ? user.getFederationLink() : StorageId.resolveProviderId(user);
|
||||
if (!StorageId.isLocalStorage(user)) throwExceptionIfInvalidUser(user);
|
||||
if (providerId != null) {
|
||||
/*
|
||||
UserStorageProviderModel model = getStorageProviderModel(realm, providerId);
|
||||
if (model == null || !model.isEnabled()) return;
|
||||
|
||||
|
@ -202,6 +207,8 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
if (updater.supportsCredentialType(credentialType)) {
|
||||
updater.disableCredentialType(realm, user, credentialType);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
getCredentialProviders(session, CredentialInputUpdater.class)
|
||||
|
@ -214,11 +221,13 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
Stream<String> types = Stream.empty();
|
||||
String providerId = StorageId.isLocalStorage(user) ? user.getFederationLink() : StorageId.resolveProviderId(user);
|
||||
if (providerId != null) {
|
||||
/*
|
||||
UserStorageProviderModel model = getStorageProviderModel(realm, providerId);
|
||||
if (model == null || !model.isEnabled()) return types;
|
||||
|
||||
CredentialInputUpdater updater = getStorageProviderInstance(model, CredentialInputUpdater.class);
|
||||
if (updater != null) types = updater.getDisableableCredentialTypesStream(realm, user);
|
||||
*/
|
||||
}
|
||||
|
||||
return Stream.concat(types, getCredentialProviders(session, CredentialInputUpdater.class)
|
||||
|
@ -251,6 +260,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
private UserStorageCredentialConfigured isConfiguredThroughUserStorage(RealmModel realm, UserModel user, String type) {
|
||||
String providerId = StorageId.isLocalStorage(user) ? user.getFederationLink() : StorageId.resolveProviderId(user);
|
||||
if (providerId != null) {
|
||||
/*
|
||||
UserStorageProviderModel model = getStorageProviderModel(realm, providerId);
|
||||
if (model == null || !model.isEnabled()) return UserStorageCredentialConfigured.USER_STORAGE_DISABLED;
|
||||
|
||||
|
@ -258,6 +268,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
|
|||
if (validator != null && validator.supportsCredentialType(type) && validator.isConfiguredFor(realm, user, type)) {
|
||||
return UserStorageCredentialConfigured.CONFIGURED;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return UserStorageCredentialConfigured.NOT_CONFIGURED;
|
||||
|
|
|
@ -148,7 +148,7 @@ public class LDAPSyncTest extends AbstractLDAPTest {
|
|||
|
||||
// Assert lastSync time updated
|
||||
Assert.assertTrue(ctx.getLdapModel().getLastSync() > 0);
|
||||
testRealm.getUserStorageProvidersStream().forEachOrdered(persistentFedModel -> {
|
||||
UserStorageUtil.getUserStorageProvidersStream(testRealm).forEachOrdered(persistentFedModel -> {
|
||||
if (LDAPStorageProviderFactory.PROVIDER_NAME.equals(persistentFedModel.getProviderId())) {
|
||||
Assert.assertTrue(persistentFedModel.getLastSync() > 0);
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderFactory;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -22,10 +23,6 @@ public class UserStorageProvidersTestUtils {
|
|||
return model.isEnabled();
|
||||
}
|
||||
|
||||
public static Stream<UserStorageProviderModel> getStorageProviders(RealmModel realm) {
|
||||
return realm.getUserStorageProvidersStream();
|
||||
}
|
||||
|
||||
private static UserStorageProviderFactory getUserStorageProviderFactory(UserStorageProviderModel model, KeycloakSession session) {
|
||||
return (UserStorageProviderFactory) session.getKeycloakSessionFactory()
|
||||
.getProviderFactory(UserStorageProvider.class, model.getProviderId());
|
||||
|
@ -50,7 +47,7 @@ public class UserStorageProvidersTestUtils {
|
|||
}
|
||||
|
||||
public static <T> Stream<UserStorageProviderModel> getStorageProviders(RealmModel realm, KeycloakSession session, Class<T> type) {
|
||||
return realm.getUserStorageProvidersStream()
|
||||
return UserStorageUtil.getUserStorageProvidersStream(realm)
|
||||
.filter(model -> {
|
||||
UserStorageProviderFactory factory = getUserStorageProviderFactory(model, session);
|
||||
if (factory == null) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import org.junit.runners.MethodSorters;
|
|||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.managers.UserStorageSyncManager;
|
||||
import org.keycloak.storage.managers.UserStorageSyncManager;
|
||||
import org.keycloak.storage.UserStorageProvider;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.user.SynchronizationResult;
|
||||
|
|
|
@ -20,9 +20,11 @@ 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.utils.KeycloakModelUtils;
|
||||
import org.keycloak.services.managers.UserStorageSyncManager;
|
||||
import org.keycloak.storage.managers.UserStorageSyncManager;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.UserStorageUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
|
@ -35,7 +37,7 @@ public class SyncDummyFederationProviderCommand extends AbstractCommand {
|
|||
int changedSyncPeriod = getIntArg(1);
|
||||
|
||||
RealmModel realm = session.realms().getRealmByName("master");
|
||||
UserStorageProviderModel fedProviderModel = KeycloakModelUtils.findUserStorageProviderByName("cluster-dummy", realm);
|
||||
UserStorageProviderModel fedProviderModel = findUserStorageProviderByName(session, "cluster-dummy", realm);
|
||||
if (fedProviderModel == null) {
|
||||
MultivaluedHashMap<String, String> cfg = fedProviderModel.getConfig();
|
||||
updateConfig(cfg, waitTime);
|
||||
|
@ -64,6 +66,16 @@ public class SyncDummyFederationProviderCommand extends AbstractCommand {
|
|||
cfg.putSingle("wait-time", String.valueOf(waitTime));
|
||||
}
|
||||
|
||||
public static UserStorageProviderModel findUserStorageProviderByName(KeycloakSession session, String displayName, RealmModel realm) {
|
||||
if (displayName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return UserStorageUtil.getUserStorageProvidersStream(realm)
|
||||
.filter(fedProvider -> Objects.equals(fedProvider.getName(), displayName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
|
Loading…
Reference in a new issue