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
|
@Override
|
||||||
public SynchronizationResult call() throws Exception {
|
public SynchronizationResult call() throws Exception {
|
||||||
updateLastSyncInterval(sessionFactory, provider, realmId);
|
int lastSync = Time.currentTime();
|
||||||
return ((ImportSynchronization)factory).sync(sessionFactory, realmId, provider);
|
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 {
|
public SynchronizationResult call() throws Exception {
|
||||||
// See when we did last sync.
|
// See when we did last sync.
|
||||||
int oldLastSync = provider.getLastSync();
|
int oldLastSync = provider.getLastSync();
|
||||||
updateLastSyncInterval(sessionFactory, provider, realmId);
|
int lastSync = Time.currentTime();
|
||||||
return ((ImportSynchronization)factory).syncSince(Time.toDate(oldLastSync), sessionFactory, realmId, provider);
|
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
|
// 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() {
|
KeycloakModelUtils.runJobInTransaction(sessionFactory, new KeycloakSessionTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -272,7 +280,6 @@ public class UserStorageSyncManager {
|
||||||
.filter(persistentFedProvider -> Objects.equals(provider.getId(), persistentFedProvider.getId()))
|
.filter(persistentFedProvider -> Objects.equals(provider.getId(), persistentFedProvider.getId()))
|
||||||
.forEachOrdered(persistentFedProvider -> {
|
.forEachOrdered(persistentFedProvider -> {
|
||||||
// Update persistent provider in DB
|
// Update persistent provider in DB
|
||||||
int lastSync = Time.currentTime();
|
|
||||||
persistentFedProvider.setLastSync(lastSync);
|
persistentFedProvider.setLastSync(lastSync);
|
||||||
persistentRealm.updateComponent(persistentFedProvider);
|
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.UserPropertyFileStorageFactory
|
||||||
org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProviderFactory
|
org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProviderFactory
|
||||||
org.keycloak.testsuite.federation.sync.SyncDummyUserFederationProviderFactory
|
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) {
|
private static void sleep(long ms) {
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in a new issue