lastSync value into COMPONENT_CONFIG is always updated
Closes https://github.com/keycloak/keycloak/issues/17022
This commit is contained in:
parent
cb78ea06b0
commit
9995a3cdd4
4 changed files with 103 additions and 6 deletions
|
@ -105,8 +105,12 @@ public class UserStorageSyncManager {
|
|||
|
||||
@Override
|
||||
public SynchronizationResult call() throws Exception {
|
||||
updateLastSyncInterval(sessionFactory, provider, realmId);
|
||||
return ((ImportSynchronization)factory).sync(sessionFactory, realmId, provider);
|
||||
int lastSync = Time.currentTime();
|
||||
SynchronizationResult result = ((ImportSynchronization)factory).sync(sessionFactory, realmId, provider);
|
||||
if (!result.isIgnored()) {
|
||||
updateLastSyncInterval(sessionFactory, provider, realmId, lastSync);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -147,8 +151,12 @@ public class UserStorageSyncManager {
|
|||
public SynchronizationResult call() throws Exception {
|
||||
// See when we did last sync.
|
||||
int oldLastSync = provider.getLastSync();
|
||||
updateLastSyncInterval(sessionFactory, provider, realmId);
|
||||
return ((ImportSynchronization)factory).syncSince(Time.toDate(oldLastSync), sessionFactory, realmId, provider);
|
||||
int lastSync = Time.currentTime();
|
||||
SynchronizationResult result = ((ImportSynchronization)factory).syncSince(Time.toDate(oldLastSync), sessionFactory, realmId, provider);
|
||||
if (!result.isIgnored()) {
|
||||
updateLastSyncInterval(sessionFactory, provider, realmId, lastSync);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -262,7 +270,7 @@ public class UserStorageSyncManager {
|
|||
}
|
||||
|
||||
// Update interval of last sync for given UserFederationProviderModel. Do it in separate transaction
|
||||
private static void updateLastSyncInterval(final KeycloakSessionFactory sessionFactory, UserStorageProviderModel provider, final String realmId) {
|
||||
private static void updateLastSyncInterval(final KeycloakSessionFactory sessionFactory, UserStorageProviderModel provider, final String realmId, final int lastSync) {
|
||||
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||
|
||||
@Override
|
||||
|
@ -272,7 +280,6 @@ public class UserStorageSyncManager {
|
|||
.filter(persistentFedProvider -> Objects.equals(provider.getId(), persistentFedProvider.getId()))
|
||||
.forEachOrdered(persistentFedProvider -> {
|
||||
// Update persistent provider in DB
|
||||
int lastSync = Time.currentTime();
|
||||
persistentFedProvider.setLastSync(lastSync);
|
||||
persistentRealm.updateComponent(persistentFedProvider);
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2023 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.sync;
|
||||
|
||||
import java.util.Date;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.storage.UserStorageProviderModel;
|
||||
import org.keycloak.storage.user.SynchronizationResult;
|
||||
import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory;
|
||||
|
||||
/**
|
||||
* <p>Test UserStorageProviderFactory in which sync methods are always ignored.</p>
|
||||
*
|
||||
* @author rmartinc
|
||||
*/
|
||||
public class IgnoredDummyUserFederationProviderFactory extends DummyUserFederationProviderFactory {
|
||||
|
||||
public static final String IGNORED_PROVIDER_ID = "ignored-dummy";
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return IGNORED_PROVIDER_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SynchronizationResult sync(KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) {
|
||||
return SynchronizationResult.ignored();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SynchronizationResult syncSince(Date lastSync, KeycloakSessionFactory sessionFactory, String realmId, UserStorageProviderModel model) {
|
||||
return SynchronizationResult.ignored();
|
||||
}
|
||||
}
|
|
@ -5,3 +5,4 @@ org.keycloak.testsuite.federation.UserMapStorageFactory
|
|||
org.keycloak.testsuite.federation.UserPropertyFileStorageFactory
|
||||
org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProviderFactory
|
||||
org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory
|
||||
org.keycloak.testsuite.federation.sync.IgnoredDummyUserFederationProviderFactory
|
||||
|
|
|
@ -320,6 +320,46 @@ public class SyncFederationTest extends AbstractAuthTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test04IgnoredSync() throws Exception {
|
||||
// Add IgnoredDummyUserFederationProviderFactory provider
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel appRealm = session.realms().getRealmByName(AuthRealm.TEST);
|
||||
UserStorageProviderModel model = new UserStorageProviderModel();
|
||||
model.setProviderId(IgnoredDummyUserFederationProviderFactory.IGNORED_PROVIDER_ID);
|
||||
model.setPriority(1);
|
||||
model.setName("test-sync-dummy");
|
||||
model.setFullSyncPeriod(-1);
|
||||
model.setChangedSyncPeriod(-1);
|
||||
model.setLastSync(0);
|
||||
appRealm.addComponentModel(model);
|
||||
});
|
||||
|
||||
// run both sync methods that will be ignored
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel appRealm = session.realms().getRealmByName(AuthRealm.TEST);
|
||||
UserStorageProviderModel dummyModel = findDummyProviderModel(appRealm);
|
||||
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
|
||||
SynchronizationResult syncResult = UserStorageSyncManager.syncAllUsers(sessionFactory, appRealm.getId(), dummyModel);
|
||||
Assert.assertTrue(syncResult.isIgnored());
|
||||
syncResult = UserStorageSyncManager.syncChangedUsers(sessionFactory, appRealm.getId(), dummyModel);
|
||||
Assert.assertTrue(syncResult.isIgnored());
|
||||
});
|
||||
|
||||
// assert the last sync is not updated
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel appRealm = session.realms().getRealmByName(AuthRealm.TEST);
|
||||
UserStorageProviderModel dummyModel = findDummyProviderModel(appRealm);
|
||||
Assert.assertEquals(0, dummyModel.getLastSync());
|
||||
});
|
||||
|
||||
// remove provider
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel appRealm = session.realms().getRealmByName(AuthRealm.TEST);
|
||||
UserStorageProviderModel dummyModel = findDummyProviderModel(appRealm);
|
||||
appRealm.removeComponent(dummyModel);
|
||||
});
|
||||
}
|
||||
|
||||
private static void sleep(long ms) {
|
||||
try {
|
||||
|
|
Loading…
Reference in a new issue