use of org.keycloak.component.ComponentModel in project keycloak by keycloak.
the class LDAPGroupMapperSyncTest method test06_ldapGroupsSyncHasLinearTimeComplexity.
// KEYCLOAK-8253 - Test if synchronization of large number of LDAP groups takes linear time
@Ignore("This test is not suitable for regular CI testing due to higher time / performance demand")
@Test
public void test06_ldapGroupsSyncHasLinearTimeComplexity() throws Exception {
// Count of LDAP groups to test the duration of the sync operation. Defaults to 30k unless overridden via system property
final int GROUPS_COUNT = (System.getProperties().containsKey(TEST_LDAP_GROUPS_SYNC_LINEAR_TIME_GROUPS_COUNT)) ? Integer.valueOf(System.getProperty(TEST_LDAP_GROUPS_SYNC_LINEAR_TIME_GROUPS_COUNT)) : 30000;
// Period on how often (per how many groups) to perform the LDAP groups sync test & report the results back.
// Defaults to 1k unless overridden via system property
final int TEST_PERIOD = (System.getProperties().containsKey(TEST_LDAP_GROUPS_SYNC_LINEAR_TIME_TEST_PERIOD)) ? Integer.valueOf(System.getProperty(TEST_LDAP_GROUPS_SYNC_LINEAR_TIME_TEST_PERIOD)) : 1000;
// Reset 'batchSizeForSync' configuration option to the default value of 'LDAPConstants.BATCH_SIZE_FOR_SYNC'
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
ctx.getLdapModel().put(LDAPConstants.BATCH_SIZE_FOR_SYNC, Integer.toString(1000));
ctx.getRealm().updateComponent(ctx.getLdapModel());
// Set group mapper to skip preservation of inheritance to test group creation
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(ctx.getRealm(), ctx.getLdapModel(), "groupsMapper");
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.PRESERVE_GROUP_INHERITANCE, "false");
ctx.getRealm().updateComponent(mapperModel);
});
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
// Remove all LDAP groups
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ctx.getLdapModel(), "groupsMapper");
/* The following for loop doesn't really test true time it took to synchronize N * TEST_PERIOD LDAP groups.
* Instead of that, in this test only time of syncing last TEST_PERIOD groups is reported. The previously
* created groups, existing as the result of (N-1)-th iteration are "just" updated.
* Also see NOTE: and the subsequent for loop, commented out, below for details.
*/
Long elapsedTime = new Long(0);
for (int i = 1; i <= GROUPS_COUNT; i++) {
LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), String.format("group-%s", i), descriptionAttrName, String.format("Testing group-%s, created at: %s", i, new Date().toString()));
if (i != 0 && i % TEST_PERIOD == 0) {
// Start the timer
elapsedTime = new Date().getTime();
// Sync the LDAP groups
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
elapsedTime = new Date().getTime() - elapsedTime;
logger.debugf("Synced %s LDAP groups in %s ms", Long.valueOf(i), elapsedTime);
}
}
/* NOTE: The nested for loop below would be better test to check duration of groups syncing,
* since it would delete the LDAP groups created in (N - 1)-th iteration, create count
* of LDAP required by N-th iteration, and report back the syncing time. But it is commented
* out, because in the current form Apache DS always returns HTTP 505 Internal Server error for
* upon reaching 3k groups - in 3-th iteration of the main for loop
*
long elapsedTime = new Long(0);
for (int i = 1; i <= GROUPS_COUNT; i++) {
int groupsPerIteration = i * TEST_PERIOD;
logger.debugf("Creating %s LDAP groups", groupsPerIteration);
for (int j = 1; j <= groupsPerIteration; j++) {
LDAPTestUtils.createLDAPGroup(session,
appRealm,
ctx.getLdapModel(),
String.format("group-%s", j),
descriptionAttrName,
String.format("Testing group-%s, created at: %s", j, new Date().toString())
);
}
logger.debugf("Done creating %s LDAP groups!", groupsPerIteration);
elapsedTime = new Date().getTime();
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
logger.debugf("Synced %s LDAP groups in %s ms", groupsPerIteration, new Date().getTime() - elapsedTime);
if (appRealm.getTopLevelGroups().size() != 0) {
LDAPTestUtils.removeAllLDAPGroups(session, appRealm, ctx.getLdapModel(), "groupsMapper");
}
}*/
});
}
use of org.keycloak.component.ComponentModel in project keycloak by keycloak.
the class LDAPGroupMapperTest method test05_getGroupsFromUserMemberOfStrategyTest.
// KEYCLOAK-5848
// Test GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE with custom 'Member-Of LDAP Attribute'. As a workaround, we are testing this with custom attribute "street"
// just because it's available on all the LDAP servers
@Test
public void test05_getGroupsFromUserMemberOfStrategyTest() throws Exception {
ComponentRepresentation groupMapperRep = findMapperRepByName("groupsMapper");
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Create street attribute mapper
LDAPTestUtils.addUserAttributeMapper(appRealm, ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);
// Find DN of "group1"
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
LDAPObject ldapGroup = groupMapper.loadLDAPGroupByName("group1");
String ldapGroupDN = ldapGroup.getDn().toString();
// Create new user in LDAP. Add him some "street" referencing existing LDAP Group
LDAPObject carlos = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "carloskeycloak", "Carlos", "Doel", "carlos.doel@email.org", ldapGroupDN, "1234");
LDAPTestUtils.updateLDAPPassword(ctx.getLdapProvider(), carlos, "Password1");
// Update group mapper
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, GroupMapperConfig.GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE, GroupMapperConfig.MEMBEROF_LDAP_ATTRIBUTE, LDAPConstants.STREET);
appRealm.updateComponent(mapperModel);
});
ComponentRepresentation streetMapperRep = findMapperRepByName("streetMapper");
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Get user in Keycloak. Ensure that he is member of requested group
UserModel carlos = session.users().getUserByUsername(appRealm, "carloskeycloak");
Set<GroupModel> carlosGroups = carlos.getGroupsStream().collect(Collectors.toSet());
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
Assert.assertTrue(carlosGroups.contains(group1));
Assert.assertFalse(carlosGroups.contains(group11));
Assert.assertFalse(carlosGroups.contains(group12));
Assert.assertEquals(1, carlosGroups.size());
});
// Revert mappers
testRealm().components().component(streetMapperRep.getId()).remove();
groupMapperRep.getConfig().putSingle(GroupMapperConfig.USER_ROLES_RETRIEVE_STRATEGY, GroupMapperConfig.LOAD_GROUPS_BY_MEMBER_ATTRIBUTE);
testRealm().components().component(groupMapperRep.getId()).update(groupMapperRep);
}
use of org.keycloak.component.ComponentModel in project keycloak by keycloak.
the class LDAPGroupMapperTest method test08_ldapOnlyGroupMappingsRanged.
@Test
public void test08_ldapOnlyGroupMappingsRanged() {
testingClient.server().run(session -> {
// try to do 3 pages (30+30+1)
int membersToTest = 61;
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
appRealm.updateComponent(mapperModel);
// Ignoring this test on ActiveDirectory and rhds as it's currently impossible to import more than 60 users without timeout
LDAPConfig ldapConfig = ctx.getLdapProvider().getLdapIdentityStore().getConfig();
if (ldapConfig.isActiveDirectory() || LDAPConstants.VENDOR_RHDS.equals(ldapConfig.getVendor())) {
return;
}
// create big grups that use ranged search
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
LDAPObject bigGroup = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "biggroup", descriptionAttrName, "biggroup - description");
// create the users to use range search and add them to the group
for (int i = 0; i < membersToTest; i++) {
String username = String.format("user%02d", i);
LDAPObject user = LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, username, username, username, username + "@email.org", null, "1234");
LDAPUtils.addMember(ctx.getLdapProvider(), MembershipType.DN, LDAPConstants.MEMBER, "not-used", bigGroup, user);
}
// check if ranged intercetor is in place and working
GroupMapperConfig config = new GroupMapperConfig(mapperModel);
bigGroup = LDAPGroupMapperTest.searchObjectInBase(ctx.getLdapProvider(), bigGroup.getDn().toString(), config.getMembershipLdapAttribute());
Assert.assertNotNull(bigGroup.getAttributes().get(config.getMembershipLdapAttribute()));
Assert.assertFalse(bigGroup.isRangeComplete(config.getMembershipLdapAttribute()));
Assert.assertTrue(membersToTest > bigGroup.getAttributeAsSet(config.getMembershipLdapAttribute()).size());
Assert.assertEquals(bigGroup.getCurrentRange(config.getMembershipLdapAttribute()), bigGroup.getAttributeAsSet(config.getMembershipLdapAttribute()).size() - 1);
// now check the population of ranged attributes is OK
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
GroupModel kcBigGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/biggroup");
// check all the users have the group assigned
for (int i = 0; i < membersToTest; i++) {
UserModel kcUser = session.users().getUserByUsername(appRealm, String.format("user%02d", i));
Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup));
}
// check the group contains all the users as member
List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcBigGroup, 0, membersToTest).collect(Collectors.toList());
Assert.assertEquals(membersToTest, groupMembers.size());
Set<String> usernames = groupMembers.stream().map(u -> u.getUsername()).collect(Collectors.toSet());
for (int i = 0; i < membersToTest; i++) {
Assert.assertTrue("Group contains user " + i, usernames.contains(String.format("user%02d", i)));
}
});
}
use of org.keycloak.component.ComponentModel in project keycloak by keycloak.
the class LDAPProvidersIntegrationNoImportTest method testFullNameMapperWriteOnly.
@Test
public void testFullNameMapperWriteOnly() {
ComponentRepresentation firstNameMapperRep = testingClient.server().fetch(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// assert that user "fullnameUser" is not in local DB
Assert.assertNull(session.users().getUserByUsername(appRealm, "fullname"));
// Add the user with some fullName into LDAP directly. Ensure that fullName is saved into "cn" attribute in LDAP (currently mapped to model firstName)
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(appRealm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
LDAPTestUtils.addLDAPUser(ldapFedProvider, appRealm, "fullname", "James Dee", "Dee", "fullname@email.org", null, "4578");
// add fullname mapper to the provider and remove "firstNameMapper". For this test, we will simply map full name to the LDAP attribute, which was before firstName ( "givenName" on active directory, "cn" on other LDAP servers)
ComponentModel firstNameMapper = LDAPTestUtils.getSubcomponentByName(appRealm, ldapModel, "first name");
String ldapFirstNameAttributeName = firstNameMapper.getConfig().getFirst(UserAttributeLDAPStorageMapper.LDAP_ATTRIBUTE);
appRealm.removeComponent(firstNameMapper);
ComponentRepresentation firstNameMapperRepp = ModelToRepresentation.toRepresentation(session, firstNameMapper, true);
ComponentModel fullNameMapperModel = KeycloakModelUtils.createComponentModel("full name", ldapModel.getId(), FullNameLDAPStorageMapperFactory.PROVIDER_ID, LDAPStorageMapper.class.getName(), FullNameLDAPStorageMapper.LDAP_FULL_NAME_ATTRIBUTE, ldapFirstNameAttributeName, FullNameLDAPStorageMapper.READ_ONLY, "false");
appRealm.addComponentModel(fullNameMapperModel);
return firstNameMapperRepp;
}, ComponentRepresentation.class);
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578");
// change mapper to writeOnly
ComponentModel fullNameMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "full name");
fullNameMapperModel.getConfig().putSingle(FullNameLDAPStorageMapper.WRITE_ONLY, "true");
appRealm.updateComponent(fullNameMapperModel);
});
// User will be changed in LDAP too
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel fullnameUser = session.users().getUserByUsername(appRealm, "fullname");
fullnameUser.setFirstName("James2");
fullnameUser.setLastName("Dee2");
});
// Assert changed user available in Keycloak, but his firstName is null (due the fullnameMapper is write-only and firstName mapper is removed)
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
// Assert user is successfully imported in Keycloak DB now with correct firstName and lastName
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", null, "Dee2", "fullname@email.org", "4578");
// Remove "fullnameUser" to assert he is removed from LDAP. Revert mappers to previous state
UserModel fullnameUser = session.users().getUserByUsername(appRealm, "fullname");
session.users().removeUser(appRealm, fullnameUser);
// Revert mappers
ComponentModel fullNameMapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "full name");
appRealm.removeComponent(fullNameMapperModel);
});
firstNameMapperRep.setId(null);
Response response = testRealm().components().add(firstNameMapperRep);
Assert.assertEquals(201, response.getStatus());
response.close();
}
use of org.keycloak.component.ComponentModel in project keycloak by keycloak.
the class BrokenUserStorageTest method testBootWithBadProviderId.
@Test
public void testBootWithBadProviderId() throws Exception {
testingClient.server().run(session -> {
// set this system property
System.setProperty(RealmAdapter.COMPONENT_PROVIDER_EXISTS_DISABLED, "true");
RealmModel realm = session.realms().getRealmByName("master");
UserStorageProviderModel model = new UserStorageProviderModel();
model.setName("bad-provider-id");
model.setPriority(2);
model.setParentId(realm.getId());
model.setProviderId("error");
ComponentModel component = realm.importComponentModel(model);
});
controller.stop(suiteContext.getAuthServerInfo().getQualifier());
controller.start(suiteContext.getAuthServerInfo().getQualifier());
reconnectAdminClient();
loginSuccessAndLogout("test-user@localhost", "password");
// make sure we can list components and delete provider as this is an admin console operation
RealmResource master = adminClient.realms().realm("master");
String masterId = master.toRepresentation().getId();
List<ComponentRepresentation> components = master.components().query(masterId, UserStorageProvider.class.getName());
ComponentRepresentation found = null;
for (ComponentRepresentation rep : components) {
if (rep.getName().equals("bad-provider-id")) {
found = rep;
}
}
Assert.assertNotNull(found);
master.components().component(found.getId()).remove();
List<ComponentRepresentation> components2 = master.components().query(masterId, UserStorageProvider.class.getName());
Assert.assertEquals(components.size() - 1, components2.size());
}
Aggregations