mirror of
https://github.com/keycloak/keycloak.git
synced 2026-06-08 16:42:13 -04:00
Respect storage provider cache policies for roles and groups
Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
This commit is contained in:
parent
88bb22bb20
commit
8a7a792f95
3 changed files with 152 additions and 259 deletions
|
|
@ -956,10 +956,14 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
long loaded = cache.getCurrentRevision(id);
|
||||
RoleModel model = getRoleDelegate().getRoleById(realm, id);
|
||||
if (model == null) return null;
|
||||
if (invalidations.contains(id)) return model;
|
||||
|
||||
StorageId storageId = new StorageId(id);
|
||||
if (!storageId.isLocal()) {
|
||||
ComponentModel component = realm.getComponent(storageId.getProviderId());
|
||||
if (component == null) {
|
||||
return model;
|
||||
}
|
||||
RoleStorageProviderModel providerModel = new RoleStorageProviderModel(component);
|
||||
if (!providerModel.isEnabled()) {
|
||||
return model;
|
||||
|
|
@ -1015,13 +1019,18 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
}
|
||||
|
||||
if (cached == null) {
|
||||
long loaded = cache.getCurrentRevision(id);
|
||||
RoleModel model = getRoleDelegate().getRoleById(realm, id);
|
||||
if (model == null) return null;
|
||||
cached = createCachedRole(loaded, model, realm);
|
||||
cache.addRevisioned(cached, startupRevision);
|
||||
RoleModel model = cacheRole(realm, id);
|
||||
if (model instanceof RoleAdapter roleAdapter) {
|
||||
return roleAdapter.cached;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return cached;
|
||||
|
||||
RoleModel adapter = validateCachedRole(realm, cached);
|
||||
if (adapter instanceof RoleAdapter roleAdapter) {
|
||||
return roleAdapter.cached;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1058,6 +1067,9 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
StorageId storageId = new StorageId(id);
|
||||
if (!storageId.isLocal()) {
|
||||
ComponentModel component = realm.getComponent(storageId.getProviderId());
|
||||
if (component == null) {
|
||||
return model;
|
||||
}
|
||||
GroupStorageProviderModel providerModel = new GroupStorageProviderModel(component);
|
||||
if (!providerModel.isEnabled()) {
|
||||
return model;
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ import org.keycloak.common.util.MultivaluedHashMap;
|
|||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.cache.infinispan.GroupAdapter;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.group.GroupStorageProvider;
|
||||
import org.keycloak.storage.group.GroupStorageProviderModel;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
|
|
@ -43,7 +46,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class GroupStorageTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
|
|
@ -124,135 +129,56 @@ public class GroupStorageTest extends AbstractTestRealmKeycloakTest {
|
|||
});
|
||||
}
|
||||
|
||||
/*
|
||||
TODO review caching of groups, it behaves a little bit different than clients so following tests fails.
|
||||
Tracked as KEYCLOAK-15135.
|
||||
*/
|
||||
// @Test
|
||||
// public void testDailyEviction() {
|
||||
// testNotCached();
|
||||
@Test
|
||||
public void testNoCache() {
|
||||
testIsCached();
|
||||
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// Calendar eviction = Calendar.getInstance();
|
||||
// eviction.add(Calendar.HOUR, 1);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_DAILY);
|
||||
// model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
// model.setEvictionMinute(eviction.get(MINUTE));
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
// setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
try {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
GroupStorageProviderModel model = new GroupStorageProviderModel(realm.getComponent(providerId));
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
|
||||
// }
|
||||
testNotCached();
|
||||
testNotCached();
|
||||
} finally {
|
||||
setDefaultCachePolicy();
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testWeeklyEviction() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// Calendar eviction = Calendar.getInstance();
|
||||
// eviction.add(Calendar.HOUR, 4 * 24);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_WEEKLY);
|
||||
// model.setEvictionDay(eviction.get(DAY_OF_WEEK));
|
||||
// model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
// model.setEvictionMinute(eviction.get(MINUTE));
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
// setTimeOffset(2 * 24 * 60 * 60); // 2 days in future
|
||||
// testIsCached();
|
||||
// setTimeOffset(5 * 24 * 60 * 60); // 5 days in future
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testMaxLifespan() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN);
|
||||
// model.setMaxLifespan(1 * 60 * 60 * 1000);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
//
|
||||
// setTimeOffset(1/2 * 60 * 60); // 1/2 hour in future
|
||||
//
|
||||
// testIsCached();
|
||||
//
|
||||
// setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
//
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
//
|
||||
// }
|
||||
testIsCached();
|
||||
}
|
||||
|
||||
// private void testNotCached() {
|
||||
// String providerId = this.providerId;
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// StorageId storageId = new StorageId(providerId, "hardcoded-group");
|
||||
// GroupModel hardcoded = session.groups().getGroupById(realm, storageId.getId());
|
||||
// Assert.assertNotNull(hardcoded);
|
||||
// Assert.assertThat(hardcoded, not(instanceOf(GroupAdapter.class)));
|
||||
// });
|
||||
// }
|
||||
private void testNotCached() {
|
||||
String providerId = this.providerId;
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
StorageId storageId = new StorageId(providerId, "hardcoded-group");
|
||||
GroupModel hardcoded = session.groups().getGroupById(realm, storageId.getId());
|
||||
assertNotNull(hardcoded);
|
||||
assertFalse(hardcoded instanceof GroupAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
// private void testIsCached() {
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleModel hardcoded = realm.getRole("hardcoded-role");
|
||||
// Assert.assertNotNull(hardcoded);
|
||||
// Assert.assertThat(hardcoded, instanceOf(RoleAdapter.class));
|
||||
// });
|
||||
// }
|
||||
private void testIsCached() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
GroupModel hardcoded = session.groups().getGroupById(realm, new StorageId(providerId, "hardcoded-group").getId());
|
||||
assertNotNull(hardcoded);
|
||||
assertTrue(hardcoded instanceof GroupAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testNoCache() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
//
|
||||
// testNotCached();
|
||||
//
|
||||
// // test twice because updating component should evict
|
||||
// testNotCached();
|
||||
//
|
||||
// // set it back
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
// }
|
||||
private void setDefaultCachePolicy() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
GroupStorageProviderModel model = new GroupStorageProviderModel(realm.getComponent(providerId));
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.DEFAULT);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
}
|
||||
|
||||
// private void setDefaultCachePolicy() {
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.DEFAULT);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// }
|
||||
// TODO review caching of groups, it behaves a little bit different than clients so daily/weekly eviction tests still need attention.
|
||||
// Tracked as KEYCLOAK-15135.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ import org.keycloak.common.util.MultivaluedHashMap;
|
|||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.cache.infinispan.RoleAdapter;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.storage.CacheableStorageProviderModel;
|
||||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.role.RoleStorageProvider;
|
||||
import org.keycloak.storage.role.RoleStorageProviderModel;
|
||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.auth.page.AuthRealm;
|
||||
|
|
@ -43,7 +46,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
|||
import static org.hamcrest.Matchers.allOf;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class RoleStorageTest extends AbstractTestRealmKeycloakTest {
|
||||
|
||||
|
|
@ -133,133 +138,83 @@ public class RoleStorageTest extends AbstractTestRealmKeycloakTest {
|
|||
});
|
||||
}
|
||||
|
||||
/*
|
||||
TODO review caching of roles, it behaves a little bit different than clients so following tests fails.
|
||||
Tracked as KEYCLOAK-14938.
|
||||
*/
|
||||
// @Test
|
||||
// public void testDailyEviction() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// Calendar eviction = Calendar.getInstance();
|
||||
// eviction.add(Calendar.HOUR, 1);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_DAILY);
|
||||
// model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
// model.setEvictionMinute(eviction.get(MINUTE));
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
// setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testWeeklyEviction() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// Calendar eviction = Calendar.getInstance();
|
||||
// eviction.add(Calendar.HOUR, 4 * 24);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.EVICT_WEEKLY);
|
||||
// model.setEvictionDay(eviction.get(DAY_OF_WEEK));
|
||||
// model.setEvictionHour(eviction.get(HOUR_OF_DAY));
|
||||
// model.setEvictionMinute(eviction.get(MINUTE));
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
// setTimeOffset(2 * 24 * 60 * 60); // 2 days in future
|
||||
// testIsCached();
|
||||
// setTimeOffset(5 * 24 * 60 * 60); // 5 days in future
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testMaxLifespan() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN);
|
||||
// model.setMaxLifespan(1 * 60 * 60 * 1000);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// testIsCached();
|
||||
//
|
||||
// setTimeOffset(1/2 * 60 * 60); // 1/2 hour in future
|
||||
//
|
||||
// testIsCached();
|
||||
//
|
||||
// setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
//
|
||||
// testNotCached();
|
||||
// testIsCached();
|
||||
//
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void testNotCached() {
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleModel hardcoded = realm.getRole("hardcoded-role");
|
||||
// Assert.assertNotNull(hardcoded);
|
||||
// Assert.assertThat(hardcoded, not(instanceOf(RoleAdapter.class)));
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// private void testIsCached() {
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleModel hardcoded = realm.getRole("hardcoded-role");
|
||||
// Assert.assertNotNull(hardcoded);
|
||||
// Assert.assertThat(hardcoded, instanceOf(RoleAdapter.class));
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testNoCache() {
|
||||
// testNotCached();
|
||||
//
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
//
|
||||
// testNotCached();
|
||||
//
|
||||
// // test twice because updating component should evict
|
||||
// testNotCached();
|
||||
//
|
||||
// // set it back
|
||||
// setDefaultCachePolicy();
|
||||
// testIsCached();
|
||||
// }
|
||||
//
|
||||
// private void setDefaultCachePolicy() {
|
||||
// testingClient.server().run(session -> {
|
||||
// RealmModel realm = session.realms().getRealmByName("test");
|
||||
// RoleStorageProviderModel model = realm.getRoleStorageProviders().get(0);
|
||||
// model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.DEFAULT);
|
||||
// realm.updateComponent(model);
|
||||
// });
|
||||
// }
|
||||
@Test
|
||||
public void testNoCache() {
|
||||
testIsCached();
|
||||
|
||||
try {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleStorageProviderModel model = new RoleStorageProviderModel(realm.getComponent(providerId));
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
|
||||
testNotCached();
|
||||
testNotCached();
|
||||
} finally {
|
||||
setDefaultCachePolicy();
|
||||
}
|
||||
|
||||
testIsCached();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxLifespan() {
|
||||
testIsCached();
|
||||
|
||||
try {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleStorageProviderModel model = new RoleStorageProviderModel(realm.getComponent(providerId));
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.MAX_LIFESPAN);
|
||||
model.setMaxLifespan(1 * 60 * 60 * 1000);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
|
||||
testIsCached();
|
||||
|
||||
setTimeOffset(30 * 60); // 1/2 hour in future
|
||||
testIsCached();
|
||||
|
||||
setTimeOffset(2 * 60 * 60); // 2 hours in future
|
||||
testNotCached();
|
||||
testIsCached();
|
||||
} finally {
|
||||
resetTimeOffset();
|
||||
setDefaultCachePolicy();
|
||||
}
|
||||
|
||||
testIsCached();
|
||||
}
|
||||
|
||||
private void testNotCached() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleModel hardcoded = realm.getRole("hardcoded-role");
|
||||
assertNotNull(hardcoded);
|
||||
assertFalse(hardcoded instanceof RoleAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
private void testIsCached() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleModel hardcoded = realm.getRole("hardcoded-role");
|
||||
assertNotNull(hardcoded);
|
||||
assertTrue(hardcoded instanceof RoleAdapter);
|
||||
});
|
||||
}
|
||||
|
||||
private void setDefaultCachePolicy() {
|
||||
testingClient.server().run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName("test");
|
||||
RoleStorageProviderModel model = new RoleStorageProviderModel(realm.getComponent(providerId));
|
||||
model.setCachePolicy(CacheableStorageProviderModel.CachePolicy.DEFAULT);
|
||||
realm.updateComponent(model);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO review caching of roles, it behaves a little bit different than clients so daily/weekly eviction tests still need attention.
|
||||
// Tracked as KEYCLOAK-14938.
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue