Loading projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +191 −122 Original line number Diff line number Diff line Loading @@ -123,11 +123,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO }; private static final String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" }; private static final String[] GROUP_AND_MEMBER_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" }; private Profiler profiler = new Profiler(LdapDAO.class); Loading @@ -152,9 +154,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Persists a group. * * @param group The group to create * * @return created group * * @throws GroupAlreadyExistsException If a group with the same ID already * exists. * @throws TransientException If an temporary, unexpected problem occurred. Loading Loading @@ -263,7 +263,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (!members.isEmpty()) { attributes.add(new Attribute("uniquemember", (String[]) members.toArray(new String[members.size()]))); (String[]) members .toArray(new String[members .size()]))); } AddRequest addRequest = new AddRequest(groupDN, attributes); Loading @@ -278,6 +280,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO /** * Checks whether group name available for the user or already in use. * * @param group * @return activated group or null if group does not exists * @throws AccessControlException Loading @@ -302,9 +305,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResultEntry searchResult = getReadWriteConnection().searchForEntry(searchRequest); SearchResultEntry searchResult = getReadWriteConnection() .searchForEntry(searchRequest); if (searchResult == null) { Loading @@ -313,7 +318,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (searchResult.getAttributeValue("nsaccountlock") == null) { throw new GroupAlreadyExistsException("Group already exists " + group.getID()); throw new GroupAlreadyExistsException("Group already exists " + group .getID()); } // activate group Loading Loading @@ -341,7 +347,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Get all group names. * * @return A collection of strings * * @throws TransientException If an temporary, unexpected problem occurred. */ public Collection<String> getGroupNames() Loading @@ -349,7 +354,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.create("(cn=*)")); final List<String> groupNames = new LinkedList<String>(); Loading @@ -373,7 +379,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if ((groupNames.size() % 100) == 0) { logger.debug("found: " + groupNames.size() + " " + dt + "ms"); logger.debug("found: " + groupNames .size() + " " + dt + "ms"); t1 = t2; } } Loading @@ -382,7 +389,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }, config.getGroupsDN(), SearchScope.ONE, filter, PUB_GROUP_ATTRS); }, config .getGroupsDN(), SearchScope.ONE, filter, PUB_GROUP_ATTRS); SearchResult searchResult = null; try Loading Loading @@ -413,7 +421,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { logger.debug("getGroupNames Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); throw new IllegalStateException("Unexpected exception: " + e1.getMatchedDN(), e1); throw new IllegalStateException("Unexpected exception: " + e1 .getMatchedDN(), e1); } } Loading @@ -422,9 +431,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Get the group with members. * * @param groupID The Group unique ID. * * @return A Group instance * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. */ Loading @@ -450,11 +457,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getGroup: " + groupDN + " attrs: " + attributes.length); String loggableGroupID = xgroupID; if (loggableGroupID == null) loggableGroupID = groupDN.toString(); // member or admin group: same name, internal tree { loggableGroupID = groupDN .toString(); // member or admin group: same name, internal tree } try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), Loading @@ -462,10 +473,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResultEntry searchEntry = getReadOnlyConnection().searchForEntry(searchRequest); SearchResultEntry searchEntry = getReadOnlyConnection() .searchForEntry(searchRequest); if (searchEntry == null) { Loading @@ -478,7 +491,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (searchEntry.getAttributeValues("uniquemember") != null) { for (String member : searchEntry.getAttributeValues("uniquemember")) for (String member : searchEntry .getAttributeValues("uniquemember")) { DN memberDN = new DN(member); if (memberDN.isDescendantOf(config.getUsersDN(), false)) Loading @@ -495,11 +509,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO // from groups they belong to } } else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) else if (memberDN .isDescendantOf(config.getGroupsDN(), false)) { try { ldapGroup.getGroupMembers().add(getGroup(memberDN, null, PUB_GROUP_ATTRS)); ldapGroup.getGroupMembers() .add(getGroup(memberDN, null, PUB_GROUP_ATTRS)); } catch (GroupNotFoundException e) { Loading Loading @@ -529,9 +545,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Modify the given group. * * @param group The group to update. It must be an existing group * * @return The newly updated group. * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. Loading Loading @@ -562,18 +576,21 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (withActivate) { mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods .add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminChanges = true; } if (group.description == null) if (StringUtil.hasText(group.description)) { mods.add(new Modification(ModificationType.REPLACE, "description")); mods.add(new Modification(ModificationType.REPLACE, "description", group.description)); } else { mods.add(new Modification(ModificationType.REPLACE, "description", group.description)); mods.add(new Modification(ModificationType.REPLACE, "description")); } try { Set<String> newMembers = new HashSet<String>(); Loading @@ -598,6 +615,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { existingUserAdmins = existing.getUserAdmins(); } // All the user administrators may have been removed. // account for that. if (group.getUserAdmins().isEmpty()) { adminChanges = true; } else { for (User<?> member : group.getUserAdmins()) { DN memberDN = userPersist.getUserDN(member); Loading @@ -607,12 +633,22 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO adminChanges = true; } } } Set<Group> existingGroupAdmins = new HashSet<Group>(0); if (existing != null) { existingGroupAdmins = existing.getGroupAdmins(); } // All the group administrators may have been removed. // account for that. if (group.getGroupAdmins().isEmpty()) { adminChanges = true; } else { for (Group gr : group.getGroupAdmins()) { if (!checkGroupExists(gr.getID())) Loading @@ -627,11 +663,17 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO adminChanges = true; } } } mods.add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newMembers.toArray(new String[newMembers.size()]))); adminMods.add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newAdmins.toArray(new String[newAdmins.size()]))); (String[]) newMembers .toArray(new String[newMembers .size()]))); adminMods .add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newAdmins .toArray(new String[newAdmins .size()]))); // modify admin group first (if necessary) if (adminChanges) Loading @@ -642,7 +684,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); LdapDAO.checkLdapResult(getReadWriteConnection().modify(modifyRequest).getResultCode()); LdapDAO.checkLdapResult(getReadWriteConnection() .modify(modifyRequest) .getResultCode()); } // modify the group itself now Loading @@ -652,7 +696,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); LdapDAO.checkLdapResult(getReadWriteConnection().modify(modifyRequest).getResultCode()); LdapDAO.checkLdapResult(getReadWriteConnection() .modify(modifyRequest) .getResultCode()); } catch (LDAPException e1) { Loading @@ -672,7 +718,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (GroupNotFoundException e) { throw new RuntimeException("BUG: modified group not found (" + group.getID() + ")"); throw new RuntimeException("BUG: modified group not found (" + group .getID() + ")"); } } Loading @@ -680,7 +727,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Deletes the group. * * @param groupID The group to delete * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. */ Loading Loading @@ -736,9 +782,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { getGroup(getGroupDN(group.getID()), null, GROUP_ATTRS); throw new RuntimeException("BUG: group not deleted " + group.getID()); throw new RuntimeException("BUG: group not deleted " + group .getID()); } catch (GroupNotFoundException ignore) { } catch (GroupNotFoundException ignore) { } } /** Loading @@ -748,7 +797,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @param userID The userID. * @param role Role of the user, either owner, member, or read/write. * @param groupID The Group ID. * * @return possibly empty collection of Group that match the query * @throws TransientException If an temporary, unexpected problem occurred. * @throws UserNotFoundException Loading Loading @@ -789,7 +837,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO groupDNs = getMemberGroups(user, userDN, groupID, true); } else { throw new IllegalArgumentException("null role"); } ret = new ArrayList<Group>(); try Loading @@ -798,7 +848,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { if (role == Role.ADMIN) { groupDN = new DN(groupDN.getRDNString() + "," + config.getGroupsDN()); groupDN = new DN(groupDN.getRDNString() + "," + config .getGroupsDN()); } try { Loading @@ -825,7 +876,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } logger.debug("found: " + ret.size() + "groups matching " + userID + "," + role + "," + groupID); logger.debug("found: " + ret .size() + "groups matching " + userID + "," + role + "," + groupID); return ret; } Loading @@ -838,14 +890,17 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { return new Group(parts[1]); } throw new RuntimeException("BUG: failed to extract group name from " + groupDN.toString()); throw new RuntimeException("BUG: failed to extract group name from " + groupDN .toString()); } private boolean isDetailedSearch(Group g, Role r) { if (searchDetailSelector == null) { return true; } return searchDetailSelector.isDetailedSearch(g, r); } // end of horribleness Loading @@ -858,16 +913,19 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO Collection<Group> ret = new ArrayList<Group>(); try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); Filter.createEqualityFilter("owner", userDN .toNormalizedString())); if (groupID != null) { DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter("entrydn", groupDN .toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( Loading @@ -875,9 +933,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResult results = getReadOnlyConnection().search(searchRequest); SearchResult results = getReadOnlyConnection() .search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { ret.add(createGroupFromEntry(result, GROUP_ATTRS)); Loading @@ -896,25 +956,35 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { if (result.getAttribute("nsaccountlock") != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue("entrydn").toString()); throw new RuntimeException("BUG: found group with nsaccountlock set: " + result .getAttributeValue("entrydn").toString()); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); if (attributes == PUB_GROUP_ATTRS) { return new Group(groupName); } DN ownerDN = result.getAttributeValueAsDN("owner"); if (ownerDN == null) { throw new AccessControlException(groupName); } try { User owner = userPersist.getX500User(ownerDN); Group g = new Group(groupName, owner); if (result.hasAttribute("description")) { g.description = result.getAttributeValue("description"); } if (result.hasAttribute("modifytimestamp")) g.lastModified = result.getAttributeValueAsDate("modifytimestamp"); { g.lastModified = result .getAttributeValueAsDate("modifytimestamp"); } return g; } catch (UserNotFoundException ex) Loading Loading @@ -958,7 +1028,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param groupID * @return */ Loading @@ -977,7 +1046,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param groupID * @return */ Loading @@ -996,7 +1064,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param owner * @return * @throws UserNotFoundException Loading Loading @@ -1035,7 +1102,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { return false; } finally { } finally { } } } projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +9 −2 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import java.util.Set; import javax.security.auth.x500.X500Principal; import ca.nrc.cadc.auth.DNPrincipal; import ca.nrc.cadc.util.StringUtil; import com.unboundid.ldap.sdk.ModifyDNRequest; import org.apache.log4j.Logger; Loading Loading @@ -662,8 +663,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO next.getAttributeValue(LDAP_LAST_NAME).trim(); final String uid = next.getAttributeValue(LDAP_UID).trim(); User<Principal> user = new User<Principal>(new HttpPrincipal(uid)); PersonalDetails pd = new PersonalDetails(firstName, lastName); user.details.add(pd); // Only add Personal Details if it is relevant. if (StringUtil.hasLength(firstName) && StringUtil.hasLength(lastName)) { user.details.add(new PersonalDetails(firstName, lastName)); } users.add(user); } } Loading projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java +17 −7 Original line number Diff line number Diff line Loading @@ -85,18 +85,28 @@ public class JsonUserListReaderWriterTest for (int i = 0; i < 4; i++) { users.add(new User<HttpPrincipal>( new HttpPrincipal(Integer.toString(i)))); final User<HttpPrincipal> user = new User<HttpPrincipal>( new HttpPrincipal(Integer.toString(i))); user.details.add(new PersonalDetails(Integer.toString(i), "NUMBER_")); if ((i % 2) == 0) { user.details.add(new PosixDetails(88l + i, 88l + i, "/tmp")); } users.add(user); } testSubject.write(users, writer); final JSONObject expected = new JSONObject("{\"users\":{\"user\":[{\"userID\":" + "{\"identity\":{\"$\":\"0\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"1\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"2\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"3\",\"@type\":\"HTTP\"}}}]}}"); new JSONObject("{\"users\":{\"user\":[" + "{\"details\":{\"userDetails\":[{\"firstName\":{\"$\":\"0\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"},{\"uid\":{\"$\":\"88\"},\"gid\":{\"$\":\"88\"},\"homeDirectory\":{\"$\":\"/tmp\"},\"@type\":\"posixDetails\"}]},\"userID\":{\"identity\":{\"$\":\"0\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":{\"firstName\":{\"$\":\"1\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}},\"userID\":{\"identity\":{\"$\":\"1\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":[{\"uid\":{\"$\":\"90\"},\"gid\":{\"$\":\"90\"},\"homeDirectory\":{\"$\":\"/tmp\"},\"@type\":\"posixDetails\"},{\"firstName\":{\"$\":\"2\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}]},\"userID\":{\"identity\":{\"$\":\"2\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":{\"firstName\":{\"$\":\"3\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}},\"userID\":{\"identity\":{\"$\":\"3\",\"@type\":\"HTTP\"}}}]}}"); final JSONObject result = new JSONObject(writer.toString()); JSONAssert.assertEquals(expected, result, true); Loading Loading
projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +191 −122 Original line number Diff line number Diff line Loading @@ -123,11 +123,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO }; private static final String[] GROUP_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description" }; private static final String[] GROUP_AND_MEMBER_ATTRS = new String[] { "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" "entrydn", "cn", "nsaccountlock", "owner", "modifytimestamp", "description", "uniquemember" }; private Profiler profiler = new Profiler(LdapDAO.class); Loading @@ -152,9 +154,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Persists a group. * * @param group The group to create * * @return created group * * @throws GroupAlreadyExistsException If a group with the same ID already * exists. * @throws TransientException If an temporary, unexpected problem occurred. Loading Loading @@ -263,7 +263,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (!members.isEmpty()) { attributes.add(new Attribute("uniquemember", (String[]) members.toArray(new String[members.size()]))); (String[]) members .toArray(new String[members .size()]))); } AddRequest addRequest = new AddRequest(groupDN, attributes); Loading @@ -278,6 +280,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO /** * Checks whether group name available for the user or already in use. * * @param group * @return activated group or null if group does not exists * @throws AccessControlException Loading @@ -302,9 +305,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResultEntry searchResult = getReadWriteConnection().searchForEntry(searchRequest); SearchResultEntry searchResult = getReadWriteConnection() .searchForEntry(searchRequest); if (searchResult == null) { Loading @@ -313,7 +318,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (searchResult.getAttributeValue("nsaccountlock") == null) { throw new GroupAlreadyExistsException("Group already exists " + group.getID()); throw new GroupAlreadyExistsException("Group already exists " + group .getID()); } // activate group Loading Loading @@ -341,7 +347,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Get all group names. * * @return A collection of strings * * @throws TransientException If an temporary, unexpected problem occurred. */ public Collection<String> getGroupNames() Loading @@ -349,7 +354,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.create("(cn=*)")); final List<String> groupNames = new LinkedList<String>(); Loading @@ -373,7 +379,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if ((groupNames.size() % 100) == 0) { logger.debug("found: " + groupNames.size() + " " + dt + "ms"); logger.debug("found: " + groupNames .size() + " " + dt + "ms"); t1 = t2; } } Loading @@ -382,7 +389,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }, config.getGroupsDN(), SearchScope.ONE, filter, PUB_GROUP_ATTRS); }, config .getGroupsDN(), SearchScope.ONE, filter, PUB_GROUP_ATTRS); SearchResult searchResult = null; try Loading Loading @@ -413,7 +421,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { logger.debug("getGroupNames Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); throw new IllegalStateException("Unexpected exception: " + e1.getMatchedDN(), e1); throw new IllegalStateException("Unexpected exception: " + e1 .getMatchedDN(), e1); } } Loading @@ -422,9 +431,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Get the group with members. * * @param groupID The Group unique ID. * * @return A Group instance * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. */ Loading @@ -450,11 +457,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO logger.debug("getGroup: " + groupDN + " attrs: " + attributes.length); String loggableGroupID = xgroupID; if (loggableGroupID == null) loggableGroupID = groupDN.toString(); // member or admin group: same name, internal tree { loggableGroupID = groupDN .toString(); // member or admin group: same name, internal tree } try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); SearchRequest searchRequest = new SearchRequest(groupDN.toNormalizedString(), Loading @@ -462,10 +473,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResultEntry searchEntry = getReadOnlyConnection().searchForEntry(searchRequest); SearchResultEntry searchEntry = getReadOnlyConnection() .searchForEntry(searchRequest); if (searchEntry == null) { Loading @@ -478,7 +491,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (searchEntry.getAttributeValues("uniquemember") != null) { for (String member : searchEntry.getAttributeValues("uniquemember")) for (String member : searchEntry .getAttributeValues("uniquemember")) { DN memberDN = new DN(member); if (memberDN.isDescendantOf(config.getUsersDN(), false)) Loading @@ -495,11 +509,13 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO // from groups they belong to } } else if (memberDN.isDescendantOf(config.getGroupsDN(), false)) else if (memberDN .isDescendantOf(config.getGroupsDN(), false)) { try { ldapGroup.getGroupMembers().add(getGroup(memberDN, null, PUB_GROUP_ATTRS)); ldapGroup.getGroupMembers() .add(getGroup(memberDN, null, PUB_GROUP_ATTRS)); } catch (GroupNotFoundException e) { Loading Loading @@ -529,9 +545,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Modify the given group. * * @param group The group to update. It must be an existing group * * @return The newly updated group. * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. Loading Loading @@ -562,18 +576,21 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO if (withActivate) { mods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods.add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminMods .add(new Modification(ModificationType.DELETE, "nsaccountlock")); adminChanges = true; } if (group.description == null) if (StringUtil.hasText(group.description)) { mods.add(new Modification(ModificationType.REPLACE, "description")); mods.add(new Modification(ModificationType.REPLACE, "description", group.description)); } else { mods.add(new Modification(ModificationType.REPLACE, "description", group.description)); mods.add(new Modification(ModificationType.REPLACE, "description")); } try { Set<String> newMembers = new HashSet<String>(); Loading @@ -598,6 +615,15 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { existingUserAdmins = existing.getUserAdmins(); } // All the user administrators may have been removed. // account for that. if (group.getUserAdmins().isEmpty()) { adminChanges = true; } else { for (User<?> member : group.getUserAdmins()) { DN memberDN = userPersist.getUserDN(member); Loading @@ -607,12 +633,22 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO adminChanges = true; } } } Set<Group> existingGroupAdmins = new HashSet<Group>(0); if (existing != null) { existingGroupAdmins = existing.getGroupAdmins(); } // All the group administrators may have been removed. // account for that. if (group.getGroupAdmins().isEmpty()) { adminChanges = true; } else { for (Group gr : group.getGroupAdmins()) { if (!checkGroupExists(gr.getID())) Loading @@ -627,11 +663,17 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO adminChanges = true; } } } mods.add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newMembers.toArray(new String[newMembers.size()]))); adminMods.add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newAdmins.toArray(new String[newAdmins.size()]))); (String[]) newMembers .toArray(new String[newMembers .size()]))); adminMods .add(new Modification(ModificationType.REPLACE, "uniquemember", (String[]) newAdmins .toArray(new String[newAdmins .size()]))); // modify admin group first (if necessary) if (adminChanges) Loading @@ -642,7 +684,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); LdapDAO.checkLdapResult(getReadWriteConnection().modify(modifyRequest).getResultCode()); LdapDAO.checkLdapResult(getReadWriteConnection() .modify(modifyRequest) .getResultCode()); } // modify the group itself now Loading @@ -652,7 +696,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO new ProxiedAuthorizationV2RequestControl( "dn:" + getSubjectDN().toNormalizedString())); LdapDAO.checkLdapResult(getReadWriteConnection().modify(modifyRequest).getResultCode()); LdapDAO.checkLdapResult(getReadWriteConnection() .modify(modifyRequest) .getResultCode()); } catch (LDAPException e1) { Loading @@ -672,7 +718,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } catch (GroupNotFoundException e) { throw new RuntimeException("BUG: modified group not found (" + group.getID() + ")"); throw new RuntimeException("BUG: modified group not found (" + group .getID() + ")"); } } Loading @@ -680,7 +727,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * Deletes the group. * * @param groupID The group to delete * * @throws GroupNotFoundException If the group was not found. * @throws TransientException If an temporary, unexpected problem occurred. */ Loading Loading @@ -736,9 +782,12 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO try { getGroup(getGroupDN(group.getID()), null, GROUP_ATTRS); throw new RuntimeException("BUG: group not deleted " + group.getID()); throw new RuntimeException("BUG: group not deleted " + group .getID()); } catch (GroupNotFoundException ignore) { } catch (GroupNotFoundException ignore) { } } /** Loading @@ -748,7 +797,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO * @param userID The userID. * @param role Role of the user, either owner, member, or read/write. * @param groupID The Group ID. * * @return possibly empty collection of Group that match the query * @throws TransientException If an temporary, unexpected problem occurred. * @throws UserNotFoundException Loading Loading @@ -789,7 +837,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO groupDNs = getMemberGroups(user, userDN, groupID, true); } else { throw new IllegalArgumentException("null role"); } ret = new ArrayList<Group>(); try Loading @@ -798,7 +848,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { if (role == Role.ADMIN) { groupDN = new DN(groupDN.getRDNString() + "," + config.getGroupsDN()); groupDN = new DN(groupDN.getRDNString() + "," + config .getGroupsDN()); } try { Loading @@ -825,7 +876,8 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } } logger.debug("found: " + ret.size() + "groups matching " + userID + "," + role + "," + groupID); logger.debug("found: " + ret .size() + "groups matching " + userID + "," + role + "," + groupID); return ret; } Loading @@ -838,14 +890,17 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { return new Group(parts[1]); } throw new RuntimeException("BUG: failed to extract group name from " + groupDN.toString()); throw new RuntimeException("BUG: failed to extract group name from " + groupDN .toString()); } private boolean isDetailedSearch(Group g, Role r) { if (searchDetailSelector == null) { return true; } return searchDetailSelector.isDetailedSearch(g, r); } // end of horribleness Loading @@ -858,16 +913,19 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO Collection<Group> ret = new ArrayList<Group>(); try { Filter filter = Filter.createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); Filter filter = Filter .createNOTFilter(Filter.createPresenceFilter("nsaccountlock")); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("owner", userDN.toNormalizedString())); Filter.createEqualityFilter("owner", userDN .toNormalizedString())); if (groupID != null) { DN groupDN = getGroupDN(groupID); filter = Filter.createANDFilter(filter, Filter.createEqualityFilter("entrydn", groupDN.toNormalizedString())); Filter.createEqualityFilter("entrydn", groupDN .toNormalizedString())); } SearchRequest searchRequest = new SearchRequest( Loading @@ -875,9 +933,11 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO searchRequest.addControl( new ProxiedAuthorizationV2RequestControl("dn:" + getSubjectDN().toNormalizedString())); getSubjectDN() .toNormalizedString())); SearchResult results = getReadOnlyConnection().search(searchRequest); SearchResult results = getReadOnlyConnection() .search(searchRequest); for (SearchResultEntry result : results.getSearchEntries()) { ret.add(createGroupFromEntry(result, GROUP_ATTRS)); Loading @@ -896,25 +956,35 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { if (result.getAttribute("nsaccountlock") != null) { throw new RuntimeException("BUG: found group with nsaccountlock set: " + result.getAttributeValue("entrydn").toString()); throw new RuntimeException("BUG: found group with nsaccountlock set: " + result .getAttributeValue("entrydn").toString()); } String entryDN = result.getAttributeValue("entrydn"); String groupName = result.getAttributeValue("cn"); if (attributes == PUB_GROUP_ATTRS) { return new Group(groupName); } DN ownerDN = result.getAttributeValueAsDN("owner"); if (ownerDN == null) { throw new AccessControlException(groupName); } try { User owner = userPersist.getX500User(ownerDN); Group g = new Group(groupName, owner); if (result.hasAttribute("description")) { g.description = result.getAttributeValue("description"); } if (result.hasAttribute("modifytimestamp")) g.lastModified = result.getAttributeValueAsDate("modifytimestamp"); { g.lastModified = result .getAttributeValueAsDate("modifytimestamp"); } return g; } catch (UserNotFoundException ex) Loading Loading @@ -958,7 +1028,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param groupID * @return */ Loading @@ -977,7 +1046,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param groupID * @return */ Loading @@ -996,7 +1064,6 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO } /** * * @param owner * @return * @throws UserNotFoundException Loading Loading @@ -1035,7 +1102,9 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO { return false; } finally { } finally { } } }
projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +9 −2 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ import java.util.Set; import javax.security.auth.x500.X500Principal; import ca.nrc.cadc.auth.DNPrincipal; import ca.nrc.cadc.util.StringUtil; import com.unboundid.ldap.sdk.ModifyDNRequest; import org.apache.log4j.Logger; Loading Loading @@ -662,8 +663,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO next.getAttributeValue(LDAP_LAST_NAME).trim(); final String uid = next.getAttributeValue(LDAP_UID).trim(); User<Principal> user = new User<Principal>(new HttpPrincipal(uid)); PersonalDetails pd = new PersonalDetails(firstName, lastName); user.details.add(pd); // Only add Personal Details if it is relevant. if (StringUtil.hasLength(firstName) && StringUtil.hasLength(lastName)) { user.details.add(new PersonalDetails(firstName, lastName)); } users.add(user); } } Loading
projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/json/JsonUserListReaderWriterTest.java +17 −7 Original line number Diff line number Diff line Loading @@ -85,18 +85,28 @@ public class JsonUserListReaderWriterTest for (int i = 0; i < 4; i++) { users.add(new User<HttpPrincipal>( new HttpPrincipal(Integer.toString(i)))); final User<HttpPrincipal> user = new User<HttpPrincipal>( new HttpPrincipal(Integer.toString(i))); user.details.add(new PersonalDetails(Integer.toString(i), "NUMBER_")); if ((i % 2) == 0) { user.details.add(new PosixDetails(88l + i, 88l + i, "/tmp")); } users.add(user); } testSubject.write(users, writer); final JSONObject expected = new JSONObject("{\"users\":{\"user\":[{\"userID\":" + "{\"identity\":{\"$\":\"0\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"1\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"2\",\"@type\":\"HTTP\"}}}," + "{\"userID\":{\"identity\":{\"$\":\"3\",\"@type\":\"HTTP\"}}}]}}"); new JSONObject("{\"users\":{\"user\":[" + "{\"details\":{\"userDetails\":[{\"firstName\":{\"$\":\"0\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"},{\"uid\":{\"$\":\"88\"},\"gid\":{\"$\":\"88\"},\"homeDirectory\":{\"$\":\"/tmp\"},\"@type\":\"posixDetails\"}]},\"userID\":{\"identity\":{\"$\":\"0\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":{\"firstName\":{\"$\":\"1\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}},\"userID\":{\"identity\":{\"$\":\"1\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":[{\"uid\":{\"$\":\"90\"},\"gid\":{\"$\":\"90\"},\"homeDirectory\":{\"$\":\"/tmp\"},\"@type\":\"posixDetails\"},{\"firstName\":{\"$\":\"2\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}]},\"userID\":{\"identity\":{\"$\":\"2\",\"@type\":\"HTTP\"}}}," + "{\"details\":{\"userDetails\":{\"firstName\":{\"$\":\"3\"},\"lastName\":{\"$\":\"NUMBER_\"},\"@type\":\"personalDetails\"}},\"userID\":{\"identity\":{\"$\":\"3\",\"@type\":\"HTTP\"}}}]}}"); final JSONObject result = new JSONObject(writer.toString()); JSONAssert.assertEquals(expected, result, true); Loading