use of org.keycloak.storage.ldap.idm.model.LDAPDn in project keycloak by keycloak.
the class LDAPIdentityStore method populateAttributedType.
private LDAPObject populateAttributedType(SearchResult searchResult, LDAPQuery ldapQuery) {
Set<String> readOnlyAttrNames = ldapQuery.getReturningReadOnlyLdapAttributes();
Set<String> lowerCasedAttrNames = new TreeSet<>();
for (String attrName : ldapQuery.getReturningLdapAttributes()) {
lowerCasedAttrNames.add(attrName.toLowerCase());
}
try {
String entryDN = searchResult.getNameInNamespace();
Attributes attributes = searchResult.getAttributes();
LDAPObject ldapObject = new LDAPObject();
LDAPDn dn = LDAPDn.fromString(entryDN);
ldapObject.setDn(dn);
ldapObject.setRdnAttributeNames(dn.getFirstRdn().getAllKeys());
NamingEnumeration<? extends Attribute> ldapAttributes = attributes.getAll();
while (ldapAttributes.hasMore()) {
Attribute ldapAttribute = ldapAttributes.next();
try {
ldapAttribute.get();
} catch (NoSuchElementException nsee) {
continue;
}
String ldapAttributeName = ldapAttribute.getID();
// check for ranged attribute
Matcher m = rangePattern.matcher(ldapAttributeName);
if (m.matches()) {
ldapAttributeName = m.group(1);
// range=X-* means all the attributes returned
if (!m.group(3).equals("*")) {
try {
int max = Integer.parseInt(m.group(3));
ldapObject.addRangedAttribute(ldapAttributeName, max);
} catch (NumberFormatException e) {
logger.warnf("Invalid ranged expresion for attribute: %s", m.group(0));
}
}
}
if (ldapAttributeName.equalsIgnoreCase(getConfig().getUuidLDAPAttributeName())) {
Object uuidValue = ldapAttribute.get();
ldapObject.setUuid(this.operationManager.decodeEntryUUID(uuidValue));
}
// Note: UUID is normally not populated here. It's populated just in case that it's used for name of other attribute as well
if (!ldapAttributeName.equalsIgnoreCase(getConfig().getUuidLDAPAttributeName()) || (lowerCasedAttrNames.contains(ldapAttributeName.toLowerCase()))) {
Set<String> attrValues = new LinkedHashSet<>();
NamingEnumeration<?> enumm = ldapAttribute.getAll();
while (enumm.hasMoreElements()) {
Object val = enumm.next();
if (val instanceof byte[]) {
// byte[]
String attrVal = Base64.encodeBytes((byte[]) val);
attrValues.add(attrVal);
} else {
// String
String attrVal = val.toString().trim();
attrValues.add(attrVal);
}
}
if (ldapAttributeName.equalsIgnoreCase(LDAPConstants.OBJECT_CLASS)) {
ldapObject.setObjectClasses(attrValues);
} else {
ldapObject.setAttribute(ldapAttributeName, attrValues);
// readOnlyAttrNames are lower-cased
if (readOnlyAttrNames.contains(ldapAttributeName.toLowerCase())) {
ldapObject.addReadOnlyAttributeName(ldapAttributeName);
}
}
}
}
if (logger.isTraceEnabled()) {
logger.tracef("Found ldap object and populated with the attributes. LDAP Object: %s", ldapObject.toString());
}
return ldapObject;
} catch (Exception e) {
throw new ModelException("Could not populate attribute type " + searchResult.getNameInNamespace() + ".", e);
}
}
use of org.keycloak.storage.ldap.idm.model.LDAPDn in project keycloak by keycloak.
the class LDAPIdentityStore method checkRename.
protected void checkRename(LDAPObject ldapObject) {
LDAPDn.RDN firstRdn = ldapObject.getDn().getFirstRdn();
String oldDn = ldapObject.getDn().toString();
// Detect which keys will need to be updated in RDN, which are new keys to be added, and which are to be removed
List<String> toUpdateKeys = firstRdn.getAllKeys();
toUpdateKeys.retainAll(ldapObject.getRdnAttributeNames());
List<String> toRemoveKeys = firstRdn.getAllKeys();
toRemoveKeys.removeAll(ldapObject.getRdnAttributeNames());
List<String> toAddKeys = new ArrayList<>(ldapObject.getRdnAttributeNames());
toAddKeys.removeAll(firstRdn.getAllKeys());
// Go through all the keys in the oldRDN and doublecheck if they are changed or not
boolean changed = false;
for (String attrKey : toUpdateKeys) {
if (ldapObject.getReadOnlyAttributeNames().contains(attrKey.toLowerCase())) {
continue;
}
String rdnAttrVal = ldapObject.getAttributeAsString(attrKey);
// Could be the case when RDN attribute of the target object is not included in Keycloak mappers
if (rdnAttrVal == null) {
continue;
}
String oldRdnAttrVal = firstRdn.getAttrValue(attrKey);
if (!oldRdnAttrVal.equalsIgnoreCase(rdnAttrVal)) {
changed = true;
firstRdn.setAttrValue(attrKey, rdnAttrVal);
}
}
// Add new keys
for (String attrKey : toAddKeys) {
String rdnAttrVal = ldapObject.getAttributeAsString(attrKey);
// Could be the case when RDN attribute of the target object is not included in Keycloak mappers
if (rdnAttrVal == null) {
continue;
}
changed = true;
firstRdn.setAttrValue(attrKey, rdnAttrVal);
}
// Remove old keys
for (String attrKey : toRemoveKeys) {
changed |= firstRdn.removeAttrValue(attrKey);
}
if (changed) {
LDAPDn newLdapDn = ldapObject.getDn().getParentDn();
newLdapDn.addFirst(firstRdn);
String newDn = newLdapDn.toString();
logger.debugf("Renaming LDAP Object. Old DN: [%s], New DN: [%s]", oldDn, newDn);
// In case, that there is conflict (For example already existing "CN=John Anthony"), the different DN is returned
newDn = this.operationManager.renameEntry(oldDn, newDn, true);
ldapObject.setDn(LDAPDn.fromString(newDn));
}
}
use of org.keycloak.storage.ldap.idm.model.LDAPDn in project keycloak by keycloak.
the class LDAPOperationManager method findNextDNForFallback.
private String findNextDNForFallback(String newDn, int counter) {
LDAPDn dn = LDAPDn.fromString(newDn);
LDAPDn.RDN firstRdn = dn.getFirstRdn();
String rdnAttrName = firstRdn.getAllKeys().get(0);
String rdnAttrVal = firstRdn.getAttrValue(rdnAttrName);
LDAPDn parentDn = dn.getParentDn();
parentDn.addFirst(rdnAttrName, rdnAttrVal + counter);
return parentDn.toString();
}
use of org.keycloak.storage.ldap.idm.model.LDAPDn in project keycloak by keycloak.
the class LDAPTestUtils method addLdapOU.
public static LDAPObject addLdapOU(LDAPStorageProvider ldapProvider, String name) {
LDAPObject ldapObject = new LDAPObject();
ldapObject.setRdnAttributeName("ou");
ldapObject.setObjectClasses(Collections.singletonList("organizationalUnit"));
ldapObject.setSingleAttribute("ou", name);
LDAPDn dn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
dn.addFirst("ou", name);
ldapObject.setDn(dn);
ldapProvider.getLdapIdentityStore().add(ldapObject);
return ldapObject;
}
use of org.keycloak.storage.ldap.idm.model.LDAPDn in project keycloak by keycloak.
the class LDAPGroupMapperTest method test04_groupReferencingNonExistentMember.
// KEYCLOAK-2682
@Test
public void test04_groupReferencingNonExistentMember() {
testingClient.server().run(session -> {
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 as it's not allowed to have LDAP group referencing nonexistent member. KEYCLOAK-2682 was related to OpenLDAP TODO: Better solution than programmatic...
LDAPConfig config = ctx.getLdapProvider().getLdapIdentityStore().getConfig();
if (config.isActiveDirectory()) {
return;
}
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ctx.getLdapProvider());
// 1 - Add some group to LDAP for testing
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ctx.getLdapModel());
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ldapProvider, appRealm);
LDAPObject group2 = LDAPTestUtils.createLDAPGroup(session, appRealm, ctx.getLdapModel(), "group2", descriptionAttrName, "group2 - description");
// 2 - Add one existing user rob to LDAP group
LDAPObject jamesLdap = ldapProvider.loadLDAPUserByUsername(appRealm, "jameskeycloak");
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, jamesLdap);
// 3 - Add non-existing user to LDAP group
LDAPDn nonExistentDn = LDAPDn.fromString(ldapProvider.getLdapIdentityStore().getConfig().getUsersDn());
nonExistentDn.addFirst(jamesLdap.getRdnAttributeNames().get(0), "nonexistent");
LDAPObject nonExistentLdapUser = new LDAPObject();
nonExistentLdapUser.setDn(nonExistentDn);
LDAPUtils.addMember(ldapProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, nonExistentLdapUser);
// 4 - Check group members. Just existing user rob should be present
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
List<UserModel> groupUsers = session.users().getGroupMembersStream(appRealm, kcGroup2, 0, 5).collect(Collectors.toList());
Assert.assertEquals(1, groupUsers.size());
UserModel rob = groupUsers.get(0);
Assert.assertEquals("jameskeycloak", rob.getUsername());
});
}
Aggregations