From 88adc79242de80e4095358ce55447a3cebf9e22a Mon Sep 17 00:00:00 2001 From: Jeff Burke <Jeff.Burke@nrc-cnrc.gc.ca> Date: Thu, 18 Sep 2014 14:24:05 -0700 Subject: [PATCH] s1651: DAO updates for adminGroups tree --- .../nrc/cadc/ac/server/ldap/LdapGroupDAO.java | 597 +++++++++++------- 1 file changed, 372 insertions(+), 225 deletions(-) diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java index 2b376898..f83bf5d6 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java @@ -102,7 +102,7 @@ import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchResultEntry; import com.unboundid.ldap.sdk.SearchScope; import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; -import java.util.logging.Level; +import java.util.Set; public class LdapGroupDAO<T extends Principal> extends LdapDAO { @@ -171,21 +171,27 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO "Support for groups properties not available"); } - Group inactiveGroup = getInactiveGroup(group.getID()); + Group inactiveGroup = getInactiveGroup(group); if (inactiveGroup != null) { return reactiveGroup(group, inactiveGroup); } DN ownerDN = userPersist.getUserDN(group.getOwner()); - Attribute ownerAttribute = - new Attribute("owner", ownerDN.toNormalizedString()); // add group to groups tree - LDAPResult result = addGroup(group, ownerAttribute); + LDAPResult result = addGroup(getGroupDN(group.getID()), + group.getID(), ownerDN, + group.description, + group.getUserMembers(), + group.getGroupMembers()); // add group to admin groups tree - result = addAdminGroup(group, ownerAttribute); + result = addGroup(getAdminGroupDN(group.getID()), + group.getID(), ownerDN, + group.description, + group.getUserMembers(), + group.getGroupMembers()); try { @@ -203,6 +209,152 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } } + + private LDAPResult addGroup(final DN groupDN, final String groupID, + final DN ownerDN, final String description, + final Set<User<? extends Principal>> users, + final Set<Group> groups) + throws UserNotFoundException, LDAPException + { + // add new group + List<Attribute> attributes = new ArrayList<Attribute>(); + Attribute ownerAttribute = + new Attribute("owner", ownerDN.toNormalizedString()); + attributes.add(ownerAttribute); + attributes.add(new Attribute("objectClass", "groupofuniquenames")); + attributes.add(new Attribute("cn", groupID)); + + if (description != null) + { + attributes.add(new Attribute("description", description)); + } + + List<String> members = new ArrayList<String>(); + for (User<? extends Principal> userMember : users) + { + DN memberDN = this.userPersist.getUserDN(userMember); + members.add(memberDN.toNormalizedString()); + } + for (Group groupMember : groups) + { + DN memberDN = getGroupDN(groupMember.getID()); + members.add(memberDN.toNormalizedString()); + } + if (!members.isEmpty()) + { + attributes.add(new Attribute("uniquemember", + (String[]) members.toArray(new String[members.size()]))); + } + + AddRequest addRequest = new AddRequest(groupDN, attributes); + + addRequest.addControl( + new ProxiedAuthorizationV2RequestControl( + "dn:" + getSubjectDN().toNormalizedString())); + + return getConnection().add(addRequest); + } + + private Group getInactiveGroup(final Group group) + throws AccessControlException, UserNotFoundException, LDAPException + { + Group inactiveGroup = + getInactiveGroup(getGroupDN(group.getID()).toNormalizedString(), + group.getID()); + + if (inactiveGroup == null) + { + return null; + } + + if (!group.getOwner().equals(inactiveGroup.getOwner())) + { + throw new AccessControlException( + "Inactive group not owned be requestor"); + } + + Group inactiveAdminGroup = getInactiveGroup( + getAdminGroupDN(group.getID()).toNormalizedString(), + group.getID()); + + if (inactiveAdminGroup == null) + { + throw new RuntimeException("BUG: adminGroup not found for group " + + group.getID()); + } + + if (!group.getOwner().equals(inactiveAdminGroup.getOwner())) + { + throw new RuntimeException("Bug: adminGroup owner doesn't match " + + "group owner for group " + + group.getID()); + } + + return inactiveGroup; + } + + private Group getInactiveGroup(final String groupDN, final String groupID) + throws UserNotFoundException, LDAPException + { + Filter filter = Filter.createANDFilter( + Filter.createEqualityFilter("cn", groupID), + Filter.createEqualityFilter("nsaccountlock", "true")); + + SearchRequest searchRequest = + new SearchRequest(groupDN, SearchScope.SUB, filter, + new String[] {"cn", "owner"}); + + searchRequest.addControl( + new ProxiedAuthorizationV2RequestControl("dn:" + + getSubjectDN().toNormalizedString())); + + SearchResultEntry searchResult = + getConnection().searchForEntry(searchRequest); + + if (searchResult == null) + { + String msg = "Inactive Group not found " + groupID; + logger.debug(msg); + return null; + } + + String groupCN = searchResult.getAttributeValue("cn"); + DN groupOwner = searchResult.getAttributeValueAsDN("owner"); + + User<X500Principal> owner = userPersist.getMember(groupOwner); + + return new Group(groupCN, owner); + } + + private Group reactiveGroup(final Group newGroup, final Group inactiveGroup) + throws UserNotFoundException, LDAPException, TransientException + { + Group group = reactiveGroup(getGroupDN(newGroup.getID()), newGroup, + inactiveGroup); + Group adminGroup = reactiveGroup(getGroupDN(newGroup.getID()), newGroup, + inactiveGroup); + return group; + } + + private Group reactiveGroup(final DN groupDN, final Group newGroup, + final Group inactiveGroup) + throws UserNotFoundException, LDAPException, TransientException + { + List<Modification> mods = new ArrayList<Modification>(); + mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); + + Group modifiedGroup = modifyGroup(groupDN, newGroup, inactiveGroup, + mods); + Group activatedGroup = new ActivatedGroup(modifiedGroup.getID(), + modifiedGroup.getOwner()); + activatedGroup.description = modifiedGroup.description; + activatedGroup.getProperties().addAll(modifiedGroup.getProperties()); + activatedGroup.getGroupMembers().addAll(modifiedGroup.getGroupMembers()); + activatedGroup.getUserMembers().addAll(modifiedGroup.getUserMembers()); + activatedGroup.getGroupAdmins().addAll(modifiedGroup.getGroupAdmins()); + activatedGroup.getUserAdmins().addAll(modifiedGroup.getUserAdmins()); + return activatedGroup; + } /** * Get the group with the given Group ID. @@ -214,14 +366,50 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. */ - public Group getGroup(String groupID) + public Group getGroup(final String groupID) throws GroupNotFoundException, TransientException, AccessControlException { return getGroup(groupID, true); } + + public Group getGroup(final String groupID, final boolean withMembers) + throws GroupNotFoundException, TransientException, + AccessControlException + { + Group group = getGroup(getGroupDN(groupID), groupID, true); + + Group adminGroup = getAdminGroup(getAdminGroupDN(groupID), groupID, + true); + + group.getGroupAdmins().addAll(adminGroup.getGroupMembers()); + group.getUserAdmins().addAll(adminGroup.getUserMembers()); + return group; + } + + private Group getGroup(final DN groupDN, final String groupID, + final boolean withMembers) + throws GroupNotFoundException, TransientException, + AccessControlException + { + String [] attributes = new String[] {"entrydn", "cn", "description", + "owner", "uniquemember", + "modifytimestamp"}; + return getGroup(groupDN, groupID, withMembers, attributes); + } + + private Group getAdminGroup(final DN groupDN, final String groupID, + final boolean withMembers) + throws GroupNotFoundException, TransientException, + AccessControlException + { + String [] attributes = new String[] {"entrydn", "cn", "owner", + "uniquemember"}; + return getGroup(groupDN, groupID, withMembers, attributes); + } - private Group getGroup(String groupID, boolean withMembers) + private Group getGroup(final DN groupDN, final String groupID, + final boolean withMembers, String[] attributes) throws GroupNotFoundException, TransientException, AccessControlException { @@ -232,28 +420,26 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO Filter.createNOTFilter( Filter.createEqualityFilter("nsaccountlock", "TRUE"))); - SearchRequest searchRequest = new SearchRequest( - config.getGroupsDN(), SearchScope.SUB, - filter, new String[] {"entrydn", "cn", "description", - "owner", "uniquemember", - "modifytimestamp"}); + SearchRequest searchRequest = + new SearchRequest(groupDN.toNormalizedString(), + SearchScope.SUB, filter, attributes); searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); - SearchResultEntry group = + SearchResultEntry searchResult = getConnection().searchForEntry(searchRequest); - if (group == null) + + if (searchResult == null) { String msg = "Group not found " + groupID; logger.debug(msg); throw new GroupNotFoundException(groupID); } - String groupCN = group.getAttributeValue("cn"); - DN groupOwner = group.getAttributeValueAsDN("owner"); - Date lastModified = - group.getAttributeValueAsDate("modifytimestamp"); + + String groupCN = searchResult.getAttributeValue("cn"); + DN groupOwner = searchResult.getAttributeValueAsDN("owner"); User<X500Principal> owner; try @@ -266,14 +452,22 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } Group ldapGroup = new Group(groupCN, owner); - ldapGroup.description = group.getAttributeValue("description"); - ldapGroup.lastModified = lastModified; + if (searchResult.hasAttribute("description")) + { + ldapGroup.description = + searchResult.getAttributeValue("description"); + } + if (searchResult.hasAttribute("modifytimestamp")) + { + ldapGroup.lastModified = + searchResult.getAttributeValueAsDate("modifytimestamp"); + } if (withMembers) { - if (group.getAttributeValues("uniquemember") != null) + if (searchResult.getAttributeValues("uniquemember") != null) { - for (String member : group + for (String member : searchResult .getAttributeValues("uniquemember")) { DN memberDN = new DN(member); @@ -332,14 +526,24 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throws GroupNotFoundException, TransientException, AccessControlException, UserNotFoundException { - // check if group exists - Group oldGroup = getGroup(group.getID()); + DN groupDN = getGroupDN(group.getID()); + Group oldGroup = getGroup(groupDN, group.getID(), true); + Group newGroup = modifyGroup(groupDN, group, oldGroup, null); + + DN adminGroupDN = getAdminGroupDN(group.getID()); + Group oldAdminGroup = getGroup(adminGroupDN, group.getID(), true); + Group newAdminGroup = modifyGroup(adminGroupDN, group, oldAdminGroup, + null); - return modifyGroup(group, oldGroup, null); + newGroup.getGroupAdmins().addAll(newAdminGroup.getGroupAdmins()); + newGroup.getUserAdmins().addAll(newAdminGroup.getUserAdmins()); + + return newGroup; } - private Group modifyGroup(Group newGroup, Group oldGroup, - List<Modification> modifications) + private Group modifyGroup(final DN groupDN, final Group newGroup, + final Group oldGroup, + final List<Modification> modifications) throws UserNotFoundException, TransientException, AccessControlException { @@ -349,25 +553,24 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO "Support for groups properties not available"); } - List<Modification> modifs = new ArrayList<Modification>(); + List<Modification> mods = new ArrayList<Modification>(); if (modifications != null) { - modifs.addAll(modifications); + mods.addAll(modifications); } if (newGroup.description == null && oldGroup.description != null) { - modifs.add(new Modification(ModificationType.DELETE, - "description")); + mods.add(new Modification(ModificationType.DELETE, "description")); } else if (newGroup.description != null && oldGroup.description == null) { - modifs.add(new Modification(ModificationType.ADD, "description", + mods.add(new Modification(ModificationType.ADD, "description", newGroup.description)); } else if (newGroup.description != null && oldGroup.description != null) { - modifs.add(new Modification(ModificationType.REPLACE, "description", + mods.add(new Modification(ModificationType.REPLACE, "description", newGroup.description)); } @@ -403,9 +606,41 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO newMembers.add(grDN.toNormalizedString()); } } + for (User<?> member : newGroup.getUserAdmins()) + { + if (!oldGroup.getUserAdmins().remove(member)) + { + DN memberDN; + try + { + memberDN = userPersist.getUserDN(member); + } + catch (LDAPException e) + { + throw new UserNotFoundException( + "User not found " + member.getUserID()); + } + newMembers.add(memberDN.toNormalizedString()); + } + } + for (Group gr : newGroup.getGroupAdmins()) + { + if (gr.equals(newGroup)) + { + throw new IllegalArgumentException( + "cyclical reference from group member to group"); + } + + if (!oldGroup.getGroupAdmins().remove(gr)) + { + DN grDN = getGroupDN(gr.getID()); + newMembers.add(grDN.toNormalizedString()); + } + } + if (!newMembers.isEmpty()) { - modifs.add(new Modification(ModificationType.ADD, "uniquemember", + mods.add(new Modification(ModificationType.ADD, "uniquemember", (String[]) newMembers.toArray(new String[newMembers.size()]))); } @@ -429,14 +664,33 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO DN grDN = getGroupDN(gr.getID()); delMembers.add(grDN.toNormalizedString()); } + for (User<?> member : oldGroup.getUserAdmins()) + { + DN memberDN; + try + { + memberDN = this.userPersist.getUserDN(member); + } + catch (LDAPException e) + { + throw new UserNotFoundException( + "User not found " + member.getUserID()); + } + delMembers.add(memberDN.toNormalizedString()); + } + for (Group gr : oldGroup.getGroupAdmins()) + { + DN grDN = getGroupDN(gr.getID()); + delMembers.add(grDN.toNormalizedString()); + } + if (!delMembers.isEmpty()) { - modifs.add(new Modification(ModificationType.DELETE, "uniquemember", + mods.add(new Modification(ModificationType.DELETE, "uniquemember", (String[]) delMembers.toArray(new String[delMembers.size()]))); } - ModifyRequest modifyRequest = - new ModifyRequest(getGroupDN(newGroup.getID()), modifs); + ModifyRequest modifyRequest = new ModifyRequest(groupDN, mods); try { modifyRequest.addControl( @@ -470,7 +724,16 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throws GroupNotFoundException, TransientException, AccessControlException { - Group group = getGroup(groupID); + deleteGroup(getGroupDN(groupID), groupID, false); + deleteGroup(getAdminGroupDN(groupID), groupID, true); + } + + private void deleteGroup(final DN groupDN, final String groupID, + final boolean isAdmin) + throws GroupNotFoundException, TransientException, + AccessControlException + { + Group group = getGroup(groupDN, groupID, false); List<Modification> modifs = new ArrayList<Modification>(); modifs.add(new Modification(ModificationType.ADD, "nsaccountlock", "true")); @@ -479,14 +742,29 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO modifs.add(new Modification(ModificationType.DELETE, "description")); } - if (!group.getGroupMembers().isEmpty() || - !group.getUserMembers().isEmpty()) + if (group.lastModified != null) + { + modifs.add(new Modification(ModificationType.DELETE, "lastModified")); + } + + if (isAdmin) { - modifs.add(new Modification(ModificationType.DELETE, "uniquemember")); + if (!group.getGroupAdmins().isEmpty() || + !group.getUserAdmins().isEmpty()) + { + modifs.add(new Modification(ModificationType.DELETE, "uniquemember")); + } + } + else + { + if (!group.getGroupMembers().isEmpty() || + !group.getUserMembers().isEmpty()) + { + modifs.add(new Modification(ModificationType.DELETE, "uniquemember")); + } } - ModifyRequest modifyRequest = - new ModifyRequest(getGroupDN(group.getID()), modifs); + ModifyRequest modifyRequest = new ModifyRequest(groupDN, modifs); try { modifyRequest.addControl( @@ -551,7 +829,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } else if (role == Role.RW) { - return getRWGroups(user, userDN, groupID); + return getAdminGroups(user, userDN, groupID); } throw new IllegalArgumentException("Unknown role " + role); } @@ -618,17 +896,45 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO Collection<Group> groups = new ArrayList<Group>(); if (userPersist.isMember(user.getUserID(), groupID)) { - groups.add(getGroup(groupID)); + groups.add(getGroup(groupID, false)); } return groups; } else { - return userPersist.getUserGroups(user.getUserID()); + try + { + Collection<Group> groups = + userPersist.getUserGroups(user.getUserID()); + + List<Filter> filters = new ArrayList<Filter>(); + for (Group group : groups) + { + filters.add(Filter.createEqualityFilter("cn", + group.getID())); + } + + Filter filter = Filter.createORFilter(filters); + SearchRequest searchRequest = new SearchRequest( + config.getAdminGroupsDN(), SearchScope.SUB, filter, + "cn"); + + SearchResult results = getConnection().search(searchRequest); + for (SearchResultEntry result : results.getSearchEntries()) + { + String groupName = result.getAttributeValue("cn"); + + } + return groups; + } + catch (LDAPException e) + { + throw new TransientException(e.getDiagnosticMessage()); + } } } - protected Collection<Group> getRWGroups(User<T> user, DN userDN, + protected Collection<Group> getAdminGroups(User<T> user, DN userDN, String groupID) throws TransientException, AccessControlException, GroupNotFoundException, UserNotFoundException @@ -800,165 +1106,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO // throw new TransientException("Error getting groups", e); // } // } - - protected Group getInactiveGroup(final String groupID) - throws UserNotFoundException, LDAPException - { - Filter filter = Filter.createANDFilter( - Filter.createEqualityFilter("cn", groupID), - Filter.createEqualityFilter("nsaccountlock", "true")); - - SearchRequest searchRequest = new SearchRequest( - config.getGroupsDN(), SearchScope.SUB, - filter, new String[] {"cn", "owner"}); - - searchRequest.addControl( - new ProxiedAuthorizationV2RequestControl("dn:" + - getSubjectDN().toNormalizedString())); - - SearchResultEntry searchResult = - getConnection().searchForEntry(searchRequest); - - if (searchResult == null) - { - String msg = "Inactive Group not found " + groupID; - logger.debug(msg); - return null; - } - - String groupCN = searchResult.getAttributeValue("cn"); - DN groupOwner = searchResult.getAttributeValueAsDN("owner"); - - User<X500Principal> owner = userPersist.getMember(groupOwner); - - return new Group(groupCN, owner); - } - - protected Group reactiveGroup(final Group newGroup, - final Group inactiveGroup) - throws UserNotFoundException, LDAPException, TransientException - { - // Check requestor owns the group. - DN ownerDN = userPersist.getUserDN(newGroup.getOwner()); - if (!ownerDN.equals(getSubjectDN())) - { - throw new AccessControlException( - "Unable to activate group " + newGroup.getID() + - " because " + getSubjectDN().toString() - + " is not the owner"); - } - - List<Modification> mods = new ArrayList<Modification>(); - mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); - - Group modifiedGroup = modifyGroup(newGroup, inactiveGroup, mods); - Group activatedGroup = - new ActivatedGroup(modifiedGroup.getID(), - modifiedGroup.getOwner()); - activatedGroup.description = modifiedGroup.description; - activatedGroup.getProperties() - .addAll(modifiedGroup.getProperties()); - activatedGroup.getGroupMembers() - .addAll(modifiedGroup.getGroupMembers()); - activatedGroup.getUserMembers() - .addAll(modifiedGroup.getUserMembers()); - return activatedGroup; - } - - /** - * - * @param group - * @param ownerAttribute - * @return - * @throws UserNotFoundException - * @throws LDAPException - */ - protected LDAPResult addGroup(final Group group, - final Attribute ownerAttribute) - throws UserNotFoundException, LDAPException - { - // add new group - List<Attribute> attributes = new ArrayList<Attribute>(); - attributes.add(ownerAttribute); - attributes.add(new Attribute("objectClass", "groupofuniquenames")); - attributes.add(new Attribute("cn", group.getID())); - - if (group.description != null) - { - attributes.add(new Attribute("description", group.description)); - } - - List<String> members = new ArrayList<String>(); - for (User<?> member : group.getUserMembers()) - { - DN memberDN = this.userPersist.getUserDN(member); - members.add(memberDN.toNormalizedString()); - } - for (Group gr : group.getGroupMembers()) - { - DN grDN = getGroupDN(gr.getID()); - members.add(grDN.toNormalizedString()); - } - if (!members.isEmpty()) - { - attributes.add(new Attribute("uniquemember", - (String[]) members.toArray(new String[members.size()]))); - } - - AddRequest addRequest = - new AddRequest(getGroupDN(group.getID()), attributes); - - addRequest.addControl( - new ProxiedAuthorizationV2RequestControl( - "dn:" + getSubjectDN().toNormalizedString())); - - return getConnection().add(addRequest); - } - - /** - * - * @param group - * @param ownerAttribute - * @return - * @throws UserNotFoundException - * @throws LDAPException - */ - protected LDAPResult addAdminGroup(final Group group, - final Attribute ownerAttribute) - throws UserNotFoundException, LDAPException - { - // add new group - List<Attribute> attributes = new ArrayList<Attribute>(); - attributes.add(ownerAttribute); - attributes.add(new Attribute("objectClass", "groupofuniquenames")); - attributes.add(new Attribute("cn", group.getID())); - - List<String> admins = new ArrayList<String>(); - for (User<?> user : group.getUserAdmins()) - { - DN userDN = this.userPersist.getUserDN(user); - admins.add(userDN.toNormalizedString()); - } - for (Group gr : group.getGroupAdmins()) - { - DN grDN = getGroupDN(gr.getID()); - admins.add(grDN.toNormalizedString()); - } - if (!admins.isEmpty()) - { - attributes.add(new Attribute("uniquemember", - (String[]) admins.toArray(new String[admins.size()]))); - } - - AddRequest addRequest = - new AddRequest(getAdminGroupDN(group.getID()), attributes); - - addRequest.addControl( - new ProxiedAuthorizationV2RequestControl( - "dn:" + getSubjectDN().toNormalizedString())); - - return getConnection().add(addRequest); - } /** * Returns a group based on its LDAP DN. The returned group is bare @@ -970,24 +1117,24 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @throws ca.nrc.cadc.ac.GroupNotFoundException * @throws ca.nrc.cadc.ac.UserNotFoundException */ - protected Group getGroup(DN groupDN) - throws LDAPException, GroupNotFoundException, UserNotFoundException - { - SearchResultEntry searchResult = - getConnection().getEntry(groupDN.toNormalizedString(), - new String[] {"cn", "description"}); - - if (searchResult == null) - { - String msg = "Group not found " + groupDN; - logger.debug(msg); - throw new GroupNotFoundException(groupDN.toNormalizedString()); - } - - Group group = new Group(searchResult.getAttributeValue("cn")); - group.description = searchResult.getAttributeValue("description"); - return group; - } +// protected Group getGroup(DN groupDN) +// throws LDAPException, GroupNotFoundException, UserNotFoundException +// { +// SearchResultEntry searchResult = +// getConnection().getEntry(groupDN.toNormalizedString(), +// new String[] {"cn", "description"}); +// +// if (searchResult == null) +// { +// String msg = "Group not found " + groupDN; +// logger.debug(msg); +// throw new GroupNotFoundException(groupDN.toNormalizedString()); +// } +// +// Group group = new Group(searchResult.getAttributeValue("cn")); +// group.description = searchResult.getAttributeValue("description"); +// return group; +// } /** * -- GitLab